2.7 KiB
middleware/domain-resolver.ts
(no submodules)
Purpose
Factory that builds a Hono middleware which resolves the incoming request's Host header to a site + organization and injects them into the request context. The middleware is the canonical hook applications install at the top of their route stack so downstream handlers can use c.get("site") / c.get("organization") without re-resolving on every endpoint. It is exposed as a service (domainResolverMiddleware) by the plugin's onInit so unrelated plugins can install it positionally without importing the package directly.
The middleware never errors on miss — it falls through with no context keys set. This matches the upstream behaviour and keeps the same instance reusable on route trees containing both site-bound and unbound endpoints.
Features
- Reads
HostthenX-Forwarded-Hostso reverse-proxied deployments work. - Strips the port via
host.split(":")before lookup. - Normalises through
normalizeDomainso the value passed to the resolver is canonical. - Injects
site,organization,siteId,organizationIdon success. - Silent fall-through on miss — downstream is free to 404 or render maintenance.
Usage: Basic
import { createDomainResolverMiddleware } from "@suaveplan/api-plugin-site/middleware/domain-resolver";
const middleware = createDomainResolverMiddleware(resolver);
app.use("*", middleware);
Usage: Advanced
import { createDomainResolverMiddleware } from "@suaveplan/api-plugin-site/middleware/domain-resolver";
// Wrap to enforce site presence on a specific subtree.
const middleware = createDomainResolverMiddleware(resolver);
app.use("/site", async (c, next) => {
await middleware(c, next);
if (c.get("site") === undefined) {
return c.json({ error: "Site not found for host" }, 404);
}
});
API Reference
type DomainResolverMiddleware = (c: Context, next: Next) => Promise<void | Response>.createDomainResolverMiddleware(resolver: DomainResolverService): DomainResolverMiddleware.
Implementation Notes
- The middleware does not throw on a resolver error — the resolver's own error path already records the
erroroutcome on the OTel counter. Throwing here would force every consumer to wrap the entire request in try/catch. X-Forwarded-Hostis consulted only whenHostis absent; if both are present we trust the proxy by deferring to the inner header set, matching the upstream convention.- The four injected context keys are typed via the
honoContextVariableMapaugmentation (consumers can re-declare for their app), but the middleware itself does not augment the global declaration to avoid namespace collisions with siblings.