UNPKG

@stacksjs/rpx

Version:

A modern and smart reverse proxy.

107 lines (106 loc) 4.52 kB
import type { OnDemandSitesConfig, SiteRouteTemplate } from './types'; /** Expand a leading `~` (or `~/…`) to the resolved home directory. */ export declare function expandHome(p: string, home: string): string; /** A registry-safe id derived from a host (`a.localhost` → `a.localhost`). */ export declare function siteIdForHost(host: string): string; /** * The host's single project label for convention discovery: `<name>.<tld>` → * `name`. Multi-label hosts (`docs.app.localhost`) and bare TLDs don't discover — * point those at an explicit `sites` entry. Returns `null` when no TLD matches. */ export declare function projectNameFromHost(host: string, tlds: string[]): string | null; /** * Read a per-project {@link SiteManifest} so users can define the dev startup * manually. Checked sources, in order: a `rpx.site.json` file in the project, * then a `"rpx"` key in its `package.json`. Returns `null` when neither exists * (or both are malformed). */ export declare function readSiteManifest(dir: string, deps: ResolverProbes): SiteManifest | null; /*` dependency in * `package.json`. Boots frontend (`/`), API (`/api`) and docs (`/docs`) with * the conventional `PORT`/`PORT_API`/`PORT_DOCS` env, deferring proxy + TLS to * rpx (`STACKS_PROXY_MANAGED=1`) and taking its public origin via `APP_URL`. * - **Generic** — any `package.json` with a `dev` script: a single `bun run dev` * backend on `PORT`. * - Otherwise `null`. */ export declare function detectProjectPreset(dir: string, deps: ResolverProbes): SitePreset | null; /** * Build a {@link SiteResolver} over an {@link OnDemandSitesConfig}. Explicit * `sites` are matched first (exact host, then wildcard), then convention * discovery under `roots`. */ export declare function createSiteResolver(config: OnDemandSitesConfig, deps?: SiteResolverDeps): SiteResolver; /** * Enumerate the sites rpx can currently boot — explicit non-wildcard * {@link SiteConfig}s plus every project discovered by scanning the configured * roots. Powers `rpx sites`. Each entry is a fully-resolved {@link ResolvedSite} * (so the caller sees the dir, command, and host it would serve). */ export declare function listDiscoverableSites(config: OnDemandSitesConfig, deps?: SiteResolverDeps): ResolvedSite[]; /** A fully-resolved site, ready for the supervisor to boot and route. */ export declare interface ResolvedSite { host: string id: string dir: string command: string env: Record<string, string> routes: SiteRouteTemplate[] selfRegisters: boolean idleTimeoutMs: number source: 'config' | 'discovered' } /** * The dev-command shape for a recognized project kind. Returned by a * {@link SiteDetector}; the resolver folds it into a {@link ResolvedSite}. */ export declare interface SitePreset { command: string env?: Record<string, string> routes?: SiteRouteTemplate[] selfRegisters?: boolean urlEnv?: string[] } /** * A per-project override of how rpx boots a site — so the dev startup can be * defined **manually** instead of relying on auto-detection. Read from a * `rpx.site.json` file in the project, or a `"rpx"` key in its `package.json`. * A manifest with a `command` fully defines the preset (and makes even a * directory that isn't otherwise a recognized project bootable). * * ```jsonc * // rpx.site.json * { * "command": "pnpm dev", * "env": { "NODE_ENV": "development" }, * "routes": [ * { "path": "/", "portEnv": "PORT", "defaultPort": 5173, "readyGate": true }, * { "path": "/api", "portEnv": "API_PORT", "defaultPort": 4000 } * ] * } * ``` */ export declare interface SiteManifest { command?: string env?: Record<string, string> routes?: SiteRouteTemplate[] selfRegisters?: boolean urlEnv?: string[] } /** Filesystem probes the resolver and detector use — injected for tests. */ export declare interface ResolverProbes { dirExists: (p: string) => boolean fileExists: (p: string) => boolean readText: (p: string) => string | null } export declare interface SiteResolverDeps extends Partial<ResolverProbes> { detect?: SiteDetector homeDir?: string readdir?: (p: string) => string[] } /** Resolve a host to a site (or `null`). Construct once, call per request. */ export declare interface SiteResolver { resolve: (host: string) => ResolvedSite | null } /** Detect a project kind from its directory. Returns `null` for "not a dev project". */ export type SiteDetector = (dir: string, deps: ResolverProbes) => SitePreset | null;