first commit
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
# `service/normalize-domain.ts`
|
||||
|
||||
## Purpose
|
||||
|
||||
Pure helper that mirrors the SurrealDB `fn::site::domain::normalize` function in TypeScript so application-tier code (the resolver, the route layer, the site service's `addDomain` / `removeDomain` paths) and database-tier code (the surql function) agree on the canonical form of a domain. Without this parity, a site stored with `"acme.example.com"` would be unreachable when an integrator naively passed `"HTTPS://WWW.Acme.Example.Com/"` from a `Host` header.
|
||||
|
||||
## Features
|
||||
|
||||
- Lower-cases, trims whitespace, strips `http://`/`https://`, strips `www.`, strips a single trailing slash.
|
||||
- Pure function, zero deps, zero side effects.
|
||||
- Single source of truth for normalisation — services and middleware call this exclusively.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { normalizeDomain } from "@suaveplan/api-plugin-site/service/normalize-domain";
|
||||
|
||||
normalizeDomain("HTTPS://WWW.Acme.Example.Com/");
|
||||
// → "acme.example.com"
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { normalizeDomain } from "@suaveplan/api-plugin-site/service/normalize-domain";
|
||||
|
||||
// Use inside a middleware to canonicalise the request domain before
|
||||
// hitting the DomainResolverService.
|
||||
const host = c.req.header("host") ?? c.req.header("x-forwarded-host") ?? "";
|
||||
const domain = normalizeDomain(host.split(":")[0] ?? host);
|
||||
const resolved = await resolver.resolve(domain);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `normalizeDomain(domain: string): string`
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The order matters: `http(s)://` MUST be stripped before `www.` so that `https://www.example.com` reduces correctly.
|
||||
- The trailing-slash strip is a single character — paths beyond the host are preserved by the caller's split (the middleware uses `host.split(":")` and the route layer uses the URL parser).
|
||||
- Internationalised domains (`xn--`) are passed through untouched; callers needing IDNA normalisation must run punycode normalisation separately.
|
||||
- The function is intentionally tolerant of leading whitespace and mixed case; in practice the `Host` header is canonical at the wire layer, but reverse proxies and edge workers occasionally pass through a value pulled from a configuration file that has neither been trimmed nor downcased. Normalisation here means the rest of the plugin can assume a single form.
|
||||
- Because the function is pure and synchronous, it is safe to call inside hot paths (e.g. inside the Hono middleware) without any concern over async ordering or external I/O.
|
||||
Reference in New Issue
Block a user