astro
Version:
Astro is a modern site builder with web best practices, performance, and DX front-of-mind.
252 lines (251 loc) • 10.9 kB
TypeScript
import type { ActionAPIContext } from '../../actions/runtime/types.js';
import type { ComponentInstance } from '../../types/astro.js';
import type { Params, Props, RewritePayload } from '../../types/public/common.js';
import type { APIContext, AstroGlobal } from '../../types/public/context.js';
import type { RouteData, SSRResult } from '../../types/public/internal.js';
import { AstroCookies } from '../cookies/index.js';
import { type Pipeline } from '../render/index.js';
import type { ResolvedRenderOptions } from '../app/base.js';
/**
* Describes a lazily-created value that handlers can contribute to the
* request context. `create` is called at most once (on first `resolve`);
* `finalize` runs during `finalizeAll` to clean up / persist.
*/
export interface ContextProvider<T> {
/** Factory called lazily on the first `resolve(key)`. */
create: () => T;
/** Optional cleanup / persist callback. Receives the created value. */
finalize?: (value: T) => Promise<void> | void;
}
/**
* The public contract of {@link FetchState} exposed to user-land code
* (custom fetch handlers, Hono middleware, etc.).
*
* Only the members listed here are part of the stable public API.
* Everything else on the concrete `FetchState` class is internal and
* may change without notice.
*
* If you add a new member to `FetchState` that should be user-visible,
* add it here first — the `implements` clause on the class ensures a
* compile-time error if the class falls out of sync.
*/
export interface AstroFetchState {
/** The incoming request. */
readonly request: Request;
/** Normalized URL derived from the request. */
readonly url: URL;
/** Base-stripped, decoded pathname of the request. */
readonly pathname: string;
/** The matched route for this request, if any. */
readonly routeData: RouteData | undefined;
/** Cookies for this request. */
readonly cookies: AstroCookies;
/** Request-scoped locals object, shared with user middleware. */
readonly locals: App.Locals;
/** Route params derived from routeData + pathname. */
readonly params: Params | undefined;
/** The `Response` produced by handlers, if any. Set after rendering. */
response: Response | undefined;
/** Default HTTP status for the rendered response. */
status: number;
/**
* Triggers a rewrite to a different route.
*
* [Astro reference](https://docs.astro.build/en/guides/routing/#rewrites)
*/
rewrite(payload: RewritePayload): Promise<Response>;
/**
* Registers a context provider under the given key. The `create`
* factory is called lazily on the first `resolve(key)`.
*/
provide<T>(key: string, provider: ContextProvider<T>): void;
/**
* Lazily resolves a provider registered under `key`. Returns
* `undefined` if no provider was registered for the key.
*/
resolve<T>(key: string): T | undefined;
/**
* Runs all registered provider `finalize` callbacks. Call this after
* the response is produced, typically in a `finally` block.
*/
finalizeAll(): Promise<void> | void;
}
/**
* Retrieves the `FetchState` stashed on an `APIContext` by
* `FetchState.getAPIContext()`. Throws if not found — this indicates
* the context was not created through Astro's request pipeline.
*/
export declare function getFetchStateFromAPIContext(context: APIContext): FetchState;
/**
* Holds per-request state as it flows through the handler pipeline.
*
* **This class is user-facing** via `astro/fetch` and `astro/hono`.
* The {@link AstroFetchState} interface defines the stable public
* surface. Members not on that interface are internal and
* may change without notice.
*
* Performance note: fields on this class are plain properties — ES
* private fields (`#foo`) have a non-zero per-access cost in V8
* which is measurable on the hot render path, so `#` is used only
* for rarely-accessed memoized caches and Maps.
*/
export declare class FetchState implements AstroFetchState {
#private;
pipeline: Pipeline;
/**
* The request to render. Mutated during rewrites so subsequent renders
* see the rewritten URL.
*/
request: Request;
routeData: RouteData | undefined;
/**
* The pathname to use for routing and rendering. Starts out as the raw,
* base-stripped, decoded pathname from the request. May be further
* normalized by `AstroHandler` after routeData is known (in dev, when
* the matched route has no `.html` extension, `.html` / `/index.html`
* suffixes are stripped).
*/
pathname: string;
/** Resolved render options (addCookieHeader, clientAddress, locals, etc.). */
readonly renderOptions: ResolvedRenderOptions;
/** When the request started, used to log duration. */
readonly timeStart: number;
/**
* The route's loaded component module. Set before middleware runs; may
* be swapped during in-flight rewrites from inside the middleware chain.
*/
componentInstance: ComponentInstance | undefined;
/**
* Slot overrides supplied by the container API. `undefined` for HTTP
* requests — `PagesHandler` coalesces to `{}` on read so we don't
* allocate an empty object per request.
*/
slots: Record<string, any> | undefined;
/**
* The `Response` produced by handlers, if any. Set after page
* rendering or middleware completes.
*/
response: Response | undefined;
/**
* Default HTTP status for the rendered response. Callers override
* before rendering runs (e.g. `AstroHandler` sets this from
* `BaseApp.getDefaultStatusCode`; error handlers set `404` / `500`).
*/
status: number;
/** Whether user middleware should be skipped for this request. */
skipMiddleware: boolean;
/** A flag that tells the render content if the rewriting was triggered. */
isRewriting: boolean;
/** A safety net in case of loops (rewrite counter). */
counter: number;
/** Cookies for this request. Created lazily on first access. */
cookies: AstroCookies;
get params(): Params | undefined;
set params(value: Params | undefined);
/** Normalized URL for this request. */
url: URL;
/** Client address for this request. */
clientAddress: string | undefined;
/** Whether this is a partial render (container API). */
partial: boolean | undefined;
/** Whether to inject CSP meta tags. */
shouldInjectCspMetaTags: boolean | undefined;
/** Request-scoped locals object, shared with user middleware. */
locals: App.Locals;
/**
* Memoized `props` (see `getProps`). `null` means "not yet computed"
* — using `null` (rather than `undefined`) keeps the hidden class
* stable and distinct from a valid-but-empty result.
*/
props: APIContext['props'] | null;
/** Memoized `ActionAPIContext` (see `getActionAPIContext`). */
actionApiContext: ActionAPIContext | null;
/** Memoized `APIContext` (see `getAPIContext`). */
apiContext: APIContext | null;
/** SSR result for the current page render. */
result: SSRResult | undefined;
/** Initial props (from container/error handler). */
initialProps: Props;
constructor(pipeline: Pipeline, request: Request, options?: ResolvedRenderOptions);
/**
* Triggers a rewrite. Delegates to the Rewrites handler.
*/
rewrite(payload: RewritePayload): Promise<Response>;
/**
* Creates the SSR result for the current page render.
*/
createResult(mod: ComponentInstance, ctx: ActionAPIContext): Promise<SSRResult>;
/**
* Creates the Astro global object for a component render.
*/
createAstro(result: SSRResult, props: Record<string, any>, slotValues: Record<string, any> | null, apiContext: ActionAPIContext): AstroGlobal;
/**
* Creates the Astro page-level partial (prototype for Astro global).
*/
createAstroPagePartial(result: SSRResult, apiContext: ActionAPIContext): Omit<AstroGlobal, 'props' | 'self' | 'slots'>;
getClientAddress(): string;
getCookies(): AstroCookies;
getCsp(): APIContext['csp'];
computeCurrentLocale(): string | undefined;
computePreferredLocale(): string | undefined;
computePreferredLocaleList(): string[] | undefined;
/**
* Lazily loads the route's component module. Returns the cached
* instance if already loaded. The promise is cached so concurrent
* callers share the same load.
*/
loadComponentInstance(): Promise<ComponentInstance>;
/**
* Registers a context provider under the given key. Handlers call
* this to contribute values to the request context (e.g. sessions).
* The `create` factory is called lazily on the first `resolve(key)`.
*/
provide<T>(key: string, provider: ContextProvider<T>): void;
/**
* Lazily resolves a provider registered under `key`. Calls
* `provider.create()` on first access and caches the result.
* Returns `undefined` if no provider was registered for the key.
*/
resolve<T>(key: string): T | undefined;
/**
* Runs all registered `finalize` callbacks. Should be called after
* the response is produced, typically in a `finally` block.
*
* Returns synchronously (no promise allocation) when nothing needs
* finalizing — important for the hot path where sessions are not used.
*/
finalizeAll(): Promise<void> | void;
/**
* Adds lazy getters to `target` for each registered provider key.
* Used by context creation (APIContext, Astro global) so that
* provider values like `session` and `cache` appear as properties
* without hard-coding the keys.
*/
defineProviderGetters(target: Record<string, any>): void;
/**
* Returns the resolved `props` for this render, computing them lazily
* from the route + component module on first access. If the
* `initialProps` already carries user-supplied props (e.g. the
* container API) those are used verbatim.
*/
getProps(): Promise<APIContext['props']>;
/**
* Returns the `ActionAPIContext` for this render, creating it lazily.
* Used by middleware, actions, and page dispatch.
*/
getActionAPIContext(): ActionAPIContext;
/**
* Returns the `APIContext` for this render, creating it lazily from
* the memoized props + action context.
*
* Callers must ensure `getProps()` has resolved at least once before
* calling this.
*/
getAPIContext(): APIContext;
/**
* Invalidates the cached `APIContext` so the next `getAPIContext()`
* call re-derives it from the (possibly mutated) state. Used
* after an in-flight rewrite swaps the route / request / params.
*/
invalidateContexts(): void;
}