import type { PathRewriteStyle, StaticRouteConfig } from './types'; export declare function resolveStaticRoute(cfg: string | StaticRouteConfig, cleanUrls: boolean): ResolvedStaticRoute; export declare function contentTypeFor(filePath: string): string; /** * Decode + normalize a URL pathname into a safe relative path. * * Traversal safety: normalizing against a leading `/` collapses every `..` * segment and clamps at the root, so the returned relative path never contains * `..` and `path.join(root, rel)` can't escape `root`. Backslash, NUL and * malformed percent-encoding are rejected outright (return `null`); the * residual `..` guard is belt-and-suspenders. */ export declare function safeRelativePath(pathname: string): string | null; /** * The clean URL to redirect a `.html` request to: mount prefix restored, query * string kept. * * Restoring the prefix is the whole point. Without it, `/docs/x.html` on a site * mounted at `/docs` redirected to `/x` — outside the mount, so whatever owns * the host root answered, and on stacksjs.com that was a 404 page. The redirect * is a 301, so browsers cached the wrong destination. A mounted root * (`/docs/index.html`) redirects to `/docs/`, keeping the trailing slash that * the unmounted case has always produced, so relative links inside the page * still resolve under the mount. */ export declare function cleanUrl(pathname: string, context?: StaticRequestContext): string; /** * Pure resolution of an incoming request pathname to a candidate file path on * disk. Does no I/O; the caller checks existence and may fall back (SPA). * * Rules: * - A trailing `/` (or root) resolves to `index.html` in that directory. * - `cleanUrls` + a `.html` request → 301 to the extensionless URL. * - Extensionless paths resolve per `pathRewriteStyle`: * - `directory`: `/about` → `about/index.html` * - `flat`: `/about` → `about.html` * - Paths with a real extension (`.css`, `.png`, …) map straight through. * * Returns `null` when the path is unsafe (traversal attempt). */ export declare function resolveStaticFile(pathname: string, route: ResolvedStaticRoute, context?: StaticRequestContext): StaticResolution | null; /** * Serve a static file for the matched route. Returns a 301 for clean-URL * redirects, the file with the right `Content-Type`/`Cache-Control` when it * exists, the SPA `index.html` fallback when configured, or 404. */ export declare function serveStaticFile(pathname: string, route: ResolvedStaticRoute, context?: StaticRequestContext): Promise; /** Normalized static-route config (shorthand string already expanded). */ export declare interface ResolvedStaticRoute { dir: string spa: boolean pathRewriteStyle: PathRewriteStyle maxAge: number cleanUrls: boolean } export declare interface StaticResolution { filePath: string redirectTo?: string } /** * What the resolver needs about the REQUEST, as opposed to the route: the two * pieces of the original URL that `pathname` alone no longer carries. * * Both exist for the clean-URL redirect, which is the only thing here that has * to name a URL rather than a file. `pathname` reaches this module already * stripped of the route's mount prefix (a directory mounted at `/docs` resolves * `/docs/guide` against `/guide`), and without its query string — so a * redirect built from `pathname` alone sends the client somewhere else * entirely. See {@link cleanUrl}. */ export declare interface StaticRequestContext { mountPath?: string search?: string }