astro 6.2.1 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/dist/actions/handler.d.ts +32 -0
  2. package/dist/actions/handler.js +45 -0
  3. package/dist/actions/runtime/server.js +1 -1
  4. package/dist/assets/build/generate.js +1 -1
  5. package/dist/assets/build/remote.d.ts +3 -2
  6. package/dist/assets/build/remote.js +16 -9
  7. package/dist/assets/endpoint/generic.js +4 -7
  8. package/dist/assets/endpoint/shared.js +7 -2
  9. package/dist/assets/index.d.ts +1 -0
  10. package/dist/assets/index.js +2 -0
  11. package/dist/assets/internal.js +16 -1
  12. package/dist/assets/services/sharp.js +16 -1
  13. package/dist/assets/utils/index.d.ts +1 -0
  14. package/dist/assets/utils/index.js +2 -0
  15. package/dist/assets/utils/redirectValidation.d.ts +48 -0
  16. package/dist/assets/utils/redirectValidation.js +48 -0
  17. package/dist/assets/utils/remoteProbe.js +25 -2
  18. package/dist/cli/add/index.js +7 -4
  19. package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
  20. package/dist/container/index.js +18 -14
  21. package/dist/content/content-layer.js +3 -4
  22. package/dist/content/loaders/types.d.ts +1 -1
  23. package/dist/content/server-listeners.js +0 -4
  24. package/dist/content/vite-plugin-content-virtual-mod.js +9 -1
  25. package/dist/core/app/base.d.ts +33 -15
  26. package/dist/core/app/base.js +120 -324
  27. package/dist/core/app/dev/app.d.ts +3 -2
  28. package/dist/core/app/dev/app.js +4 -60
  29. package/dist/core/app/entrypoints/virtual/dev.js +2 -0
  30. package/dist/core/app/entrypoints/virtual/prod.js +4 -1
  31. package/dist/core/app/prepare-response.d.ts +11 -0
  32. package/dist/core/app/prepare-response.js +18 -0
  33. package/dist/core/app/render-options.d.ts +11 -0
  34. package/dist/core/app/render-options.js +11 -0
  35. package/dist/core/base-pipeline.d.ts +38 -1
  36. package/dist/core/base-pipeline.js +50 -7
  37. package/dist/core/build/app.d.ts +3 -4
  38. package/dist/core/build/app.js +3 -17
  39. package/dist/core/build/plugins/plugin-css.js +7 -1
  40. package/dist/core/build/plugins/plugin-manifest.js +11 -1
  41. package/dist/core/build/static-build.js +16 -2
  42. package/dist/core/cache/handler.d.ts +29 -0
  43. package/dist/core/cache/handler.js +81 -0
  44. package/dist/core/compile/style.js +18 -1
  45. package/dist/core/config/index.d.ts +1 -1
  46. package/dist/core/config/index.js +4 -1
  47. package/dist/core/config/schemas/base.d.ts +4 -0
  48. package/dist/core/config/schemas/base.js +4 -0
  49. package/dist/core/config/schemas/relative.d.ts +6 -0
  50. package/dist/core/config/settings.js +2 -4
  51. package/dist/core/config/tsconfig.d.ts +24 -9
  52. package/dist/core/config/tsconfig.js +54 -45
  53. package/dist/core/constants.d.ts +27 -1
  54. package/dist/core/constants.js +14 -1
  55. package/dist/core/cookies/cookies.d.ts +7 -2
  56. package/dist/core/cookies/cookies.js +11 -4
  57. package/dist/core/cookies/response.d.ts +1 -1
  58. package/dist/core/cookies/response.js +1 -2
  59. package/dist/core/create-vite.js +15 -0
  60. package/dist/core/csp/runtime.js +6 -4
  61. package/dist/core/dev/dev.js +1 -1
  62. package/dist/core/errors/build-handler.d.ts +17 -0
  63. package/dist/core/errors/build-handler.js +22 -0
  64. package/dist/core/errors/default-handler.d.ts +14 -0
  65. package/dist/core/errors/default-handler.js +144 -0
  66. package/dist/core/errors/dev-handler.d.ts +21 -0
  67. package/dist/core/errors/dev-handler.js +82 -0
  68. package/dist/core/errors/handler.d.ts +9 -0
  69. package/dist/core/errors/handler.js +0 -0
  70. package/dist/core/fetch/default-handler.d.ts +17 -0
  71. package/dist/core/fetch/default-handler.js +45 -0
  72. package/dist/core/fetch/fetch-state.d.ts +244 -0
  73. package/dist/core/fetch/fetch-state.js +779 -0
  74. package/dist/core/fetch/index.d.ts +61 -0
  75. package/dist/core/fetch/index.js +121 -0
  76. package/dist/core/fetch/types.d.ts +6 -0
  77. package/dist/core/fetch/types.js +0 -0
  78. package/dist/core/fetch/vite-plugin.d.ts +5 -0
  79. package/dist/core/fetch/vite-plugin.js +69 -0
  80. package/dist/core/hono/index.d.ts +21 -0
  81. package/dist/core/hono/index.js +98 -0
  82. package/dist/core/i18n/handler.d.ts +18 -0
  83. package/dist/core/i18n/handler.js +119 -0
  84. package/dist/core/logger/core.d.ts +8 -0
  85. package/dist/core/logger/core.js +16 -0
  86. package/dist/core/messages/runtime.js +1 -1
  87. package/dist/core/middleware/astro-middleware.d.ts +27 -0
  88. package/dist/core/middleware/astro-middleware.js +53 -0
  89. package/dist/core/pages/handler.d.ts +20 -0
  90. package/dist/core/pages/handler.js +74 -0
  91. package/dist/core/redirects/render.d.ts +2 -2
  92. package/dist/core/redirects/render.js +7 -8
  93. package/dist/core/render/params-and-props.js +1 -1
  94. package/dist/core/render/slots.js +9 -2
  95. package/dist/core/rewrites/handler.d.ts +37 -0
  96. package/dist/core/rewrites/handler.js +67 -0
  97. package/dist/core/routing/3xx.js +8 -4
  98. package/dist/core/routing/handler.d.ts +17 -0
  99. package/dist/core/routing/handler.js +172 -0
  100. package/dist/core/routing/match.d.ts +0 -7
  101. package/dist/core/routing/match.js +0 -5
  102. package/dist/core/routing/pattern.js +1 -1
  103. package/dist/core/routing/rewrite.js +1 -4
  104. package/dist/core/routing/trailing-slash-handler.d.ts +18 -0
  105. package/dist/core/routing/trailing-slash-handler.js +67 -0
  106. package/dist/core/session/drivers.d.ts +1 -1
  107. package/dist/core/session/handler.d.ts +11 -0
  108. package/dist/core/session/handler.js +33 -0
  109. package/dist/core/session/runtime.js +7 -2
  110. package/dist/core/util/normalized-url.d.ts +10 -0
  111. package/dist/core/util/normalized-url.js +21 -0
  112. package/dist/i18n/middleware.d.ts +10 -0
  113. package/dist/i18n/middleware.js +4 -88
  114. package/dist/i18n/utils.js +2 -2
  115. package/dist/prefetch/index.js +12 -7
  116. package/dist/runtime/server/astro-island.js +57 -20
  117. package/dist/runtime/server/astro-island.prebuilt-dev.d.ts +1 -1
  118. package/dist/runtime/server/astro-island.prebuilt-dev.js +1 -1
  119. package/dist/runtime/server/astro-island.prebuilt.d.ts +1 -1
  120. package/dist/runtime/server/astro-island.prebuilt.js +1 -1
  121. package/dist/runtime/server/render/common.js +10 -4
  122. package/dist/runtime/server/render/server-islands.js +2 -1
  123. package/dist/runtime/server/scripts.js +6 -0
  124. package/dist/types/public/config.d.ts +46 -12
  125. package/dist/types/public/content.d.ts +4 -4
  126. package/dist/types/public/internal.d.ts +1 -1
  127. package/dist/vite-plugin-app/app.d.ts +4 -5
  128. package/dist/vite-plugin-app/app.js +20 -68
  129. package/dist/vite-plugin-astro/compile.js +2 -2
  130. package/dist/vite-plugin-astro/utils.d.ts +1 -0
  131. package/dist/vite-plugin-astro/utils.js +9 -1
  132. package/dist/vite-plugin-head/index.js +36 -19
  133. package/dist/vite-plugin-utils/index.d.ts +1 -0
  134. package/dist/vite-plugin-utils/index.js +3 -0
  135. package/package.json +13 -6
  136. package/dist/core/render-context.d.ts +0 -77
  137. package/dist/core/render-context.js +0 -826
