# `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 `Host` then `X-Forwarded-Host` so reverse-proxied deployments work. - Strips the port via `host.split(":")` before lookup. - Normalises through `normalizeDomain` so the value passed to the resolver is canonical. - Injects `site`, `organization`, `siteId`, `organizationId` on success. - Silent fall-through on miss — downstream is free to 404 or render maintenance. ## Usage: Basic ```ts import { createDomainResolverMiddleware } from "@suaveplan/api-plugin-site/middleware/domain-resolver"; const middleware = createDomainResolverMiddleware(resolver); app.use("*", middleware); ``` ## Usage: Advanced ```ts 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`. - `createDomainResolverMiddleware(resolver: DomainResolverService): DomainResolverMiddleware`. ## Implementation Notes - The middleware does not throw on a resolver error — the resolver's own error path already records the `error` outcome on the OTel counter. Throwing here would force every consumer to wrap the entire request in try/catch. - `X-Forwarded-Host` is consulted only when `Host` is 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 `hono` `ContextVariableMap` augmentation (consumers can re-declare for their app), but the middleware itself does not augment the global declaration to avoid namespace collisions with siblings.