feat: scaffold Astro + Tailwind project
This commit is contained in:
17
node_modules/astro/dist/core/fetch/default-handler.d.ts
generated
vendored
Normal file
17
node_modules/astro/dist/core/fetch/default-handler.d.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import type { BaseApp, ResolvedRenderOptions } from '../app/base.js';
|
||||
import type { Pipeline } from '../base-pipeline.js';
|
||||
import type { FetchHandler } from './types.js';
|
||||
/**
|
||||
* The default request handler for `BaseApp`. Builds the per-request
|
||||
* `FetchState` and delegates to an `AstroHandler`.
|
||||
*/
|
||||
export declare class DefaultFetchHandler {
|
||||
#private;
|
||||
constructor(app?: BaseApp<Pipeline>);
|
||||
/**
|
||||
* Fast path: called directly by `BaseApp.render()` with pre-resolved
|
||||
* options, avoiding the `Reflect.set/get` round-trip through the request.
|
||||
*/
|
||||
renderWithOptions(request: Request, options: ResolvedRenderOptions): Promise<Response>;
|
||||
fetch: FetchHandler;
|
||||
}
|
||||
45
node_modules/astro/dist/core/fetch/default-handler.js
generated
vendored
Normal file
45
node_modules/astro/dist/core/fetch/default-handler.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
import { FetchState } from "./fetch-state.js";
|
||||
import { appSymbol } from "../constants.js";
|
||||
import { AstroHandler } from "../routing/handler.js";
|
||||
class DefaultFetchHandler {
|
||||
#app;
|
||||
#handler;
|
||||
constructor(app) {
|
||||
this.#app = app ?? null;
|
||||
this.#handler = app ? new AstroHandler(app) : null;
|
||||
}
|
||||
/**
|
||||
* Fast path: called directly by `BaseApp.render()` with pre-resolved
|
||||
* options, avoiding the `Reflect.set/get` round-trip through the request.
|
||||
*/
|
||||
renderWithOptions(request, options) {
|
||||
if (!this.#app) {
|
||||
const app = Reflect.get(request, appSymbol);
|
||||
if (!app) {
|
||||
throw new Error("No fetch handler provided.");
|
||||
}
|
||||
this.#app = app;
|
||||
this.#handler = new AstroHandler(app);
|
||||
}
|
||||
const state = new FetchState(this.#app.pipeline, request, options);
|
||||
return this.#handler.handle(state);
|
||||
}
|
||||
fetch = (request) => {
|
||||
if (!this.#app) {
|
||||
const app = Reflect.get(request, appSymbol);
|
||||
if (!app) {
|
||||
throw new Error("No fetch handler provided.");
|
||||
}
|
||||
this.#app = app;
|
||||
this.#handler = new AstroHandler(app);
|
||||
}
|
||||
const state = new FetchState(this.#app.pipeline, request);
|
||||
if (!this.#handler) {
|
||||
throw new Error("No fetch handler provided.");
|
||||
}
|
||||
return this.#handler.handle(state);
|
||||
};
|
||||
}
|
||||
export {
|
||||
DefaultFetchHandler
|
||||
};
|
||||
244
node_modules/astro/dist/core/fetch/fetch-state.d.ts
generated
vendored
Normal file
244
node_modules/astro/dist/core/fetch/fetch-state.d.ts
generated
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
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;
|
||||
/** 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;
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
779
node_modules/astro/dist/core/fetch/fetch-state.js
generated
vendored
Normal file
779
node_modules/astro/dist/core/fetch/fetch-state.js
generated
vendored
Normal file
@@ -0,0 +1,779 @@
|
||||
import colors from "piccolore";
|
||||
import {
|
||||
collapseDuplicateLeadingSlashes,
|
||||
prependForwardSlash,
|
||||
removeTrailingForwardSlash
|
||||
} from "@astrojs/internal-helpers/path";
|
||||
import { deserializeActionResult } from "../../actions/runtime/client.js";
|
||||
import { createCallAction, createGetActionResult, hasActionPayload } from "../../actions/utils.js";
|
||||
import { AstroCookies } from "../cookies/index.js";
|
||||
import { Slots } from "../render/index.js";
|
||||
import {
|
||||
ASTRO_GENERATOR,
|
||||
DEFAULT_404_COMPONENT,
|
||||
fetchStateSymbol,
|
||||
originPathnameSymbol,
|
||||
pipelineSymbol,
|
||||
responseSentSymbol
|
||||
} from "../constants.js";
|
||||
import { pushDirective } from "../csp/runtime.js";
|
||||
import { generateCspDigest } from "../encryption.js";
|
||||
import { AstroError, AstroErrorData } from "../errors/index.js";
|
||||
import {
|
||||
computeCurrentLocale as computeCurrentLocaleUtil,
|
||||
computeCurrentLocaleFromParams,
|
||||
computePreferredLocale as computePreferredLocaleUtil,
|
||||
computePreferredLocaleList as computePreferredLocaleListUtil
|
||||
} from "../../i18n/utils.js";
|
||||
import { getParams, getProps } from "../render/index.js";
|
||||
import { Rewrites } from "../rewrites/handler.js";
|
||||
import { isRoute404or500, isRouteServerIsland } from "../routing/match.js";
|
||||
import { normalizeUrl } from "../util/normalized-url.js";
|
||||
import { getOriginPathname, setOriginPathname } from "../routing/rewrite.js";
|
||||
import { routeHasHtmlExtension } from "../routing/helpers.js";
|
||||
import { getRenderOptions } from "../app/render-options.js";
|
||||
function getFetchStateFromAPIContext(context) {
|
||||
const state = context[fetchStateSymbol];
|
||||
if (!state) {
|
||||
throw new Error(
|
||||
"FetchState not found on APIContext. This is an internal error \u2014 the context was not created through Astro's request pipeline."
|
||||
);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
class FetchState {
|
||||
pipeline;
|
||||
/**
|
||||
* The request to render. Mutated during rewrites so subsequent renders
|
||||
* see the rewritten URL.
|
||||
*/
|
||||
request;
|
||||
routeData;
|
||||
/**
|
||||
* 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;
|
||||
/** Resolved render options (addCookieHeader, clientAddress, locals, etc.). */
|
||||
renderOptions;
|
||||
/** When the request started, used to log duration. */
|
||||
timeStart;
|
||||
/**
|
||||
* The route's loaded component module. Set before middleware runs; may
|
||||
* be swapped during in-flight rewrites from inside the middleware chain.
|
||||
*/
|
||||
componentInstance;
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* 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 = 200;
|
||||
/** Whether user middleware should be skipped for this request. */
|
||||
skipMiddleware = false;
|
||||
/** A flag that tells the render content if the rewriting was triggered. */
|
||||
isRewriting = false;
|
||||
/** A safety net in case of loops (rewrite counter). */
|
||||
counter = 0;
|
||||
/** Cookies for this request. Created lazily on first access. */
|
||||
cookies;
|
||||
/** Route params derived from routeData + pathname. Computed lazily. */
|
||||
#params;
|
||||
get params() {
|
||||
if (!this.#params && this.routeData) {
|
||||
this.#params = getParams(this.routeData, this.pathname);
|
||||
}
|
||||
return this.#params;
|
||||
}
|
||||
set params(value) {
|
||||
this.#params = value;
|
||||
}
|
||||
/** Normalized URL for this request. */
|
||||
url;
|
||||
/** Client address for this request. */
|
||||
clientAddress;
|
||||
/** Whether this is a partial render (container API). */
|
||||
partial;
|
||||
/** Whether to inject CSP meta tags. */
|
||||
shouldInjectCspMetaTags;
|
||||
/** Request-scoped locals object, shared with user middleware. */
|
||||
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 = null;
|
||||
/** Memoized `ActionAPIContext` (see `getActionAPIContext`). */
|
||||
actionApiContext = null;
|
||||
/** Memoized `APIContext` (see `getAPIContext`). */
|
||||
apiContext = null;
|
||||
/** Registered context providers keyed by name. Lazy-initialized on first provide(). */
|
||||
#providers;
|
||||
/** Cached values from resolved providers. Lazy-initialized on first resolve(). */
|
||||
#providersResolvedValues;
|
||||
/** Cached promise for lazy component instance loading. */
|
||||
#componentInstancePromise;
|
||||
/** SSR result for the current page render. */
|
||||
result;
|
||||
/** Initial props (from container/error handler). */
|
||||
initialProps = {};
|
||||
/** Rewrites handler instance. Lazy-initialized on first rewrite(). */
|
||||
#rewrites;
|
||||
/** Memoized Astro page partial. */
|
||||
#astroPagePartial;
|
||||
/** Memoized current locale. */
|
||||
#currentLocale;
|
||||
/** Memoized preferred locale. */
|
||||
#preferredLocale;
|
||||
/** Memoized preferred locale list. */
|
||||
#preferredLocaleList;
|
||||
constructor(pipeline, request, options) {
|
||||
this.pipeline = pipeline;
|
||||
this.request = request;
|
||||
options ??= getRenderOptions(request);
|
||||
this.routeData = options?.routeData;
|
||||
this.renderOptions = options ?? {
|
||||
addCookieHeader: false,
|
||||
clientAddress: void 0,
|
||||
locals: void 0,
|
||||
prerenderedErrorPageFetch: fetch,
|
||||
routeData: void 0,
|
||||
waitUntil: void 0
|
||||
};
|
||||
this.componentInstance = void 0;
|
||||
this.slots = void 0;
|
||||
const url = new URL(request.url);
|
||||
this.pathname = this.#computePathname(url);
|
||||
this.timeStart = performance.now();
|
||||
this.clientAddress = options?.clientAddress;
|
||||
this.locals = options?.locals ?? {};
|
||||
this.url = normalizeUrl(url);
|
||||
this.cookies = new AstroCookies(request);
|
||||
if (!Reflect.get(request, originPathnameSymbol)) {
|
||||
setOriginPathname(
|
||||
request,
|
||||
this.pathname,
|
||||
pipeline.manifest.trailingSlash,
|
||||
pipeline.manifest.buildFormat
|
||||
);
|
||||
}
|
||||
this.#resolveRouteData();
|
||||
}
|
||||
/**
|
||||
* Triggers a rewrite. Delegates to the Rewrites handler.
|
||||
*/
|
||||
rewrite(payload) {
|
||||
return (this.#rewrites ??= new Rewrites()).execute(this, payload);
|
||||
}
|
||||
/**
|
||||
* Creates the SSR result for the current page render.
|
||||
*/
|
||||
async createResult(mod, ctx) {
|
||||
const pipeline = this.pipeline;
|
||||
const { clientDirectives, inlinedScripts, compressHTML, manifest, renderers, resolve } = pipeline;
|
||||
const routeData = this.routeData;
|
||||
const { links, scripts, styles } = await pipeline.headElements(routeData);
|
||||
const extraStyleHashes = [];
|
||||
const extraScriptHashes = [];
|
||||
const shouldInjectCspMetaTags = this.shouldInjectCspMetaTags ?? manifest.shouldInjectCspMetaTags;
|
||||
const cspAlgorithm = manifest.csp?.algorithm ?? "SHA-256";
|
||||
if (shouldInjectCspMetaTags) {
|
||||
for (const style of styles) {
|
||||
extraStyleHashes.push(await generateCspDigest(style.children, cspAlgorithm));
|
||||
}
|
||||
for (const script of scripts) {
|
||||
extraScriptHashes.push(await generateCspDigest(script.children, cspAlgorithm));
|
||||
}
|
||||
}
|
||||
const componentMetadata = await pipeline.componentMetadata(routeData) ?? manifest.componentMetadata;
|
||||
const headers = new Headers({ "Content-Type": "text/html" });
|
||||
const partial = typeof this.partial === "boolean" ? this.partial : Boolean(mod.partial);
|
||||
const actionResult = hasActionPayload(this.locals) ? deserializeActionResult(this.locals._actionPayload.actionResult) : void 0;
|
||||
const status = this.status;
|
||||
const response = {
|
||||
status: actionResult?.error ? actionResult?.error.status : status,
|
||||
statusText: actionResult?.error ? actionResult?.error.type : "OK",
|
||||
get headers() {
|
||||
return headers;
|
||||
},
|
||||
set headers(_) {
|
||||
throw new AstroError(AstroErrorData.AstroResponseHeadersReassigned);
|
||||
}
|
||||
};
|
||||
const state = this;
|
||||
const result = {
|
||||
base: manifest.base,
|
||||
userAssetsBase: manifest.userAssetsBase,
|
||||
cancelled: false,
|
||||
clientDirectives,
|
||||
inlinedScripts,
|
||||
componentMetadata,
|
||||
compressHTML,
|
||||
cookies: this.cookies,
|
||||
createAstro: (props, slots) => state.createAstro(result, props, slots, ctx),
|
||||
links,
|
||||
// SAFETY: createResult is only called after route resolution, so routeData
|
||||
// is always set and the params getter always returns a value.
|
||||
params: this.params,
|
||||
partial,
|
||||
pathname: this.pathname,
|
||||
renderers,
|
||||
resolve,
|
||||
response,
|
||||
request: this.request,
|
||||
scripts,
|
||||
styles,
|
||||
actionResult,
|
||||
async getServerIslandNameMap() {
|
||||
const serverIslands = await pipeline.getServerIslands();
|
||||
return serverIslands.serverIslandNameMap ?? /* @__PURE__ */ new Map();
|
||||
},
|
||||
key: manifest.key,
|
||||
trailingSlash: manifest.trailingSlash,
|
||||
_experimentalQueuedRendering: {
|
||||
pool: pipeline.nodePool,
|
||||
htmlStringCache: pipeline.htmlStringCache,
|
||||
enabled: manifest.experimentalQueuedRendering?.enabled,
|
||||
poolSize: manifest.experimentalQueuedRendering?.poolSize,
|
||||
contentCache: manifest.experimentalQueuedRendering?.contentCache
|
||||
},
|
||||
_metadata: {
|
||||
hasHydrationScript: false,
|
||||
rendererSpecificHydrationScripts: /* @__PURE__ */ new Set(),
|
||||
hasRenderedHead: false,
|
||||
renderedScripts: /* @__PURE__ */ new Set(),
|
||||
hasDirectives: /* @__PURE__ */ new Set(),
|
||||
hasRenderedServerIslandRuntime: false,
|
||||
headInTree: false,
|
||||
extraHead: [],
|
||||
extraStyleHashes,
|
||||
extraScriptHashes,
|
||||
propagators: /* @__PURE__ */ new Set(),
|
||||
templateDepth: 0
|
||||
},
|
||||
cspDestination: manifest.csp?.cspDestination ?? (routeData.prerender ? "meta" : "header"),
|
||||
shouldInjectCspMetaTags,
|
||||
cspAlgorithm,
|
||||
scriptHashes: manifest.csp?.scriptHashes ? [...manifest.csp.scriptHashes] : [],
|
||||
scriptResources: manifest.csp?.scriptResources ? [...manifest.csp.scriptResources] : [],
|
||||
styleHashes: manifest.csp?.styleHashes ? [...manifest.csp.styleHashes] : [],
|
||||
styleResources: manifest.csp?.styleResources ? [...manifest.csp.styleResources] : [],
|
||||
directives: manifest.csp?.directives ? [...manifest.csp.directives] : [],
|
||||
isStrictDynamic: manifest.csp?.isStrictDynamic ?? false,
|
||||
internalFetchHeaders: manifest.internalFetchHeaders
|
||||
};
|
||||
this.result = result;
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Creates the Astro global object for a component render.
|
||||
*/
|
||||
createAstro(result, props, slotValues, apiContext) {
|
||||
let astroPagePartial;
|
||||
if (this.isRewriting) {
|
||||
this.#astroPagePartial = this.createAstroPagePartial(result, apiContext);
|
||||
}
|
||||
this.#astroPagePartial ??= this.createAstroPagePartial(result, apiContext);
|
||||
astroPagePartial = this.#astroPagePartial;
|
||||
const astroComponentPartial = { props, self: null };
|
||||
const Astro = Object.assign(
|
||||
Object.create(astroPagePartial),
|
||||
astroComponentPartial
|
||||
);
|
||||
let _slots;
|
||||
Object.defineProperty(Astro, "slots", {
|
||||
get: () => {
|
||||
if (!_slots) {
|
||||
_slots = new Slots(
|
||||
result,
|
||||
slotValues,
|
||||
this.pipeline.logger
|
||||
);
|
||||
}
|
||||
return _slots;
|
||||
}
|
||||
});
|
||||
return Astro;
|
||||
}
|
||||
/**
|
||||
* Creates the Astro page-level partial (prototype for Astro global).
|
||||
*/
|
||||
createAstroPagePartial(result, apiContext) {
|
||||
const state = this;
|
||||
const { cookies, locals, params, pipeline, url } = this;
|
||||
const { response } = result;
|
||||
const redirect = (path, status = 302) => {
|
||||
if (state.request[responseSentSymbol]) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.ResponseSentError
|
||||
});
|
||||
}
|
||||
return new Response(null, { status, headers: { Location: path } });
|
||||
};
|
||||
const rewrite = async (reroutePayload) => {
|
||||
return await state.rewrite(reroutePayload);
|
||||
};
|
||||
const callAction = createCallAction(apiContext);
|
||||
const partial = {
|
||||
generator: ASTRO_GENERATOR,
|
||||
routePattern: this.routeData.route,
|
||||
isPrerendered: this.routeData.prerender,
|
||||
cookies,
|
||||
get clientAddress() {
|
||||
return state.getClientAddress();
|
||||
},
|
||||
get currentLocale() {
|
||||
return state.computeCurrentLocale();
|
||||
},
|
||||
params,
|
||||
get preferredLocale() {
|
||||
return state.computePreferredLocale();
|
||||
},
|
||||
get preferredLocaleList() {
|
||||
return state.computePreferredLocaleList();
|
||||
},
|
||||
locals,
|
||||
redirect,
|
||||
rewrite,
|
||||
request: this.request,
|
||||
response,
|
||||
site: pipeline.site,
|
||||
getActionResult: createGetActionResult(locals),
|
||||
get callAction() {
|
||||
return callAction;
|
||||
},
|
||||
url,
|
||||
get originPathname() {
|
||||
return getOriginPathname(state.request);
|
||||
},
|
||||
get csp() {
|
||||
return state.getCsp();
|
||||
},
|
||||
get logger() {
|
||||
return {
|
||||
info(msg) {
|
||||
pipeline.logger.info(null, msg);
|
||||
},
|
||||
warn(msg) {
|
||||
pipeline.logger.warn(null, msg);
|
||||
},
|
||||
error(msg) {
|
||||
pipeline.logger.error(null, msg);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
this.defineProviderGetters(partial);
|
||||
return partial;
|
||||
}
|
||||
getClientAddress() {
|
||||
const { pipeline, clientAddress } = this;
|
||||
const routeData = this.routeData;
|
||||
if (routeData.prerender) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.PrerenderClientAddressNotAvailable,
|
||||
message: AstroErrorData.PrerenderClientAddressNotAvailable.message(routeData.component)
|
||||
});
|
||||
}
|
||||
if (clientAddress) {
|
||||
return clientAddress;
|
||||
}
|
||||
if (pipeline.adapterName) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.ClientAddressNotAvailable,
|
||||
message: AstroErrorData.ClientAddressNotAvailable.message(pipeline.adapterName)
|
||||
});
|
||||
}
|
||||
throw new AstroError(AstroErrorData.StaticClientAddressNotAvailable);
|
||||
}
|
||||
getCookies() {
|
||||
return this.cookies;
|
||||
}
|
||||
getCsp() {
|
||||
const state = this;
|
||||
const { pipeline } = this;
|
||||
if (!pipeline.manifest.csp) {
|
||||
if (pipeline.runtimeMode === "production") {
|
||||
pipeline.logger.warn(
|
||||
"csp",
|
||||
`context.csp was used when rendering the route ${colors.green(state.routeData.route)}, but CSP was not configured. For more information, see https://docs.astro.build/en/reference/configuration-reference/#securitycsp`
|
||||
);
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
return {
|
||||
insertDirective(payload) {
|
||||
if (state?.result?.directives) {
|
||||
state.result.directives = pushDirective(state.result.directives, payload);
|
||||
} else {
|
||||
state?.result?.directives.push(payload);
|
||||
}
|
||||
},
|
||||
insertScriptResource(resource) {
|
||||
state.result?.scriptResources.push(resource);
|
||||
},
|
||||
insertStyleResource(resource) {
|
||||
state.result?.styleResources.push(resource);
|
||||
},
|
||||
insertStyleHash(hash) {
|
||||
state.result?.styleHashes.push(hash);
|
||||
},
|
||||
insertScriptHash(hash) {
|
||||
state.result?.scriptHashes.push(hash);
|
||||
}
|
||||
};
|
||||
}
|
||||
computeCurrentLocale() {
|
||||
const {
|
||||
url,
|
||||
pipeline: { i18n },
|
||||
routeData
|
||||
} = this;
|
||||
if (!i18n || !routeData) return;
|
||||
const { defaultLocale, locales, strategy } = i18n;
|
||||
const fallbackTo = strategy === "pathname-prefix-other-locales" || strategy === "domains-prefix-other-locales" ? defaultLocale : void 0;
|
||||
if (this.#currentLocale) {
|
||||
return this.#currentLocale;
|
||||
}
|
||||
let computedLocale;
|
||||
if (isRouteServerIsland(routeData)) {
|
||||
let referer = this.request.headers.get("referer");
|
||||
if (referer) {
|
||||
if (URL.canParse(referer)) {
|
||||
referer = new URL(referer).pathname;
|
||||
}
|
||||
computedLocale = computeCurrentLocaleUtil(referer, locales, defaultLocale);
|
||||
}
|
||||
} else {
|
||||
let pathname = routeData.pathname;
|
||||
if (url && !routeData.pattern.test(url.pathname)) {
|
||||
for (const fallbackRoute of routeData.fallbackRoutes) {
|
||||
if (fallbackRoute.pattern.test(url.pathname)) {
|
||||
pathname = fallbackRoute.pathname;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pathname = pathname && !isRoute404or500(routeData) ? pathname : url.pathname ?? this.pathname;
|
||||
computedLocale = computeCurrentLocaleUtil(pathname, locales, defaultLocale);
|
||||
if (routeData.params.length > 0) {
|
||||
const localeFromParams = computeCurrentLocaleFromParams(this.params, locales);
|
||||
if (localeFromParams) {
|
||||
computedLocale = localeFromParams;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.#currentLocale = computedLocale ?? fallbackTo;
|
||||
return this.#currentLocale;
|
||||
}
|
||||
computePreferredLocale() {
|
||||
const {
|
||||
pipeline: { i18n },
|
||||
request
|
||||
} = this;
|
||||
if (!i18n) return;
|
||||
return this.#preferredLocale ??= computePreferredLocaleUtil(request, i18n.locales);
|
||||
}
|
||||
computePreferredLocaleList() {
|
||||
const {
|
||||
pipeline: { i18n },
|
||||
request
|
||||
} = this;
|
||||
if (!i18n) return;
|
||||
return this.#preferredLocaleList ??= computePreferredLocaleListUtil(request, i18n.locales);
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
async loadComponentInstance() {
|
||||
if (this.componentInstance) return this.componentInstance;
|
||||
if (this.#componentInstancePromise) return this.#componentInstancePromise;
|
||||
this.#componentInstancePromise = this.pipeline.getComponentByRoute(this.routeData).then((mod) => {
|
||||
this.componentInstance = mod;
|
||||
return mod;
|
||||
});
|
||||
return this.#componentInstancePromise;
|
||||
}
|
||||
/**
|
||||
* 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(key, provider) {
|
||||
(this.#providers ??= /* @__PURE__ */ new Map()).set(key, provider);
|
||||
}
|
||||
/**
|
||||
* 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(key) {
|
||||
if (this.#providersResolvedValues?.has(key)) {
|
||||
return this.#providersResolvedValues.get(key);
|
||||
}
|
||||
const provider = this.#providers?.get(key);
|
||||
if (!provider) return void 0;
|
||||
const value = provider.create();
|
||||
(this.#providersResolvedValues ??= /* @__PURE__ */ new Map()).set(key, value);
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* 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() {
|
||||
if (!this.#providersResolvedValues || this.#providersResolvedValues.size === 0) return;
|
||||
let chain;
|
||||
for (const [key, provider] of this.#providers) {
|
||||
if (provider.finalize && this.#providersResolvedValues.has(key)) {
|
||||
const result = provider.finalize(this.#providersResolvedValues.get(key));
|
||||
if (result) {
|
||||
chain = chain ? chain.then(() => result) : result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return chain;
|
||||
}
|
||||
/**
|
||||
* 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) {
|
||||
if (!this.#providers) return;
|
||||
const state = this;
|
||||
for (const key of this.#providers.keys()) {
|
||||
Object.defineProperty(target, key, {
|
||||
get: () => state.resolve(key),
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Resolves the route to use for this request and stores it on
|
||||
* `this.routeData`. If the adapter (or the dev server) provided a
|
||||
* `routeData` via render options it's already set and this is a
|
||||
* no-op. Otherwise we use the app's synchronous route matcher and
|
||||
* fall back to a `404.astro` route so middleware can still run.
|
||||
*
|
||||
* Called eagerly from the constructor so individual handlers
|
||||
* (actions, pages, middleware, etc.) always see a resolved route
|
||||
* without the caller needing an extra setup step.
|
||||
*
|
||||
* Once routeData is known, finalizes `this.pathname`: in dev, if the
|
||||
* matched route has no `.html` extension, strip `.html` / `/index.html`
|
||||
* suffixes so the rendering pipeline sees the canonical pathname.
|
||||
*/
|
||||
/**
|
||||
* Strip `.html` / `/index.html` suffixes from the pathname so the
|
||||
* rendering pipeline sees the canonical route path. Skipped when the
|
||||
* matched route itself has an `.html` extension in its definition.
|
||||
*/
|
||||
#stripHtmlExtension() {
|
||||
if (this.routeData && !routeHasHtmlExtension(this.routeData)) {
|
||||
this.pathname = this.pathname.replace(/\/index\.html$/, "/").replace(/\.html$/, "");
|
||||
}
|
||||
}
|
||||
#resolveRouteData() {
|
||||
const pipeline = this.pipeline;
|
||||
if (this.routeData) {
|
||||
this.#stripHtmlExtension();
|
||||
return;
|
||||
}
|
||||
const matched = pipeline.matchRoute(this.pathname);
|
||||
if (matched && matched.prerender && pipeline.manifest.serverLike) {
|
||||
this.routeData = void 0;
|
||||
} else {
|
||||
this.routeData = matched;
|
||||
}
|
||||
pipeline.logger.debug("router", "Astro matched the following route for " + this.request.url);
|
||||
pipeline.logger.debug("router", "RouteData:\n" + this.routeData);
|
||||
if (!this.routeData) {
|
||||
this.routeData = pipeline.manifestData.routes.find(
|
||||
(route) => route.component === "404.astro" || route.component === DEFAULT_404_COMPONENT
|
||||
);
|
||||
}
|
||||
if (!this.routeData) {
|
||||
pipeline.logger.debug("router", "Astro hasn't found routes that match " + this.request.url);
|
||||
pipeline.logger.debug("router", "Here's the available routes:\n", pipeline.manifestData);
|
||||
return;
|
||||
}
|
||||
this.#stripHtmlExtension();
|
||||
}
|
||||
/**
|
||||
* Strips the pipeline's base from the request URL, prepends a forward
|
||||
* slash, and decodes the pathname. Falls back to the raw (not decoded)
|
||||
* pathname if `decodeURI` throws.
|
||||
*
|
||||
* Mirrors `BaseApp.removeBase`, including the
|
||||
* `collapseDuplicateLeadingSlashes` fix that prevents middleware
|
||||
* authorization bypass when the URL starts with `//`.
|
||||
*/
|
||||
#computePathname(url) {
|
||||
let pathname = collapseDuplicateLeadingSlashes(url.pathname);
|
||||
const base = this.pipeline.manifest.base;
|
||||
if (pathname.startsWith(base)) {
|
||||
const baseWithoutTrailingSlash = removeTrailingForwardSlash(base);
|
||||
pathname = pathname.slice(baseWithoutTrailingSlash.length + 1);
|
||||
}
|
||||
pathname = prependForwardSlash(pathname);
|
||||
try {
|
||||
return decodeURI(pathname);
|
||||
} catch (e) {
|
||||
this.pipeline.logger.error(null, e.toString());
|
||||
return pathname;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
async getProps() {
|
||||
if (this.props !== null) return this.props;
|
||||
if (Object.keys(this.initialProps).length > 0) {
|
||||
this.props = this.initialProps;
|
||||
return this.props;
|
||||
}
|
||||
const pipeline = this.pipeline;
|
||||
const mod = await this.loadComponentInstance();
|
||||
this.props = await getProps({
|
||||
mod,
|
||||
routeData: this.routeData,
|
||||
routeCache: pipeline.routeCache,
|
||||
pathname: this.pathname,
|
||||
logger: pipeline.logger,
|
||||
serverLike: pipeline.manifest.serverLike,
|
||||
base: pipeline.manifest.base,
|
||||
trailingSlash: pipeline.manifest.trailingSlash
|
||||
});
|
||||
return this.props;
|
||||
}
|
||||
/**
|
||||
* Returns the `ActionAPIContext` for this render, creating it lazily.
|
||||
* Used by middleware, actions, and page dispatch.
|
||||
*/
|
||||
getActionAPIContext() {
|
||||
if (this.actionApiContext !== null) return this.actionApiContext;
|
||||
const state = this;
|
||||
const ctx = {
|
||||
get cookies() {
|
||||
return state.cookies;
|
||||
},
|
||||
routePattern: this.routeData.route,
|
||||
isPrerendered: this.routeData.prerender,
|
||||
get clientAddress() {
|
||||
return state.getClientAddress();
|
||||
},
|
||||
get currentLocale() {
|
||||
return state.computeCurrentLocale();
|
||||
},
|
||||
generator: ASTRO_GENERATOR,
|
||||
get locals() {
|
||||
return state.locals;
|
||||
},
|
||||
set locals(_) {
|
||||
throw new AstroError(AstroErrorData.LocalsReassigned);
|
||||
},
|
||||
// SAFETY: getActionAPIContext is only called after route resolution,
|
||||
// so routeData is always set and the params getter always returns a value.
|
||||
params: this.params,
|
||||
get preferredLocale() {
|
||||
return state.computePreferredLocale();
|
||||
},
|
||||
get preferredLocaleList() {
|
||||
return state.computePreferredLocaleList();
|
||||
},
|
||||
request: this.request,
|
||||
site: this.pipeline.site,
|
||||
url: this.url,
|
||||
get originPathname() {
|
||||
return getOriginPathname(state.request);
|
||||
},
|
||||
get csp() {
|
||||
return state.getCsp();
|
||||
},
|
||||
get logger() {
|
||||
if (!state.pipeline.manifest.experimentalLogger) {
|
||||
state.pipeline.logger.warn(
|
||||
null,
|
||||
"The Astro.logger is available only when experimental.logger is defined."
|
||||
);
|
||||
return void 0;
|
||||
}
|
||||
return {
|
||||
info(msg) {
|
||||
state.pipeline.logger.info(null, msg);
|
||||
},
|
||||
warn(msg) {
|
||||
state.pipeline.logger.warn(null, msg);
|
||||
},
|
||||
error(msg) {
|
||||
state.pipeline.logger.error(null, msg);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
this.defineProviderGetters(ctx);
|
||||
this.actionApiContext = ctx;
|
||||
return this.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() {
|
||||
if (this.apiContext !== null) return this.apiContext;
|
||||
const actionApiContext = this.getActionAPIContext();
|
||||
const state = this;
|
||||
const redirect = (path, status = 302) => new Response(null, { status, headers: { Location: path } });
|
||||
const rewrite = async (reroutePayload) => {
|
||||
return await state.rewrite(reroutePayload);
|
||||
};
|
||||
Reflect.set(actionApiContext, pipelineSymbol, this.pipeline);
|
||||
actionApiContext[fetchStateSymbol] = this;
|
||||
this.apiContext = Object.assign(actionApiContext, {
|
||||
props: this.props,
|
||||
redirect,
|
||||
rewrite,
|
||||
getActionResult: createGetActionResult(actionApiContext.locals),
|
||||
callAction: createCallAction(actionApiContext)
|
||||
});
|
||||
return this.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() {
|
||||
this.props = null;
|
||||
this.actionApiContext = null;
|
||||
this.apiContext = null;
|
||||
}
|
||||
}
|
||||
export {
|
||||
FetchState,
|
||||
getFetchStateFromAPIContext
|
||||
};
|
||||
61
node_modules/astro/dist/core/fetch/index.d.ts
generated
vendored
Normal file
61
node_modules/astro/dist/core/fetch/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
import { FetchState as BaseFetchState } from './fetch-state.js';
|
||||
import type { AstroFetchState } from './fetch-state.js';
|
||||
export type { AstroFetchState };
|
||||
export declare class FetchState extends BaseFetchState {
|
||||
constructor(request: Request);
|
||||
}
|
||||
export declare function astro(state: FetchState): Promise<Response>;
|
||||
/**
|
||||
* Checks if the request pathname needs trailing-slash normalization and
|
||||
* returns a redirect `Response` if so. Returns `undefined` when no
|
||||
* redirect is needed and the caller should continue processing.
|
||||
*/
|
||||
export declare function trailingSlash(state: FetchState): Response | undefined;
|
||||
/**
|
||||
* Runs Astro's middleware chain for the given state, calling `next` at
|
||||
* the bottom of the chain to produce the response. Lazily creates
|
||||
* the render context if needed.
|
||||
*/
|
||||
export declare function middleware(state: FetchState, next: (state: FetchState) => Promise<Response>): Promise<Response>;
|
||||
/**
|
||||
* Dispatches the request to the matched route (endpoint, page, redirect,
|
||||
* or fallback). Lazily creates the render context if needed.
|
||||
*/
|
||||
export declare function pages(state: FetchState): Promise<Response>;
|
||||
/**
|
||||
* Registers the session provider on the state. The session is created
|
||||
* lazily when user code accesses `ctx.session`, and persisted when
|
||||
* `state.finalizeAll()` is called. No-op if sessions are not configured.
|
||||
*
|
||||
* Call this early (before middleware runs). Call `state.finalizeAll()`
|
||||
* in a `finally` block after the response is produced to persist
|
||||
* any session mutations.
|
||||
*/
|
||||
export declare function sessions(state: FetchState): Promise<void> | void;
|
||||
/**
|
||||
* Checks if the matched route is a redirect and returns the redirect
|
||||
* `Response` if so. Returns `undefined` when the route is not a
|
||||
* redirect and the caller should continue processing.
|
||||
* `state.routeData` must be set before calling this.
|
||||
*/
|
||||
export declare function redirects(state: FetchState): Promise<Response> | undefined;
|
||||
/**
|
||||
* Handles Astro Action requests (RPC + form). Returns a `Response` for
|
||||
* RPC actions, or `undefined` for form actions / non-action requests
|
||||
* (the caller should continue to page rendering). Lazily creates
|
||||
* the render context if needed.
|
||||
*/
|
||||
export declare function actions(state: FetchState): Promise<Response | undefined> | undefined;
|
||||
/**
|
||||
* Post-processes a response against the app's i18n configuration.
|
||||
* Handles locale redirects, 404s for invalid locales, and fallback
|
||||
* routing. Returns the response unmodified if i18n is not configured.
|
||||
*/
|
||||
export declare function i18n(state: FetchState, response: Response): Promise<Response>;
|
||||
/**
|
||||
* Wraps a render callback with cache provider logic. Handles runtime
|
||||
* caching (onRequest), CDN-based providers (headers only), and the
|
||||
* no-cache case transparently. Cache headers are applied and stripped
|
||||
* internally.
|
||||
*/
|
||||
export declare function cache(state: FetchState, next: () => Promise<Response>): Promise<Response>;
|
||||
121
node_modules/astro/dist/core/fetch/index.js
generated
vendored
Normal file
121
node_modules/astro/dist/core/fetch/index.js
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
import { ActionHandler } from "../../actions/handler.js";
|
||||
import { FetchState as BaseFetchState } from "./fetch-state.js";
|
||||
import { CacheHandler } from "../cache/handler.js";
|
||||
import { appSymbol } from "../constants.js";
|
||||
import { I18n } from "../i18n/handler.js";
|
||||
import { AstroMiddleware } from "../middleware/astro-middleware.js";
|
||||
import { PagesHandler } from "../pages/handler.js";
|
||||
import { renderRedirect } from "../redirects/render.js";
|
||||
import { AstroHandler } from "../routing/handler.js";
|
||||
import { provideSession } from "../session/handler.js";
|
||||
import { TrailingSlashHandler } from "../routing/trailing-slash-handler.js";
|
||||
function getApp(request) {
|
||||
const app = Reflect.get(request, appSymbol);
|
||||
if (!app) {
|
||||
throw new Error(
|
||||
"FetchState(request) called on a request without an attached app. Ensure it runs inside Astro's request pipeline."
|
||||
);
|
||||
}
|
||||
return app;
|
||||
}
|
||||
class FetchState extends BaseFetchState {
|
||||
constructor(request) {
|
||||
super(getApp(request).pipeline, request);
|
||||
}
|
||||
}
|
||||
const astroHandlers = /* @__PURE__ */ new WeakMap();
|
||||
function astro(state) {
|
||||
const app = getApp(state.request);
|
||||
let handler = astroHandlers.get(app);
|
||||
if (!handler) {
|
||||
handler = new AstroHandler(app);
|
||||
astroHandlers.set(app, handler);
|
||||
}
|
||||
return handler.handle(state);
|
||||
}
|
||||
const trailingSlashHandlers = /* @__PURE__ */ new WeakMap();
|
||||
function trailingSlash(state) {
|
||||
const app = getApp(state.request);
|
||||
let handler = trailingSlashHandlers.get(app);
|
||||
if (!handler) {
|
||||
handler = new TrailingSlashHandler(app);
|
||||
trailingSlashHandlers.set(app, handler);
|
||||
}
|
||||
return handler.handle(state);
|
||||
}
|
||||
const middlewareInstances = /* @__PURE__ */ new WeakMap();
|
||||
function middleware(state, next) {
|
||||
const app = getApp(state.request);
|
||||
let mw = middlewareInstances.get(app);
|
||||
if (!mw) {
|
||||
mw = new AstroMiddleware(app.pipeline);
|
||||
middlewareInstances.set(app, mw);
|
||||
}
|
||||
return mw.handle(state, (s, _ctx) => next(s));
|
||||
}
|
||||
const pagesHandlers = /* @__PURE__ */ new WeakMap();
|
||||
function pages(state) {
|
||||
const app = getApp(state.request);
|
||||
let handler = pagesHandlers.get(app);
|
||||
if (!handler) {
|
||||
handler = new PagesHandler(app.pipeline);
|
||||
pagesHandlers.set(app, handler);
|
||||
}
|
||||
return handler.handle(state, state.getAPIContext());
|
||||
}
|
||||
function sessions(state) {
|
||||
return provideSession(state);
|
||||
}
|
||||
function redirects(state) {
|
||||
if (state.routeData?.type === "redirect") {
|
||||
return renderRedirect(state);
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
const actionHandlers = /* @__PURE__ */ new WeakMap();
|
||||
function actions(state) {
|
||||
const app = getApp(state.request);
|
||||
let handler = actionHandlers.get(app);
|
||||
if (!handler) {
|
||||
handler = new ActionHandler();
|
||||
actionHandlers.set(app, handler);
|
||||
}
|
||||
return handler.handle(state.getAPIContext(), state);
|
||||
}
|
||||
const i18nHandlers = /* @__PURE__ */ new WeakMap();
|
||||
function getI18n(app) {
|
||||
let handler = i18nHandlers.get(app);
|
||||
if (handler === void 0) {
|
||||
const config = app.manifest.i18n;
|
||||
handler = config && config.strategy !== "manual" ? new I18n(config, app.manifest.base, app.manifest.trailingSlash, app.manifest.buildFormat) : null;
|
||||
i18nHandlers.set(app, handler);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
function i18n(state, response) {
|
||||
const handler = getI18n(getApp(state.request));
|
||||
if (!handler) return Promise.resolve(response);
|
||||
return handler.finalize(state, response);
|
||||
}
|
||||
const cacheHandlers = /* @__PURE__ */ new WeakMap();
|
||||
function cache(state, next) {
|
||||
const app = getApp(state.request);
|
||||
let handler = cacheHandlers.get(app);
|
||||
if (!handler) {
|
||||
handler = new CacheHandler(app);
|
||||
cacheHandlers.set(app, handler);
|
||||
}
|
||||
return handler.handle(state, next);
|
||||
}
|
||||
export {
|
||||
FetchState,
|
||||
actions,
|
||||
astro,
|
||||
cache,
|
||||
i18n,
|
||||
middleware,
|
||||
pages,
|
||||
redirects,
|
||||
sessions,
|
||||
trailingSlash
|
||||
};
|
||||
6
node_modules/astro/dist/core/fetch/types.d.ts
generated
vendored
Normal file
6
node_modules/astro/dist/core/fetch/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* A framework-agnostic request handler. Takes a standard `Request` and
|
||||
* returns a `Response`. This mirrors the Web Fetch API handler shape, which
|
||||
* lets handlers compose easily with other middleware systems later.
|
||||
*/
|
||||
export type FetchHandler = (request: Request) => Promise<Response>;
|
||||
0
node_modules/astro/dist/core/fetch/types.js
generated
vendored
Normal file
0
node_modules/astro/dist/core/fetch/types.js
generated
vendored
Normal file
5
node_modules/astro/dist/core/fetch/vite-plugin.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/core/fetch/vite-plugin.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import { type Plugin as VitePlugin } from 'vite';
|
||||
import type { AstroSettings } from '../../types/astro.js';
|
||||
export declare function vitePluginFetchable({ settings }: {
|
||||
settings: AstroSettings;
|
||||
}): VitePlugin;
|
||||
69
node_modules/astro/dist/core/fetch/vite-plugin.js
generated
vendored
Normal file
69
node_modules/astro/dist/core/fetch/vite-plugin.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
import { fileURLToPath } from "node:url";
|
||||
import {
|
||||
normalizePath as viteNormalizePath
|
||||
} from "vite";
|
||||
import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../constants.js";
|
||||
const FETCHABLE_MODULE_ID = "virtual:astro:fetchable";
|
||||
const FETCHABLE_RESOLVED_MODULE_ID = "\0" + FETCHABLE_MODULE_ID;
|
||||
const APP_PATH_SEGMENT_NAME = "app";
|
||||
function vitePluginFetchable({ settings }) {
|
||||
let resolvedUserAppId;
|
||||
let userAppPresent = false;
|
||||
const advancedRoutingEnabled = settings.config.experimental.advancedRouting;
|
||||
const normalizedSrcDir = viteNormalizePath(fileURLToPath(settings.config.srcDir));
|
||||
return {
|
||||
name: "@astro/plugin-fetchable",
|
||||
applyToEnvironment(environment) {
|
||||
return environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.ssr || environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.astro || environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.prerender;
|
||||
},
|
||||
configureServer(server) {
|
||||
server.watcher.on("change", (path) => {
|
||||
const normalizedPath = viteNormalizePath(path);
|
||||
if (!normalizedPath.startsWith(normalizedSrcDir)) return;
|
||||
const relativePath = normalizedPath.slice(normalizedSrcDir.length);
|
||||
if (!relativePath.startsWith(`${APP_PATH_SEGMENT_NAME}.`)) return;
|
||||
for (const name of [
|
||||
ASTRO_VITE_ENVIRONMENT_NAMES.ssr,
|
||||
ASTRO_VITE_ENVIRONMENT_NAMES.astro
|
||||
]) {
|
||||
const environment = server.environments[name];
|
||||
if (!environment) continue;
|
||||
const virtualMod = environment.moduleGraph.getModuleById(FETCHABLE_RESOLVED_MODULE_ID);
|
||||
if (virtualMod) {
|
||||
environment.moduleGraph.invalidateModule(virtualMod);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
resolveId: {
|
||||
filter: {
|
||||
id: new RegExp(`^${FETCHABLE_MODULE_ID}$`)
|
||||
},
|
||||
async handler() {
|
||||
const resolved = await this.resolve(`${normalizedSrcDir}${APP_PATH_SEGMENT_NAME}`);
|
||||
userAppPresent = advancedRoutingEnabled && !!resolved;
|
||||
resolvedUserAppId = resolved?.id;
|
||||
return FETCHABLE_RESOLVED_MODULE_ID;
|
||||
}
|
||||
},
|
||||
load: {
|
||||
filter: {
|
||||
id: new RegExp(`^${FETCHABLE_RESOLVED_MODULE_ID}$`)
|
||||
},
|
||||
handler() {
|
||||
if (userAppPresent && resolvedUserAppId) {
|
||||
return {
|
||||
code: `export { default } from '${resolvedUserAppId}';`
|
||||
};
|
||||
}
|
||||
return {
|
||||
code: `import { DefaultFetchHandler } from 'astro/app/fetch/default-handler';
|
||||
export default new DefaultFetchHandler();`
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
vitePluginFetchable
|
||||
};
|
||||
Reference in New Issue
Block a user