@@ -0,0 +1,144 @@
1
+ import { FetchState } from "../fetch/fetch-state.js";
2
+ import { prepareResponse } from "../app/prepare-response.js";
3
+ import { attachCookiesToResponse } from "../cookies/index.js";
4
+ import { getCookiesFromResponse } from "../cookies/response.js";
5
+ import { AstroMiddleware } from "../middleware/astro-middleware.js";
6
+ import { PagesHandler } from "../pages/handler.js";
7
+ import { matchRoute } from "../routing/match.js";
8
+ import { provideSession } from "../session/handler.js";
9
+ class DefaultErrorHandler {
10
+ #app;
11
+ #astroMiddleware;
12
+ #pagesHandler;
13
+ constructor(app) {
14
+ this.#app = app;
15
+ this.#astroMiddleware = new AstroMiddleware(app.pipeline);
16
+ this.#pagesHandler = new PagesHandler(app.pipeline);
17
+ }
18
+ async renderError(request, {
19
+ status,
20
+ response: originalResponse,
21
+ skipMiddleware = false,
22
+ error,
23
+ pathname,
24
+ ...resolvedRenderOptions
25
+ }) {
26
+ const app = this.#app;
27
+ const resolvedPathname = pathname ?? new FetchState(app.pipeline, request).pathname;
28
+ const errorRoutePath = `/${status}${app.manifest.trailingSlash === "always" ? "/" : ""}`;
29
+ const errorRouteData = matchRoute(errorRoutePath, app.manifestData);
30
+ const url = new URL(request.url);
31
+ if (errorRouteData) {
32
+ if (errorRouteData.prerender) {
33
+ const maybeDotHtml = errorRouteData.route.endsWith(`/${status}`) ? ".html" : "";
34
+ const statusURL = new URL(`${app.baseWithoutTrailingSlash}/${status}${maybeDotHtml}`, url);
35
+ if (statusURL.toString() !== request.url && resolvedRenderOptions.prerenderedErrorPageFetch) {
36
+ const response2 = await resolvedRenderOptions.prerenderedErrorPageFetch(
37
+ statusURL.toString()
38
+ );
39
+ const override = { status, removeContentEncodingHeaders: true };
40
+ const newResponse = mergeResponses(response2, originalResponse, override);
41
+ prepareResponse(newResponse, resolvedRenderOptions);
42
+ return newResponse;
43
+ }
44
+ }
45
+ const mod = await app.pipeline.getComponentByRoute(errorRouteData);
46
+ const errorState = new FetchState(app.pipeline, request);
47
+ errorState.skipMiddleware = skipMiddleware;
48
+ errorState.clientAddress = resolvedRenderOptions.clientAddress;
49
+ errorState.routeData = errorRouteData;
50
+ errorState.pathname = resolvedPathname;
51
+ errorState.status = status;
52
+ errorState.componentInstance = mod;
53
+ errorState.locals = resolvedRenderOptions.locals ?? {};
54
+ errorState.initialProps = { error };
55
+ try {
56
+ await provideSession(errorState);
57
+ const response2 = await this.#astroMiddleware.handle(
58
+ errorState,
59
+ this.#pagesHandler.handle.bind(this.#pagesHandler)
60
+ );
61
+ const newResponse = mergeResponses(response2, originalResponse);
62
+ prepareResponse(newResponse, resolvedRenderOptions);
63
+ return newResponse;
64
+ } catch {
65
+ if (skipMiddleware === false) {
66
+ return this.renderError(request, {
67
+ ...resolvedRenderOptions,
68
+ status,
69
+ response: originalResponse,
70
+ skipMiddleware: true,
71
+ pathname: resolvedPathname
72
+ });
73
+ }
74
+ } finally {
75
+ await errorState.finalizeAll();
76
+ }
77
+ }
78
+ const response = mergeResponses(new Response(null, { status }), originalResponse);
79
+ prepareResponse(response, resolvedRenderOptions);
80
+ return response;
81
+ }
82
+ }
83
+ function mergeResponses(newResponse, originalResponse, override) {
84
+ let newResponseHeaders = newResponse.headers;
85
+ if (override?.removeContentEncodingHeaders) {
86
+ newResponseHeaders = new Headers(newResponseHeaders);
87
+ newResponseHeaders.delete("Content-Encoding");
88
+ newResponseHeaders.delete("Content-Length");
89
+ }
90
+ if (!originalResponse) {
91
+ if (override !== void 0) {
92
+ return new Response(newResponse.body, {
93
+ status: override.status,
94
+ statusText: newResponse.statusText,
95
+ headers: newResponseHeaders
96
+ });
97
+ }
98
+ return newResponse;
99
+ }
100
+ const status = override?.status ? override.status : originalResponse.status === 200 ? newResponse.status : originalResponse.status;
101
+ try {
102
+ originalResponse.headers.delete("Content-type");
103
+ originalResponse.headers.delete("Content-Length");
104
+ originalResponse.headers.delete("Transfer-Encoding");
105
+ } catch {
106
+ }
107
+ const newHeaders = new Headers();
108
+ const seen = /* @__PURE__ */ new Set();
109
+ for (const [name, value] of originalResponse.headers) {
110
+ newHeaders.append(name, value);
111
+ seen.add(name.toLowerCase());
112
+ }
113
+ for (const [name, value] of newResponseHeaders) {
114
+ if (!seen.has(name.toLowerCase())) {
115
+ newHeaders.append(name, value);
116
+ }
117
+ }
118
+ const mergedResponse = new Response(newResponse.body, {
119
+ status,
120
+ statusText: status === 200 ? newResponse.statusText : originalResponse.statusText,
121
+ // If you're looking at here for possible bugs, it means that it's not a bug.
122
+ // With the middleware, users can meddle with headers, and we should pass to the 404/500.
123
+ // If users see something weird, it's because they are setting some headers they should not.
124
+ //
125
+ // Although, we don't want it to replace the content-type, because the error page must return `text/html`
126
+ headers: newHeaders
127
+ });
128
+ const originalCookies = getCookiesFromResponse(originalResponse);
129
+ const newCookies = getCookiesFromResponse(newResponse);
130
+ if (originalCookies) {
131
+ if (newCookies) {
132
+ for (const cookieValue of newCookies.consume()) {
133
+ originalResponse.headers.append("set-cookie", cookieValue);
134
+ }
135
+ }
136
+ attachCookiesToResponse(mergedResponse, originalCookies);
137
+ } else if (newCookies) {
138
+ attachCookiesToResponse(mergedResponse, newCookies);
139
+ }
140
+ return mergedResponse;
141
+ }
142
+ export {
143
+ DefaultErrorHandler
144
+ };
@@ -0,0 +1,21 @@
1
+ import type { BaseApp, RenderErrorOptions } from '../app/base.js';
2
+ import type { Pipeline } from '../base-pipeline.js';
3
+ import type { ErrorHandler } from './handler.js';
4
+ export interface DevErrorHandlerOptions {
5
+ /**
6
+ * Whether to inject CSP meta tags into the rendered error page response.
7
+ * The Vite dev server injects them; the non-runnable dev pipeline does not.
8
+ */
9
+ shouldInjectCspMetaTags: boolean;
10
+ }
11
+ /**
12
+ * The dev-server error handler. Renders custom 404/500 routes if the user
13
+ * has them, otherwise throws so Vite's dev overlay is shown. Shared between
14
+ * the Vite dev server (`AstroServerApp`) and the non-runnable dev pipeline
15
+ * (`DevApp`); only `shouldInjectCspMetaTags` differs between them.
16
+ */
17
+ export declare class DevErrorHandler implements ErrorHandler {
18
+ #private;
19
+ constructor(app: BaseApp<Pipeline>, options: DevErrorHandlerOptions);
20
+ renderError(request: Request, { skipMiddleware, error, status, response: _response, pathname, ...resolvedRenderOptions }: RenderErrorOptions): Promise<Response>;
21
+ }
@@ -0,0 +1,82 @@
1
+ import { FetchState } from "../fetch/fetch-state.js";
2
+ import { AstroMiddleware } from "../middleware/astro-middleware.js";
3
+ import { PagesHandler } from "../pages/handler.js";
4
+ import { getCustom404Route, getCustom500Route } from "../routing/helpers.js";
5
+ import { isAstroError } from "./index.js";
6
+ import { MiddlewareNoDataOrNextCalled, MiddlewareNotAResponse } from "./errors-data.js";
7
+ class DevErrorHandler {
8
+ #app;
9
+ #shouldInjectCspMetaTags;
10
+ #astroMiddleware;
11
+ #pagesHandler;
12
+ constructor(app, options) {
13
+ this.#app = app;
14
+ this.#shouldInjectCspMetaTags = options.shouldInjectCspMetaTags;
15
+ this.#astroMiddleware = new AstroMiddleware(app.pipeline);
16
+ this.#pagesHandler = new PagesHandler(app.pipeline);
17
+ }
18
+ async renderError(request, {
19
+ skipMiddleware = false,
20
+ error,
21
+ status,
22
+ response: _response,
23
+ pathname,
24
+ ...resolvedRenderOptions
25
+ }) {
26
+ if (isAstroError(error) && [MiddlewareNoDataOrNextCalled.name, MiddlewareNotAResponse.name].includes(error.name)) {
27
+ throw error;
28
+ }
29
+ const app = this.#app;
30
+ const shouldInjectCspMetaTags = this.#shouldInjectCspMetaTags;
31
+ const resolvedPathname = pathname ?? new FetchState(app.pipeline, request).pathname;
32
+ const renderRoute = async (routeData) => {
33
+ try {
34
+ const preloadedComponent = await app.pipeline.getComponentByRoute(routeData);
35
+ const errorState = new FetchState(app.pipeline, request);
36
+ errorState.skipMiddleware = skipMiddleware;
37
+ errorState.clientAddress = resolvedRenderOptions.clientAddress;
38
+ errorState.shouldInjectCspMetaTags = shouldInjectCspMetaTags ? !!app.manifest.csp : false;
39
+ errorState.routeData = routeData;
40
+ errorState.pathname = resolvedPathname;
41
+ errorState.status = status;
42
+ errorState.componentInstance = preloadedComponent;
43
+ errorState.locals = resolvedRenderOptions.locals ?? {};
44
+ errorState.initialProps = { error };
45
+ const response = await this.#astroMiddleware.handle(
46
+ errorState,
47
+ this.#pagesHandler.handle.bind(this.#pagesHandler)
48
+ );
49
+ if (error) {
50
+ app.logger.error("router", error.stack || error.message);
51
+ }
52
+ return response;
53
+ } catch (_err) {
54
+ if (skipMiddleware === false) {
55
+ return this.renderError(request, {
56
+ ...resolvedRenderOptions,
57
+ status: 500,
58
+ skipMiddleware: true,
59
+ error: _err,
60
+ pathname: resolvedPathname
61
+ });
62
+ }
63
+ throw _err;
64
+ }
65
+ };
66
+ if (status === 404) {
67
+ const custom404 = getCustom404Route(app.manifestData);
68
+ if (custom404) {
69
+ return renderRoute(custom404);
70
+ }
71
+ }
72
+ const custom500 = getCustom500Route(app.manifestData);
73
+ if (!custom500) {
74
+ throw error;
75
+ } else {
76
+ return renderRoute(custom500);
77
+ }
78
+ }
79
+ }
80
+ export {
81
+ DevErrorHandler
82
+ };
@@ -0,0 +1,9 @@
1
+ import type { RenderErrorOptions } from '../app/base.js';
2
+ /**
3
+ * A strategy for rendering error responses (404, 500, etc.). Each execution
4
+ * environment (prod SSR, build/prerender, dev server) supplies its own
5
+ * implementation rather than overriding a method on the app.
6
+ */
7
+ export interface ErrorHandler {
8
+ renderError(request: Request, options: RenderErrorOptions): Promise<Response>;
9
+ }
File without changes
@@ -0,0 +1,17 @@
1
+ import type { BaseApp, ResolvedRenderOptions } from '../app/base.js';
2
+ import type { Pipeline } from '../base-pipeline.js';
3
+ import type { FetchHandler } from './types.js';
4
+ /**
5
+ * The default request handler for `BaseApp`. Builds the per-request
6
+ * `FetchState` and delegates to an `AstroHandler`.
7
+ */
8
+ export declare class DefaultFetchHandler {
9
+ #private;
10
+ constructor(app?: BaseApp<Pipeline>);
11
+ /**
12
+ * Fast path: called directly by `BaseApp.render()` with pre-resolved
13
+ * options, avoiding the `Reflect.set/get` round-trip through the request.
14
+ */
15
+ renderWithOptions(request: Request, options: ResolvedRenderOptions): Promise<Response>;
16
+ fetch: FetchHandler;
17
+ }
@@ -0,0 +1,45 @@
1
+ import { FetchState } from "./fetch-state.js";
2
+ import { appSymbol } from "../constants.js";
3
+ import { AstroHandler } from "../routing/handler.js";
4
+ class DefaultFetchHandler {
5
+ #app;
6
+ #handler;
7
+ constructor(app) {
8
+ this.#app = app ?? null;
9
+ this.#handler = app ? new AstroHandler(app) : null;
10
+ }
11
+ /**
12
+ * Fast path: called directly by `BaseApp.render()` with pre-resolved
13
+ * options, avoiding the `Reflect.set/get` round-trip through the request.
14
+ */
15
+ renderWithOptions(request, options) {
16
+ if (!this.#app) {
17
+ const app = Reflect.get(request, appSymbol);
18
+ if (!app) {
19
+ throw new Error("No fetch handler provided.");
20
+ }
21
+ this.#app = app;
22
+ this.#handler = new AstroHandler(app);
23
+ }
24
+ const state = new FetchState(this.#app.pipeline, request, options);
25
+ return this.#handler.handle(state);
26
+ }
27
+ fetch = (request) => {
28
+ if (!this.#app) {
29
+ const app = Reflect.get(request, appSymbol);
30
+ if (!app) {
31
+ throw new Error("No fetch handler provided.");
32
+ }
33
+ this.#app = app;
34
+ this.#handler = new AstroHandler(app);
35
+ }
36
+ const state = new FetchState(this.#app.pipeline, request);
37
+ if (!this.#handler) {
38
+ throw new Error("No fetch handler provided.");
39
+ }
40
+ return this.#handler.handle(state);
41
+ };
42
+ }
43
+ export {
44
+ DefaultFetchHandler
45
+ };
@@ -0,0 +1,244 @@
1
+ import type { ActionAPIContext } from '../../actions/runtime/types.js';
2
+ import type { ComponentInstance } from '../../types/astro.js';
3
+ import type { Params, Props, RewritePayload } from '../../types/public/common.js';
4
+ import type { APIContext, AstroGlobal } from '../../types/public/context.js';
5
+ import type { RouteData, SSRResult } from '../../types/public/internal.js';
6
+ import { AstroCookies } from '../cookies/index.js';
7
+ import { type Pipeline } from '../render/index.js';
8
+ import type { ResolvedRenderOptions } from '../app/base.js';
9
+ /**
10
+ * Describes a lazily-created value that handlers can contribute to the
11
+ * request context. `create` is called at most once (on first `resolve`);
12
+ * `finalize` runs during `finalizeAll` to clean up / persist.
13
+ */
14
+ export interface ContextProvider<T> {
15
+ /** Factory called lazily on the first `resolve(key)`. */
16
+ create: () => T;
17
+ /** Optional cleanup / persist callback. Receives the created value. */
18
+ finalize?: (value: T) => Promise<void> | void;
19
+ }
20
+ /**
21
+ * The public contract of {@link FetchState} exposed to user-land code
22
+ * (custom fetch handlers, Hono middleware, etc.).
23
+ *
24
+ * Only the members listed here are part of the stable public API.
25
+ * Everything else on the concrete `FetchState` class is internal and
26
+ * may change without notice.
27
+ *
28
+ * If you add a new member to `FetchState` that should be user-visible,
29
+ * add it here first — the `implements` clause on the class ensures a
30
+ * compile-time error if the class falls out of sync.
31
+ */
32
+ export interface AstroFetchState {
33
+ /** The incoming request. */
34
+ readonly request: Request;
35
+ /** Normalized URL derived from the request. */
36
+ readonly url: URL;
37
+ /** Base-stripped, decoded pathname of the request. */
38
+ readonly pathname: string;
39
+ /** The matched route for this request, if any. */
40
+ readonly routeData: RouteData | undefined;
41
+ /** Cookies for this request. */
42
+ readonly cookies: AstroCookies;
43
+ /** Request-scoped locals object, shared with user middleware. */
44
+ readonly locals: App.Locals;
45
+ /** Route params derived from routeData + pathname. */
46
+ readonly params: Params | undefined;
47
+ /** Default HTTP status for the rendered response. */
48
+ status: number;
49
+ /**
50
+ * Triggers a rewrite to a different route.
51
+ *
52
+ * [Astro reference](https://docs.astro.build/en/guides/routing/#rewrites)
53
+ */
54
+ rewrite(payload: RewritePayload): Promise<Response>;
55
+ /**
56
+ * Registers a context provider under the given key. The `create`
57
+ * factory is called lazily on the first `resolve(key)`.
58
+ */
59
+ provide<T>(key: string, provider: ContextProvider<T>): void;
60
+ /**
61
+ * Lazily resolves a provider registered under `key`. Returns
62
+ * `undefined` if no provider was registered for the key.
63
+ */
64
+ resolve<T>(key: string): T | undefined;
65
+ /**
66
+ * Runs all registered provider `finalize` callbacks. Call this after
67
+ * the response is produced, typically in a `finally` block.
68
+ */
69
+ finalizeAll(): Promise<void> | void;
70
+ }
71
+ /**
72
+ * Retrieves the `FetchState` stashed on an `APIContext` by
73
+ * `FetchState.getAPIContext()`. Throws if not found — this indicates
74
+ * the context was not created through Astro's request pipeline.
75
+ */
76
+ export declare function getFetchStateFromAPIContext(context: APIContext): FetchState;
77
+ /**
78
+ * Holds per-request state as it flows through the handler pipeline.
79
+ *
80
+ * **This class is user-facing** via `astro/fetch` and `astro/hono`.
81
+ * The {@link AstroFetchState} interface defines the stable public
82
+ * surface. Members not on that interface are internal and
83
+ * may change without notice.
84
+ *
85
+ * Performance note: fields on this class are plain properties — ES
86
+ * private fields (`#foo`) have a non-zero per-access cost in V8
87
+ * which is measurable on the hot render path, so `#` is used only
88
+ * for rarely-accessed memoized caches and Maps.
89
+ */
90
+ export declare class FetchState implements AstroFetchState {
91
+ #private;
92
+ pipeline: Pipeline;
93
+ /**
94
+ * The request to render. Mutated during rewrites so subsequent renders
95
+ * see the rewritten URL.
96
+ */
97
+ request: Request;
98
+ routeData: RouteData | undefined;
99
+ /**
100
+ * The pathname to use for routing and rendering. Starts out as the raw,
101
+ * base-stripped, decoded pathname from the request. May be further
102
+ * normalized by `AstroHandler` after routeData is known (in dev, when
103
+ * the matched route has no `.html` extension, `.html` / `/index.html`
104
+ * suffixes are stripped).
105
+ */
106
+ pathname: string;
107
+ /** Resolved render options (addCookieHeader, clientAddress, locals, etc.). */
108
+ readonly renderOptions: ResolvedRenderOptions;
109
+ /** When the request started, used to log duration. */
110
+ readonly timeStart: number;
111
+ /**
112
+ * The route's loaded component module. Set before middleware runs; may
113
+ * be swapped during in-flight rewrites from inside the middleware chain.
114
+ */
115
+ componentInstance: ComponentInstance | undefined;
116
+ /**
117
+ * Slot overrides supplied by the container API. `undefined` for HTTP
118
+ * requests — `PagesHandler` coalesces to `{}` on read so we don't
119
+ * allocate an empty object per request.
120
+ */
121
+ slots: Record<string, any> | undefined;
122
+ /**
123
+ * Default HTTP status for the rendered response. Callers override
124
+ * before rendering runs (e.g. `AstroHandler` sets this from
125
+ * `BaseApp.getDefaultStatusCode`; error handlers set `404` / `500`).
126
+ */
127
+ status: number;
128
+ /** Whether user middleware should be skipped for this request. */
129
+ skipMiddleware: boolean;
130
+ /** A flag that tells the render content if the rewriting was triggered. */
131
+ isRewriting: boolean;
132
+ /** A safety net in case of loops (rewrite counter). */
133
+ counter: number;
134
+ /** Cookies for this request. Created lazily on first access. */
135
+ cookies: AstroCookies;
136
+ get params(): Params | undefined;
137
+ set params(value: Params | undefined);
138
+ /** Normalized URL for this request. */
139
+ url: URL;
140
+ /** Client address for this request. */
141
+ clientAddress: string | undefined;
142
+ /** Whether this is a partial render (container API). */
143
+ partial: boolean | undefined;
144
+ /** Whether to inject CSP meta tags. */
145
+ shouldInjectCspMetaTags: boolean | undefined;
146
+ /** Request-scoped locals object, shared with user middleware. */
147
+ locals: App.Locals;
148
+ /**
149
+ * Memoized `props` (see `getProps`). `null` means "not yet computed"
150
+ * — using `null` (rather than `undefined`) keeps the hidden class
151
+ * stable and distinct from a valid-but-empty result.
152
+ */
153
+ props: APIContext['props'] | null;
154
+ /** Memoized `ActionAPIContext` (see `getActionAPIContext`). */
155
+ actionApiContext: ActionAPIContext | null;
156
+ /** Memoized `APIContext` (see `getAPIContext`). */
157
+ apiContext: APIContext | null;
158
+ /** SSR result for the current page render. */
159
+ result: SSRResult | undefined;
160
+ /** Initial props (from container/error handler). */
161
+ initialProps: Props;
162
+ constructor(pipeline: Pipeline, request: Request, options?: ResolvedRenderOptions);
163
+ /**
164
+ * Triggers a rewrite. Delegates to the Rewrites handler.
165
+ */
166
+ rewrite(payload: RewritePayload): Promise<Response>;
167
+ /**
168
+ * Creates the SSR result for the current page render.
169
+ */
170
+ createResult(mod: ComponentInstance, ctx: ActionAPIContext): Promise<SSRResult>;
171
+ /**
172
+ * Creates the Astro global object for a component render.
173
+ */
174
+ createAstro(result: SSRResult, props: Record<string, any>, slotValues: Record<string, any> | null, apiContext: ActionAPIContext): AstroGlobal;
175
+ /**
176
+ * Creates the Astro page-level partial (prototype for Astro global).
177
+ */
178
+ createAstroPagePartial(result: SSRResult, apiContext: ActionAPIContext): Omit<AstroGlobal, 'props' | 'self' | 'slots'>;
179
+ getClientAddress(): string;
180
+ getCookies(): AstroCookies;
181
+ getCsp(): APIContext['csp'];
182
+ computeCurrentLocale(): string | undefined;
183
+ computePreferredLocale(): string | undefined;
184
+ computePreferredLocaleList(): string[] | undefined;
185
+ /**
186
+ * Lazily loads the route's component module. Returns the cached
187
+ * instance if already loaded. The promise is cached so concurrent
188
+ * callers share the same load.
189
+ */
190
+ loadComponentInstance(): Promise<ComponentInstance>;
191
+ /**
192
+ * Registers a context provider under the given key. Handlers call
193
+ * this to contribute values to the request context (e.g. sessions).
194
+ * The `create` factory is called lazily on the first `resolve(key)`.
195
+ */
196
+ provide<T>(key: string, provider: ContextProvider<T>): void;
197
+ /**
198
+ * Lazily resolves a provider registered under `key`. Calls
199
+ * `provider.create()` on first access and caches the result.
200
+ * Returns `undefined` if no provider was registered for the key.
201
+ */
202
+ resolve<T>(key: string): T | undefined;
203
+ /**
204
+ * Runs all registered `finalize` callbacks. Should be called after
205
+ * the response is produced, typically in a `finally` block.
206
+ *
207
+ * Returns synchronously (no promise allocation) when nothing needs
208
+ * finalizing — important for the hot path where sessions are not used.
209
+ */
210
+ finalizeAll(): Promise<void> | void;
211
+ /**
212
+ * Adds lazy getters to `target` for each registered provider key.
213
+ * Used by context creation (APIContext, Astro global) so that
214
+ * provider values like `session` and `cache` appear as properties
215
+ * without hard-coding the keys.
216
+ */
217
+ defineProviderGetters(target: Record<string, any>): void;
218
+ /**
219
+ * Returns the resolved `props` for this render, computing them lazily
220
+ * from the route + component module on first access. If the
221
+ * `initialProps` already carries user-supplied props (e.g. the
222
+ * container API) those are used verbatim.
223
+ */
224
+ getProps(): Promise<APIContext['props']>;
225
+ /**
226
+ * Returns the `ActionAPIContext` for this render, creating it lazily.
227
+ * Used by middleware, actions, and page dispatch.
228
+ */
229
+ getActionAPIContext(): ActionAPIContext;
230
+ /**
231
+ * Returns the `APIContext` for this render, creating it lazily from
232
+ * the memoized props + action context.
233
+ *
234
+ * Callers must ensure `getProps()` has resolved at least once before
235
+ * calling this.
236
+ */
237
+ getAPIContext(): APIContext;
238
+ /**
239
+ * Invalidates the cached `APIContext` so the next `getAPIContext()`
240
+ * call re-derives it from the (possibly mutated) state. Used
241
+ * after an in-flight rewrite swaps the route / request / params.
242
+ */
243
+ invalidateContexts(): void;
244
+ }