tapimo 0.10.0 → 0.10.2
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/dist/ApiKey.d.ts +2 -1
- package/dist/ApiKey.d.ts.map +1 -1
- package/dist/ApiKeys.d.ts +4 -2
- package/dist/ApiKeys.d.ts.map +1 -1
- package/dist/ApiKeys.js +26 -1
- package/dist/ApiKeys.js.map +1 -1
- package/dist/App.d.ts +6007 -5003
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +1 -0
- package/dist/App.js.map +1 -1
- package/dist/Webhooks.d.ts +1 -1
- package/dist/Webhooks.d.ts.map +1 -1
- package/dist/Webhooks.js +6 -6
- package/dist/Webhooks.js.map +1 -1
- package/dist/admin/App.d.ts +91 -84
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +22 -13
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +6 -0
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts +4 -2
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.js +69 -69
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +232 -0
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts +4 -0
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +2 -0
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/apps/Zones.d.ts +4266 -82
- package/dist/apps/Zones.d.ts.map +1 -1
- package/dist/apps/Zones.js +27 -8
- package/dist/apps/Zones.js.map +1 -1
- package/dist/apps/data/App.d.ts +3467 -2696
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +2 -0
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +2999 -100
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +340 -2
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +514 -0
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +26 -26
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +7 -3
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +4 -4
- package/dist/apps/data/routes/earn.d.ts +75 -75
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +65 -36
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts +124 -120
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +115 -77
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +24 -24
- package/dist/apps/data/routes/indexer.d.ts +2 -1
- package/dist/apps/data/routes/indexer.d.ts.map +1 -1
- package/dist/apps/data/routes/indexer.js +3 -2
- package/dist/apps/data/routes/indexer.js.map +1 -1
- package/dist/apps/data/routes/receipts.d.ts +4 -3
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +15 -14
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/rpc.d.ts.map +1 -1
- package/dist/apps/data/routes/rpc.js +5 -1
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +12 -12
- package/dist/apps/data/routes/tokens.d.ts +1 -1
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +4 -3
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +25 -7
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts +37 -37
- package/dist/apps/data/routes/webhooks.d.ts +71 -1
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +177 -23
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.js +1 -1
- package/dist/apps/data/routes/zones.js.map +1 -1
- package/dist/apps/funding/App.d.ts +322 -89
- package/dist/apps/funding/App.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts +375 -45
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.js +208 -12
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/funding/routes/transfers.d.ts +32 -32
- package/dist/apps/funding/routes/transfers.js +1 -1
- package/dist/apps/funding/routes/transfers.js.map +1 -1
- package/dist/apps/management/App.d.ts +418 -418
- package/dist/apps/management/routes/api-keys.d.ts +50 -50
- package/dist/apps/management/routes/billing.d.ts +72 -72
- package/dist/apps/management/routes/billing.js +1 -1
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +8 -8
- package/dist/apps/management/routes/faucet.js +2 -2
- package/dist/apps/management/routes/faucet.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +42 -42
- package/dist/apps/management/routes/me.d.ts +6 -6
- package/dist/apps/management/routes/members.d.ts +14 -14
- package/dist/apps/management/routes/projects.d.ts +40 -40
- package/dist/apps/management/routes/usage.d.ts +8 -8
- package/dist/apps/management/routes/webhooks.d.ts +49 -49
- package/dist/apps/mcp.d.ts.map +1 -1
- package/dist/apps/mcp.js +4 -1
- package/dist/apps/mcp.js.map +1 -1
- package/dist/db/Db.d.ts +2 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +90 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +19 -0
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +24 -0
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/fundingDepositAddresses.d.ts +20 -0
- package/dist/db/tables/fundingDepositAddresses.d.ts.map +1 -1
- package/dist/db/tables/fundingDepositAddresses.js +17 -0
- package/dist/db/tables/fundingDepositAddresses.js.map +1 -1
- package/dist/db/tables/fundingDeposits.d.ts +41 -0
- package/dist/db/tables/fundingDeposits.d.ts.map +1 -1
- package/dist/db/tables/fundingDeposits.js +69 -0
- package/dist/db/tables/fundingDeposits.js.map +1 -1
- package/dist/db/tables/webhookQueueEvents.d.ts +122 -0
- package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -0
- package/dist/db/tables/webhookQueueEvents.js +160 -0
- package/dist/db/tables/webhookQueueEvents.js.map +1 -0
- package/dist/db/tables/webhookSubscriptions.d.ts +2 -0
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +10 -0
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/internal/Auth.d.ts +3 -26
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +6 -37
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Credential.d.ts +27 -0
- package/dist/internal/Credential.d.ts.map +1 -0
- package/dist/internal/Credential.js +34 -0
- package/dist/internal/Credential.js.map +1 -0
- package/dist/internal/EarnRates.js +11 -7
- package/dist/internal/EarnRates.js.map +1 -1
- package/dist/internal/Log.d.ts +8 -0
- 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/MetricSink.d.ts +51 -0
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +54 -2
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/RateLimit.d.ts +4 -6
- package/dist/internal/RateLimit.d.ts.map +1 -1
- package/dist/internal/RateLimit.js +15 -14
- package/dist/internal/RateLimit.js.map +1 -1
- package/dist/internal/Store.d.ts +2 -1
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +57 -18
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts +4 -3
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +2 -2
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Value.d.ts +2 -0
- package/dist/internal/Value.d.ts.map +1 -1
- package/dist/internal/Value.js +25 -0
- package/dist/internal/Value.js.map +1 -1
- package/dist/internal/Viem.d.ts +4 -3
- package/dist/internal/Viem.d.ts.map +1 -1
- package/dist/internal/Viem.js +3 -2
- package/dist/internal/Viem.js.map +1 -1
- package/dist/internal/WebhookTransfer.d.ts +20 -0
- package/dist/internal/WebhookTransfer.d.ts.map +1 -1
- package/dist/internal/WebhookTransfer.js +7 -4
- package/dist/internal/WebhookTransfer.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +141 -0
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +139 -10
- package/dist/internal/Webhooks.js.map +1 -1
- package/dist/internal/funding/providers/relay.d.ts +3 -4
- package/dist/internal/funding/providers/relay.d.ts.map +1 -1
- package/dist/internal/funding/providers/relay.js +59 -8
- package/dist/internal/funding/providers/relay.js.map +1 -1
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1 -0
- package/dist/internal/index.js.map +1 -1
- package/package.json +3 -3
- package/src/ApiKeys.test.ts +20 -0
- package/src/ApiKeys.ts +28 -1
- package/src/App.test.ts +40 -8
- package/src/App.ts +1 -0
- package/src/Client.test-d.ts +34 -1
- package/src/Webhooks.ts +20 -18
- package/src/admin/apps/api-keys.test.ts +9 -0
- package/src/admin/apps/api-keys.ts +15 -0
- package/src/admin/ui/src/lib/query-client.ts +3 -2
- package/src/admin/ui/src/routes/api-keys.tsx +31 -9
- package/src/admin/ui.generated.ts +69 -69
- package/src/analytics/Analytics.test.ts +42 -0
- package/src/analytics/Analytics.ts +232 -0
- package/src/analytics/tables/requestEvents.ts +6 -0
- package/src/apps/Zones.test.ts +20 -3
- package/src/apps/Zones.ts +28 -8
- package/src/apps/composition.test.ts +2 -0
- package/src/apps/data/App.test.ts +2 -2
- package/src/apps/data/App.ts +2 -0
- package/src/apps/data/routes/activities.bench.ts +41 -0
- package/src/apps/data/routes/activities.test.ts +103 -2
- package/src/apps/data/routes/activities.ts +401 -2
- package/src/apps/data/routes/balances.bench.ts +21 -0
- package/src/apps/data/routes/balances.ts +7 -3
- package/src/apps/data/routes/blocks.bench.ts +34 -0
- package/src/apps/data/routes/coingecko.bench.ts +53 -0
- package/src/apps/data/routes/earn.bench.ts +71 -0
- package/src/apps/data/routes/earn.ts +66 -36
- package/src/apps/data/routes/exchanges.bench.ts +85 -0
- package/src/apps/data/routes/exchanges.test.ts +8 -3
- package/src/apps/data/routes/exchanges.ts +134 -82
- package/src/apps/data/routes/fee-amm.bench.ts +13 -0
- package/src/apps/data/routes/indexer.bench.ts +8 -0
- package/src/apps/data/routes/indexer.test.ts +2 -1
- package/src/apps/data/routes/indexer.ts +3 -2
- package/src/apps/data/routes/receipts.bench.ts +39 -0
- package/src/apps/data/routes/receipts.ts +16 -14
- package/src/apps/data/routes/rpc.bench.ts +14 -0
- package/src/apps/data/routes/rpc.test.ts +27 -0
- package/src/apps/data/routes/rpc.ts +5 -1
- package/src/apps/data/routes/tokenlist.bench.ts +3 -0
- package/src/apps/data/routes/tokens.bench.ts +76 -0
- package/src/apps/data/routes/tokens.ts +3 -2
- package/src/apps/data/routes/transactions.bench.ts +48 -0
- package/src/apps/data/routes/transfers.bench.ts +28 -0
- package/src/apps/data/routes/transfers.ts +36 -10
- package/src/apps/data/routes/valuation.bench.ts +14 -0
- package/src/apps/data/routes/verified-tokens.bench.ts +8 -0
- package/src/apps/data/routes/webhooks.bench.ts +26 -0
- package/src/apps/data/routes/webhooks.scan.test.ts +326 -0
- package/src/apps/data/routes/webhooks.test.ts +53 -6
- package/src/apps/data/routes/webhooks.ts +252 -24
- package/src/apps/data/routes/zones.bench.ts +32 -0
- package/src/apps/data/routes/zones.test.ts +1 -1
- package/src/apps/data/routes/zones.ts +1 -1
- package/src/apps/funding/routes/chains.test.ts +1 -1
- package/src/apps/funding/routes/deposit-addresses.test.ts +217 -3
- package/src/apps/funding/routes/deposit-addresses.ts +255 -19
- package/src/apps/funding/routes/providers.test.ts +1 -1
- package/src/apps/funding/routes/quotes.test.ts +1 -1
- package/src/apps/funding/routes/transfers.test.ts +20 -8
- package/src/apps/funding/routes/transfers.ts +1 -1
- package/src/apps/management/routes/billing.ts +1 -1
- package/src/apps/management/routes/faucet.ts +2 -2
- package/src/apps/management/routes/me.test.ts +31 -0
- package/src/apps/mcp.ts +4 -1
- package/src/db/Db.ts +117 -0
- package/src/db/Schema.ts +32 -0
- package/src/db/tables/fundingDepositAddresses.test.ts +28 -0
- package/src/db/tables/fundingDepositAddresses.ts +39 -0
- package/src/db/tables/fundingDeposits.test.ts +82 -0
- package/src/db/tables/fundingDeposits.ts +130 -0
- package/src/db/tables/webhookQueueEvents.ts +285 -0
- package/src/db/tables/webhookSubscriptions.ts +15 -0
- package/src/internal/Auth.test.ts +61 -98
- package/src/internal/Auth.ts +9 -63
- package/src/internal/Credential.test.ts +51 -0
- package/src/internal/Credential.ts +58 -0
- package/src/internal/EarnRates.ts +13 -7
- package/src/internal/EarnVaults.test.ts +2 -2
- package/src/internal/Log.test.ts +3 -1
- package/src/internal/Log.ts +14 -0
- package/src/internal/MetricSink.test.ts +108 -2
- package/src/internal/MetricSink.ts +112 -2
- package/src/internal/RateLimit.test.ts +23 -18
- package/src/internal/RateLimit.ts +23 -15
- package/src/internal/Store.test.ts +99 -13
- package/src/internal/Store.ts +52 -17
- package/src/internal/Tidx.test.ts +4 -4
- package/src/internal/Tidx.ts +5 -4
- package/src/internal/Value.test.ts +25 -0
- package/src/internal/Value.ts +29 -0
- package/src/internal/Viem.test.ts +4 -0
- package/src/internal/Viem.ts +6 -4
- package/src/internal/WebhookTransfer.test.ts +89 -0
- package/src/internal/WebhookTransfer.ts +11 -7
- package/src/internal/Webhooks.test.ts +488 -0
- package/src/internal/Webhooks.ts +291 -10
- package/src/internal/funding/Provider.test.ts +1 -1
- package/src/internal/funding/providers/index.test.ts +73 -3
- package/src/internal/funding/providers/relay.test.ts +1 -5
- package/src/internal/funding/providers/relay.ts +56 -12
- package/src/internal/index.test.ts +1 -0
- package/src/internal/index.ts +1 -0
package/src/Webhooks.ts
CHANGED
|
@@ -19,7 +19,7 @@ export * from './internal/Webhooks.js'
|
|
|
19
19
|
// type delivery bodies: `Webhooks.schema.Envelope` (a discriminated union on
|
|
20
20
|
// `type`), plus the per-event `TransferEvent` / `TransactionEvent` / `PingEvent`
|
|
21
21
|
// payloads. Infer a type with `z.infer<typeof Webhooks.schema.Envelope>`.
|
|
22
|
-
export { eventTypes, schema } from './apps/data/routes/webhooks.js'
|
|
22
|
+
export { enrichEventData, eventTypes, scanBlock, schema } from './apps/data/routes/webhooks.js'
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Builds a webhook poller bound to a state store and chain config.
|
|
@@ -74,23 +74,25 @@ export function createPoller(options: createPoller.Options): createPoller.Poller
|
|
|
74
74
|
return result
|
|
75
75
|
}
|
|
76
76
|
: inner
|
|
77
|
-
const dispatchBatch =
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
77
|
+
const dispatchBatch = innerBatch
|
|
78
|
+
? async (
|
|
79
|
+
dispatchables: readonly AppWebhooks.poll.Dispatchable[],
|
|
80
|
+
context: AppWebhooks.poll.DispatchContext,
|
|
81
|
+
) => {
|
|
82
|
+
const start = Date.now()
|
|
83
|
+
const result = await innerBatch(dispatchables, context)
|
|
84
|
+
const durationMs = Date.now() - start
|
|
85
|
+
for (const dispatchable of dispatchables)
|
|
86
|
+
metrics?.record({
|
|
87
|
+
chainId: dispatchable.envelope.chainId,
|
|
88
|
+
durationMs,
|
|
89
|
+
eventType: dispatchable.envelope.type,
|
|
90
|
+
ok: result.ok,
|
|
91
|
+
type: 'webhook:enqueue',
|
|
92
|
+
})
|
|
93
|
+
return result
|
|
94
|
+
}
|
|
95
|
+
: undefined
|
|
94
96
|
|
|
95
97
|
// Resolve per tick so Workers factories build a fresh Hyperdrive-pooled
|
|
96
98
|
// connection each run.
|
|
@@ -105,6 +105,15 @@ describe('POST /api-keys', () => {
|
|
|
105
105
|
expect((await core_ApiKeys.list(store))[0]?.expiresAt).toBe(expiresAt)
|
|
106
106
|
})
|
|
107
107
|
|
|
108
|
+
test('rejects an expiry without the minimum storage lead time', async () => {
|
|
109
|
+
const { client } = await setup()
|
|
110
|
+
const response = await client['api-keys'].$post({
|
|
111
|
+
json: { ...validBody, expiresAt: new Date(Date.now() + 60_000).toISOString() },
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
expect(response.status).toBe(400)
|
|
115
|
+
})
|
|
116
|
+
|
|
108
117
|
test('rejects an unknown scope with 400', async () => {
|
|
109
118
|
const { client } = await setup()
|
|
110
119
|
const response = await client['api-keys'].$post({
|
|
@@ -15,6 +15,9 @@ import type * as App from '../App.js'
|
|
|
15
15
|
|
|
16
16
|
/** Zod schemas owned by the admin API-keys handler. */
|
|
17
17
|
export namespace schema {
|
|
18
|
+
// Leave time for validation and database lookups before KV writes its minimum 60-second TTL.
|
|
19
|
+
const minimumExpiryLeadMs = 2 * 60_000
|
|
20
|
+
|
|
18
21
|
const Name = z
|
|
19
22
|
.pipe(
|
|
20
23
|
z.string(),
|
|
@@ -27,6 +30,17 @@ export namespace schema {
|
|
|
27
30
|
z.meta({ examples: ['Explorer testnet'] }),
|
|
28
31
|
)
|
|
29
32
|
|
|
33
|
+
const ExpiresAt = z.optional(z.iso.datetime()).check(
|
|
34
|
+
z.refine(
|
|
35
|
+
(value) => value === undefined || Date.parse(value) >= Date.now() + minimumExpiryLeadMs,
|
|
36
|
+
{
|
|
37
|
+
error: 'Expiry must be at least two minutes in the future.',
|
|
38
|
+
},
|
|
39
|
+
),
|
|
40
|
+
z.describe('ISO 8601 expiry timestamp. Omit for a non-expiring key.'),
|
|
41
|
+
z.meta({ examples: ['2100-01-01T00:00:00.000Z'] }),
|
|
42
|
+
)
|
|
43
|
+
|
|
30
44
|
const ApiKey = Schema.describe(
|
|
31
45
|
z.extend(ApiKeys.schema.Record, {
|
|
32
46
|
createdByLabel: z
|
|
@@ -59,6 +73,7 @@ export namespace schema {
|
|
|
59
73
|
*/
|
|
60
74
|
export const Body = Schema.describe(
|
|
61
75
|
z.extend(z.omit(ApiKeys.schema.MintInput, { createdBy: true, name: true }), {
|
|
76
|
+
expiresAt: ExpiresAt,
|
|
62
77
|
name: Name,
|
|
63
78
|
scopes: z
|
|
64
79
|
.readonly(
|
|
@@ -17,12 +17,13 @@ const persister = createAsyncStoragePersister({
|
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
export const persistOptions: Omit<PersistQueryClientOptions, 'queryClient'> = {
|
|
20
|
-
|
|
21
|
-
persister,
|
|
20
|
+
buster: 'rate-limit-periods',
|
|
22
21
|
dehydrateOptions: {
|
|
23
22
|
shouldDehydrateQuery: (query) =>
|
|
24
23
|
query.queryKey[0] !== 'config' &&
|
|
25
24
|
query.queryKey[0] !== 'organizations' &&
|
|
26
25
|
defaultShouldDehydrateQuery(query),
|
|
27
26
|
},
|
|
27
|
+
maxAge: 1000 * 60 * 60 * 24,
|
|
28
|
+
persister,
|
|
28
29
|
}
|
|
@@ -59,9 +59,11 @@ function RouteComponent() {
|
|
|
59
59
|
alert('Enter a name that identifies what uses this key.')
|
|
60
60
|
return
|
|
61
61
|
}
|
|
62
|
+
const expiresAt_value = field('expiresAt')
|
|
63
|
+
const expiresAt = expiresAt_value ? new Date(expiresAt_value).toISOString() : undefined
|
|
62
64
|
const orgId = filters.orgId ?? field('orgId')
|
|
63
65
|
const rateLimit = field('rateLimit')
|
|
64
|
-
const
|
|
66
|
+
const limit = rateLimit ? Number(rateLimit) : undefined
|
|
65
67
|
const environment = field('environment') === 'sandbox' ? 'sandbox' : 'production'
|
|
66
68
|
const pendingZoneScopes = (['read', 'write'] as const).map((access) => {
|
|
67
69
|
const chainId = field(`zoneChainId_${access}`)
|
|
@@ -87,10 +89,13 @@ function RouteComponent() {
|
|
|
87
89
|
provision.mutate(
|
|
88
90
|
{
|
|
89
91
|
environment,
|
|
92
|
+
...(expiresAt === undefined ? {} : { expiresAt }),
|
|
90
93
|
name,
|
|
91
94
|
...(orgId ? { orgId } : {}),
|
|
92
95
|
...(filters.projectId ? { projectId: filters.projectId } : {}),
|
|
93
|
-
...(
|
|
96
|
+
...(limit === undefined
|
|
97
|
+
? {}
|
|
98
|
+
: { rateLimits: { '*': { limit, period: 'minute' as const } } }),
|
|
94
99
|
scopes: scopes as ApiKeys.provision.Input['scopes'],
|
|
95
100
|
},
|
|
96
101
|
{ onError: (error) => alert(error.message), onSuccess: () => setOpen(false) },
|
|
@@ -273,7 +278,7 @@ function ProvisionForm(props: {
|
|
|
273
278
|
</div>
|
|
274
279
|
) : null}
|
|
275
280
|
<Fields
|
|
276
|
-
className="min-h-0 flex-1 gap-6
|
|
281
|
+
className="min-h-0 flex-1 gap-6 overflow-y-auto overscroll-contain"
|
|
277
282
|
variant="default"
|
|
278
283
|
>
|
|
279
284
|
<OrganizationAutocomplete orgId={props.orgId} />
|
|
@@ -289,6 +294,12 @@ function ProvisionForm(props: {
|
|
|
289
294
|
<option value="sandbox">Sandbox</option>
|
|
290
295
|
</select>
|
|
291
296
|
</div>
|
|
297
|
+
<Input
|
|
298
|
+
label="Expires at (optional)"
|
|
299
|
+
min={toLocalDateTimeCeil(new Date(Date.now() + 2 * 60_000))}
|
|
300
|
+
name="expiresAt"
|
|
301
|
+
type="datetime-local"
|
|
302
|
+
/>
|
|
292
303
|
<Input
|
|
293
304
|
defaultValue="10000"
|
|
294
305
|
label="Rate limit"
|
|
@@ -298,14 +309,14 @@ function ProvisionForm(props: {
|
|
|
298
309
|
suffix="req/min"
|
|
299
310
|
type="number"
|
|
300
311
|
/>
|
|
301
|
-
<div className="flex
|
|
312
|
+
<div className="flex flex-col gap-2">
|
|
302
313
|
<span className="label-13 text-foreground-secondary">Scopes</span>
|
|
303
314
|
{scopes.isPending ? (
|
|
304
315
|
<span className="text-label-13 text-foreground-secondary">Loading scopes…</span>
|
|
305
316
|
) : scopes.error ? (
|
|
306
317
|
<span className="text-label-13 text-negative">{scopes.error.message}</span>
|
|
307
318
|
) : (
|
|
308
|
-
<div className="
|
|
319
|
+
<div className="border border-border">
|
|
309
320
|
<Rows variant="surface">
|
|
310
321
|
{(scopes.data?.data ?? []).map((entry) => {
|
|
311
322
|
const zoneAccess = Scopes.accessFromTemplate(entry.scope)
|
|
@@ -618,7 +629,7 @@ function KeyList(props: {
|
|
|
618
629
|
function KeyRow(props: { currentUser?: string | undefined; record: ApiKeys.ApiKey }) {
|
|
619
630
|
const { currentUser, record } = props
|
|
620
631
|
const [expanded, setExpanded] = useState(false)
|
|
621
|
-
const
|
|
632
|
+
const rateLimit = record.rateLimits?.['*']
|
|
622
633
|
|
|
623
634
|
return (
|
|
624
635
|
<>
|
|
@@ -659,7 +670,9 @@ function KeyRow(props: { currentUser?: string | undefined; record: ApiKeys.ApiKe
|
|
|
659
670
|
<Detail label="Key ID">{record.id}</Detail>
|
|
660
671
|
<Detail label="Environment">{record.environment ?? 'production'}</Detail>
|
|
661
672
|
<Detail label="Rate limit">
|
|
662
|
-
{
|
|
673
|
+
{rateLimit === undefined
|
|
674
|
+
? 'Inherited'
|
|
675
|
+
: `${rateLimit.limit} req/${rateLimit.period === 'minute' ? 'min' : 'sec'}`}
|
|
663
676
|
</Detail>
|
|
664
677
|
<Detail label="Token">···{record.tokenLast4}</Detail>
|
|
665
678
|
<Detail label="Organization">{organization(record)}</Detail>
|
|
@@ -804,9 +817,11 @@ function RevokeDialog(props: { currentUser?: string | undefined; record: ApiKeys
|
|
|
804
817
|
<Detail label="Project">{project(record)}</Detail>
|
|
805
818
|
<Detail label="Provisioned by">{creator ?? 'Unknown'}</Detail>
|
|
806
819
|
<Detail label="Rate limit">
|
|
807
|
-
{record.rateLimits?.['*']
|
|
820
|
+
{record.rateLimits?.['*'] === undefined
|
|
808
821
|
? 'Inherited'
|
|
809
|
-
: `${record.rateLimits['*']!.
|
|
822
|
+
: `${record.rateLimits['*']!.limit} req/${
|
|
823
|
+
record.rateLimits['*']!.period === 'minute' ? 'min' : 'sec'
|
|
824
|
+
}`}
|
|
810
825
|
</Detail>
|
|
811
826
|
</dl>
|
|
812
827
|
{differentCreator ? (
|
|
@@ -858,6 +873,13 @@ function Detail(props: { children: ReactNode; className?: string; label: ReactNo
|
|
|
858
873
|
)
|
|
859
874
|
}
|
|
860
875
|
|
|
876
|
+
/** Rounds an instant up for a minute-precision `datetime-local` control. */
|
|
877
|
+
function toLocalDateTimeCeil(date: Date) {
|
|
878
|
+
const minute = 60_000
|
|
879
|
+
const time = Math.ceil(date.getTime() / minute) * minute
|
|
880
|
+
return new Date(time - date.getTimezoneOffset() * minute).toISOString().slice(0, 16)
|
|
881
|
+
}
|
|
882
|
+
|
|
861
883
|
function matches(record: ApiKeys.ApiKey, query?: string) {
|
|
862
884
|
const normalized = query?.trim().toLowerCase()
|
|
863
885
|
if (!normalized) return true
|