import { Hono } from 'hono' import type Stripe from 'stripe' import type * as App from '../../App.js' import * as Email from '../../internal/Email.js' import * as Metadata from '../metadata.js' import { apiKeys } from './routes/api-keys.js' import { billing } from './routes/billing.js' import { faucet } from './routes/faucet.js' import { invitations } from './routes/invitations.js' import { inviteLinks } from './routes/invite-links.js' import { me } from './routes/me.js' import { members } from './routes/members.js' import { orgs } from './routes/orgs.js' import { projects } from './routes/projects.js' import { scopes } from './routes/scopes.js' import { usage } from './routes/usage.js' import { verifiedTokenRequests } from './routes/verified-token-requests.js' import { webhooks } from './routes/webhooks.js' /** Billing capability, one bag per billing source; Stripe is the sole source today. */ export type Billing = { /** * Stripe billing source. */ stripe: { /** Constructed Stripe client. */ client: Stripe /** Console URL for Checkout/portal return links when the request carries no `Origin`. Defaults to the hosted console. */ consoleUrl?: string | undefined /** Test-mode Stripe backing sandbox billing; omit to keep sandbox billing 501. */ sandbox?: | { /** Constructed test-mode Stripe client. */ client: Stripe /** Test-mode webhook endpoint signing secret (`whsec_…`). */ webhookSecret: string } | undefined /** Webhook endpoint signing secret (`whsec_…`). */ webhookSecret: string } } /** * Request environment for management routes: the shared app environment plus * the billing capability this group publishes on context. */ export type Environment = { Variables: App.Environment['Variables'] & { /** Stripe billing capability; undefined when billing is unconfigured. */ billing: Billing | undefined } } /** * The management route group: the current user, orgs, projects, members, * invitations, and API-key management. Every route reads its dependencies from * request context set by {@link App.create}. * * The session-auth surface is owned by {@link App.create}; management routes * reference it alongside scoped API-key access. * * ```ts * App.create(options).route('/', management()) * ``` */ export function management(options: management.Options = {}) { const app = new Hono() // Publish this group's capabilities for handlers; undefined disables each. .use('*', async (c, next) => { c.set('billing', options.billing) await next() }) .route('/', apiKeys({ enabled: options.apiKeys !== false })) .route('/', billing()) .route('/', faucet()) .route('/', invitations()) .route('/', inviteLinks()) .route('/', me()) .route('/', members()) .route('/', orgs()) .route('/', projects()) .route('/', scopes()) .route('/', usage()) .route('/', verifiedTokenRequests()) .route('/', webhooks({ webhook: options.webhook === false ? undefined : options.webhook })) return Email.attach(Metadata.attach(app, openapi), options.email) } export declare namespace management { /** Options for the management route group. */ type Options = { /** Expose the API-key management routes in the OpenAPI document. @default true */ apiKeys?: boolean | undefined /** Stripe billing capability; omit to disable billing routes (501) and keep production sponsorship closed. */ billing?: Billing | undefined /** Legacy group-level transactional email sender. Prefer `App.create({ email })`. */ email?: Email.Sender | undefined /** Webhook capability shared with the data group and host poller; omit or pass false to disable management. */ webhook?: App.Webhook | false | undefined } } /** * The OpenAPI metadata this group owns: management operation tags. Tagged onto * the {@link management} instance so `App.create` collects it. */ const openapi = { tags: [ { name: 'API Keys', description: 'Credentials for accessing the Tempo API.' }, { name: 'Billing', description: 'Organization billing backed by Stripe.' }, { name: 'Faucet', description: 'Test token routes for Tempo testnet accounts.' }, { name: 'Invitations', description: 'Pending organization invitations.' }, { name: 'Invite Links', description: 'Reusable organization invite links.' }, { name: 'Members', description: 'Organization team membership.' }, { name: 'Organizations', description: 'Teams that own application workspaces and members.' }, { name: 'Projects', description: 'Application workspaces within an organization.' }, { name: 'Usage', description: 'Request and sponsorship usage for organizations.' }, { name: 'Users', description: 'Users on the Tempo Platform.' }, { name: 'Verified Token Requests', description: 'Organization requests to add tokens to the curated verified list.' }, // prettier-ignore { name: 'Webhooks', description: 'Organization webhook subscriptions.' }, ], 'x-tagGroups': [ { name: 'Management API', tags: [ 'API Keys', 'Authentication', 'Billing', 'Invitations', 'Invite Links', 'Members', 'Organizations', 'Projects', 'Usage', 'Users', 'Verified Token Requests', 'Webhooks', ], }, ], } satisfies App.create.Metadata