/** * Adapter Factory Module * * Handles creation and caching of runtime adapters for different project contexts. * Supports local projects (filesystem-first) and proxy mode (API-first). * * @module server/runtime-handler/adapter-factory */ import type { RuntimeAdapter } from "../../platform/adapters/base.js"; import { type PreparedHostedConfigContext } from "../../config/loader.js"; import type { VeryfrontConfig } from "../../config/index.js"; import { type ProjectDiscoveryCache } from "./local-project-discovery.js"; import type { ParsedDomain } from "../utils/domain-parser.js"; import { type PreviewSourceSnapshotMarker } from "../handlers/request/source-snapshot-freshness.js"; /** * Which path produced `config`, so a caller that degrades on a missing config * can say why it is missing. * * `config` being `undefined` is reached from four unrelated places -- an * inherited caller config, a deliberate defer, a published project that has no * config file, and a hosted 404 -- and the result alone cannot tell them * apart. Downstream, `resolveProjectRuntimeContext` silently substitutes the * process-wide security config for an absent project config, which serves a * correct-looking 200 carrying the platform-default CSP instead of the * project's. That degradation was undiagnosable from production logs because * every branch that reaches it logs at debug. */ export type ConfigResolutionOutcome = /** No project-specific load ran; whatever the caller passed through stands. */ "inherited" /** Loaded from a local project directory. */ | "local" /** Deliberately skipped: see `shouldDeferConfigLoad`. */ | "deferred" /** Loaded from the control plane for this project. */ | "hosted" /** The control plane answered 404: the project publishes no config file. */ | "hosted-absent"; interface AdapterResolutionResult { /** The effective project directory to use */ projectDir: string; /** The adapter to use for this request */ adapter: RuntimeAdapter; /** The config for this project */ config: VeryfrontConfig | undefined; /** Which branch produced `config`. */ configOutcome: ConfigResolutionOutcome; /** Whether this is a local project (filesystem-first) */ isLocalProject: boolean; /** Strict mutable-source generation that produced document configuration. */ previewDocumentSourceSnapshot?: PreviewSourceSnapshotMarker; } interface AdapterResolutionOptions { /** * Inbound request. Used to determine whether forwarded headers such as * `x-project-path` can be trusted (see {@link isProxyTrusted}). */ req: Request; /** Base project directory */ projectDir: string; /** Base adapter */ adapter: RuntimeAdapter; /** Base config (optional) */ config: VeryfrontConfig | undefined; /** Project slug */ projectSlug: string | undefined; /** Project ID */ projectId: string | undefined; /** Proxy token */ proxyToken: string | undefined; /** Release ID */ releaseId: string | undefined; /** Environment (preview/production) */ proxyEnv: "preview" | "production" | undefined; /** Branch name */ branch: string | null | undefined; /** Environment name (e.g., "staging") */ environmentName: string | undefined; /** Parsed domain info */ parsedDomain: ParsedDomain; /** Request pathname, used to decide whether config failures can safely fall back. */ pathname?: string; /** Whether running in proxy mode */ isProxyMode: boolean; /** Host admission decision for executing project-owned document handlers. */ allowHostProjectCodeExecution?: boolean; /** Result of an earlier proxy trust check, when already available. */ proxyTrusted?: boolean; /** Optional injectable cache (defaults to module-level singleton) */ cache?: ProjectDiscoveryCache; /** * Authenticated source and environment snapshot for hosted config. Proxy * config must never derive either value independently inside this factory. */ prepareHostedConfigContext?: (isLocalProject: boolean) => Promise; } /** * Whether an error carries an own `status` of 404. * * Read through an own-property descriptor rather than plain access: this runs on * a rejection value that may be anything, and a getter on an attacker-shaped * object should not execute during error handling. * * Callers must scope this to the single operation whose 404 means "absent", * never to a block that also performs other requests -- see the config load * below, where only the getHostedConfig call is treated this way. */ export declare function hasNotFoundStatus(error: unknown): boolean; /** * Resolve the effective adapter and config for a request. * * For local projects: Uses filesystem adapter, loads config from disk. * For proxy mode: Uses VeryFront API adapter with project context. */ export declare function resolveAdapter(opts: AdapterResolutionOptions): Promise; export {}; //# sourceMappingURL=adapter-factory.d.ts.map