astro 7.0.0-alpha.0 → 7.0.0-alpha.2

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 (251) hide show
  1. package/components/Code.astro +1 -1
  2. package/dist/actions/handler.d.ts +32 -0
  3. package/dist/actions/handler.js +45 -0
  4. package/dist/actions/runtime/server.js +1 -1
  5. package/dist/assets/build/generate.js +1 -1
  6. package/dist/assets/build/remote.d.ts +3 -2
  7. package/dist/assets/build/remote.js +16 -9
  8. package/dist/assets/endpoint/dev.js +1 -1
  9. package/dist/assets/endpoint/generic.js +8 -20
  10. package/dist/assets/endpoint/loadImage.d.ts +11 -0
  11. package/dist/assets/endpoint/loadImage.js +19 -0
  12. package/dist/assets/endpoint/shared.js +7 -2
  13. package/dist/assets/fonts/config.d.ts +4 -4
  14. package/dist/assets/fonts/core/optimize-fallbacks.js +38 -13
  15. package/dist/assets/fonts/definitions.d.ts +2 -2
  16. package/dist/assets/fonts/infra/system-fallbacks-provider.d.ts +2 -2
  17. package/dist/assets/fonts/infra/system-fallbacks-provider.js +46 -9
  18. package/dist/assets/fonts/types.d.ts +1 -0
  19. package/dist/assets/index.d.ts +1 -0
  20. package/dist/assets/index.js +2 -0
  21. package/dist/assets/internal.js +22 -3
  22. package/dist/assets/services/service.d.ts +1 -1
  23. package/dist/assets/services/service.js +9 -9
  24. package/dist/assets/services/sharp.js +53 -18
  25. package/dist/assets/utils/generateImageStylesCSS.js +26 -6
  26. package/dist/assets/utils/index.d.ts +1 -0
  27. package/dist/assets/utils/index.js +2 -0
  28. package/dist/assets/utils/inferSourceFormat.d.ts +8 -3
  29. package/dist/assets/utils/inferSourceFormat.js +15 -4
  30. package/dist/assets/utils/metadata.js +1 -1
  31. package/dist/assets/utils/redirectValidation.d.ts +48 -0
  32. package/dist/assets/utils/redirectValidation.js +48 -0
  33. package/dist/assets/utils/remoteProbe.js +25 -2
  34. package/dist/assets/utils/vendor/image-size/types/svg.js +1 -1
  35. package/dist/cli/add/index.js +7 -58
  36. package/dist/cli/dev/background.d.ts +16 -0
  37. package/dist/cli/dev/background.js +116 -0
  38. package/dist/cli/dev/index.js +82 -3
  39. package/dist/cli/dev/logs.d.ts +6 -0
  40. package/dist/cli/dev/logs.js +72 -0
  41. package/dist/cli/dev/status.d.ts +15 -0
  42. package/dist/cli/dev/status.js +27 -0
  43. package/dist/cli/dev/stop.d.ts +12 -0
  44. package/dist/cli/dev/stop.js +43 -0
  45. package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
  46. package/dist/container/index.js +18 -14
  47. package/dist/content/content-layer.js +16 -11
  48. package/dist/content/data-store.d.ts +1 -1
  49. package/dist/content/loaders/types.d.ts +1 -1
  50. package/dist/content/runtime-assets.d.ts +2 -2
  51. package/dist/content/runtime.d.ts +1 -1
  52. package/dist/content/runtime.js +9 -4
  53. package/dist/content/server-listeners.js +0 -4
  54. package/dist/content/types-generator.js +5 -1
  55. package/dist/content/utils.d.ts +1 -1
  56. package/dist/content/utils.js +1 -1
  57. package/dist/content/vite-plugin-content-assets.js +1 -0
  58. package/dist/content/vite-plugin-content-virtual-mod.js +9 -1
  59. package/dist/core/app/base.d.ts +42 -15
  60. package/dist/core/app/base.js +151 -375
  61. package/dist/core/app/dev/app.d.ts +3 -2
  62. package/dist/core/app/dev/app.js +4 -60
  63. package/dist/core/app/entrypoints/node.d.ts +1 -1
  64. package/dist/core/app/entrypoints/node.js +2 -0
  65. package/dist/core/app/entrypoints/virtual/dev.js +2 -0
  66. package/dist/core/app/entrypoints/virtual/prod.js +4 -1
  67. package/dist/core/app/node.d.ts +16 -0
  68. package/dist/core/app/node.js +59 -13
  69. package/dist/core/app/prepare-response.d.ts +11 -0
  70. package/dist/core/app/prepare-response.js +18 -0
  71. package/dist/core/app/render-options.d.ts +11 -0
  72. package/dist/core/app/render-options.js +11 -0
  73. package/dist/core/base-pipeline.d.ts +48 -1
  74. package/dist/core/base-pipeline.js +63 -8
  75. package/dist/core/build/app.d.ts +3 -4
  76. package/dist/core/build/app.js +3 -17
  77. package/dist/core/build/generate.js +8 -1
  78. package/dist/core/build/index.d.ts +0 -11
  79. package/dist/core/build/index.js +0 -3
  80. package/dist/core/build/internal.d.ts +7 -0
  81. package/dist/core/build/plugins/plugin-chunk-imports.d.ts +6 -0
  82. package/dist/core/build/plugins/plugin-chunk-imports.js +29 -17
  83. package/dist/core/build/plugins/plugin-css.js +40 -1
  84. package/dist/core/build/plugins/plugin-internals.js +1 -1
  85. package/dist/core/build/plugins/plugin-manifest.js +11 -1
  86. package/dist/core/build/static-build.js +22 -141
  87. package/dist/core/build/types.d.ts +0 -1
  88. package/dist/core/build/util.js +8 -1
  89. package/dist/core/build/vite-build-config.d.ts +28 -0
  90. package/dist/core/build/vite-build-config.js +165 -0
  91. package/dist/core/cache/handler.d.ts +29 -0
  92. package/dist/core/cache/handler.js +81 -0
  93. package/dist/core/compile/style.js +18 -1
  94. package/dist/core/config/index.d.ts +1 -1
  95. package/dist/core/config/index.js +4 -1
  96. package/dist/core/config/merge.js +4 -0
  97. package/dist/core/config/schemas/base.d.ts +25 -13
  98. package/dist/core/config/schemas/base.js +39 -10
  99. package/dist/core/config/schemas/relative.d.ts +76 -49
  100. package/dist/core/config/schemas/relative.js +2 -3
  101. package/dist/core/config/settings.js +2 -4
  102. package/dist/core/config/tsconfig.d.ts +24 -9
  103. package/dist/core/config/tsconfig.js +54 -45
  104. package/dist/core/config/validate.js +59 -0
  105. package/dist/core/constants.d.ts +27 -1
  106. package/dist/core/constants.js +14 -1
  107. package/dist/core/cookies/cookies.d.ts +7 -2
  108. package/dist/core/cookies/cookies.js +11 -4
  109. package/dist/core/cookies/response.d.ts +1 -1
  110. package/dist/core/cookies/response.js +1 -2
  111. package/dist/core/create-vite.js +18 -1
  112. package/dist/core/csp/config.js +17 -5
  113. package/dist/core/csp/runtime.js +6 -4
  114. package/dist/core/dev/dev.d.ts +1 -0
  115. package/dist/core/dev/dev.js +4 -13
  116. package/dist/core/dev/lockfile.d.ts +54 -0
  117. package/dist/core/dev/lockfile.js +93 -0
  118. package/dist/core/errors/build-handler.d.ts +17 -0
  119. package/dist/core/errors/build-handler.js +22 -0
  120. package/dist/core/errors/default-handler.d.ts +14 -0
  121. package/dist/core/errors/default-handler.js +144 -0
  122. package/dist/core/errors/dev-handler.d.ts +21 -0
  123. package/dist/core/errors/dev-handler.js +82 -0
  124. package/dist/core/errors/errors-data.d.ts +43 -38
  125. package/dist/core/errors/errors-data.js +79 -73
  126. package/dist/core/errors/handler.d.ts +9 -0
  127. package/dist/core/errors/handler.js +0 -0
  128. package/dist/core/errors/zod-error-map.js +30 -1
  129. package/dist/core/fetch/default-handler.d.ts +17 -0
  130. package/dist/core/fetch/default-handler.js +45 -0
  131. package/dist/core/fetch/fetch-state.d.ts +230 -0
  132. package/dist/core/fetch/fetch-state.js +896 -0
  133. package/dist/core/fetch/index.d.ts +61 -0
  134. package/dist/core/fetch/index.js +121 -0
  135. package/dist/core/fetch/types.d.ts +25 -0
  136. package/dist/core/fetch/types.js +0 -0
  137. package/dist/core/fetch/vite-plugin.d.ts +5 -0
  138. package/dist/core/fetch/vite-plugin.js +76 -0
  139. package/dist/core/hono/index.d.ts +21 -0
  140. package/dist/core/hono/index.js +101 -0
  141. package/dist/core/i18n/domain.d.ts +12 -0
  142. package/dist/core/i18n/domain.js +66 -0
  143. package/dist/core/i18n/handler.d.ts +18 -0
  144. package/dist/core/i18n/handler.js +122 -0
  145. package/dist/core/logger/core.d.ts +9 -1
  146. package/dist/core/logger/core.js +17 -1
  147. package/dist/core/messages/runtime.d.ts +0 -3
  148. package/dist/core/messages/runtime.js +1 -9
  149. package/dist/core/middleware/astro-middleware.d.ts +27 -0
  150. package/dist/core/middleware/astro-middleware.js +51 -0
  151. package/dist/core/module-loader/vite.js +1 -2
  152. package/dist/core/pages/handler.d.ts +20 -0
  153. package/dist/core/pages/handler.js +75 -0
  154. package/dist/core/preview/index.js +6 -5
  155. package/dist/core/preview/static-preview-server.js +5 -2
  156. package/dist/core/redirects/render.d.ts +2 -2
  157. package/dist/core/redirects/render.js +7 -8
  158. package/dist/core/render/params-and-props.js +2 -2
  159. package/dist/core/render/route-cache.d.ts +1 -0
  160. package/dist/core/render/route-cache.js +4 -4
  161. package/dist/core/render/slots.js +9 -2
  162. package/dist/core/rewrites/handler.d.ts +37 -0
  163. package/dist/core/rewrites/handler.js +67 -0
  164. package/dist/core/routing/3xx.js +8 -4
  165. package/dist/core/routing/create-manifest.js +11 -1
  166. package/dist/core/routing/handler.d.ts +17 -0
  167. package/dist/core/routing/handler.js +171 -0
  168. package/dist/core/routing/match.d.ts +0 -7
  169. package/dist/core/routing/match.js +0 -5
  170. package/dist/core/routing/parse-route.js +1 -1
  171. package/dist/core/routing/pattern.js +1 -1
  172. package/dist/core/routing/rewrite.js +2 -5
  173. package/dist/core/routing/router.d.ts +8 -0
  174. package/dist/core/routing/router.js +28 -0
  175. package/dist/core/routing/trailing-slash-handler.d.ts +18 -0
  176. package/dist/core/routing/trailing-slash-handler.js +67 -0
  177. package/dist/core/routing/validation.js +1 -1
  178. package/dist/core/server-islands/vite-plugin-server-islands.d.ts +6 -1
  179. package/dist/core/server-islands/vite-plugin-server-islands.js +13 -3
  180. package/dist/core/session/config.d.ts +1 -1
  181. package/dist/core/session/drivers.d.ts +1 -1
  182. package/dist/core/session/handler.d.ts +11 -0
  183. package/dist/core/session/handler.js +33 -0
  184. package/dist/core/session/runtime.js +7 -2
  185. package/dist/core/util/normalized-url.d.ts +10 -0
  186. package/dist/core/util/normalized-url.js +24 -0
  187. package/dist/core/util/pathname.d.ts +10 -1
  188. package/dist/core/util/pathname.js +13 -4
  189. package/dist/environments.js +1 -1
  190. package/dist/events/session.d.ts +8 -0
  191. package/dist/events/session.js +11 -0
  192. package/dist/i18n/middleware.d.ts +10 -0
  193. package/dist/i18n/middleware.js +4 -88
  194. package/dist/i18n/utils.js +2 -2
  195. package/dist/jsx/rehype.d.ts +1 -1
  196. package/dist/manifest/virtual-module.js +3 -1
  197. package/dist/markdown/index.d.ts +4 -0
  198. package/dist/markdown/index.js +14 -0
  199. package/dist/prefetch/index.js +12 -7
  200. package/dist/prerender/utils.js +5 -1
  201. package/dist/runtime/client/dev-toolbar/apps/audit/rules/a11y.js +9 -0
  202. package/dist/runtime/server/astro-island.js +57 -20
  203. package/dist/runtime/server/astro-island.prebuilt-dev.d.ts +1 -1
  204. package/dist/runtime/server/astro-island.prebuilt-dev.js +1 -1
  205. package/dist/runtime/server/astro-island.prebuilt.d.ts +1 -1
  206. package/dist/runtime/server/astro-island.prebuilt.js +1 -1
  207. package/dist/runtime/server/jsx.js +1 -1
  208. package/dist/runtime/server/render/common.js +10 -4
  209. package/dist/runtime/server/render/component.js +8 -6
  210. package/dist/runtime/server/render/head.js +1 -5
  211. package/dist/runtime/server/render/server-islands.js +2 -1
  212. package/dist/runtime/server/render/util.js +2 -2
  213. package/dist/runtime/server/scripts.js +6 -0
  214. package/dist/runtime/server/transition.d.ts +1 -6
  215. package/dist/runtime/server/transition.js +0 -8
  216. package/dist/transitions/events.d.ts +0 -14
  217. package/dist/transitions/events.js +0 -14
  218. package/dist/transitions/index.d.ts +0 -1
  219. package/dist/transitions/index.js +0 -2
  220. package/dist/transitions/vite-plugin-transitions.js +2 -4
  221. package/dist/types/public/config.d.ts +96 -14
  222. package/dist/types/public/content.d.ts +5 -5
  223. package/dist/types/public/index.d.ts +2 -1
  224. package/dist/types/public/integrations.d.ts +11 -3
  225. package/dist/types/public/internal.d.ts +1 -1
  226. package/dist/types/public/manifest.d.ts +1 -1
  227. package/dist/virtual-modules/i18n.d.ts +2 -2
  228. package/dist/virtual-modules/i18n.js +1 -1
  229. package/dist/vite-plugin-app/app.d.ts +13 -6
  230. package/dist/vite-plugin-app/app.js +51 -89
  231. package/dist/vite-plugin-app/createAstroServerApp.d.ts +3 -1
  232. package/dist/vite-plugin-app/createAstroServerApp.js +4 -3
  233. package/dist/vite-plugin-astro-server/plugin.js +11 -5
  234. package/dist/vite-plugin-astro-server/route-guard.d.ts +33 -0
  235. package/dist/vite-plugin-astro-server/route-guard.js +42 -23
  236. package/dist/vite-plugin-dev-status/index.d.ts +2 -0
  237. package/dist/vite-plugin-dev-status/index.js +15 -0
  238. package/dist/vite-plugin-head/index.js +36 -19
  239. package/dist/vite-plugin-hmr-reload/index.d.ts +1 -1
  240. package/dist/vite-plugin-hmr-reload/index.js +23 -1
  241. package/dist/vite-plugin-integrations-container/index.js +15 -6
  242. package/dist/vite-plugin-markdown/content-entry-type.js +7 -4
  243. package/dist/vite-plugin-markdown/images.js +9 -11
  244. package/dist/vite-plugin-markdown/index.js +12 -11
  245. package/dist/vite-plugin-utils/index.d.ts +1 -0
  246. package/dist/vite-plugin-utils/index.js +10 -1
  247. package/package.json +23 -16
  248. package/templates/content/types.d.ts +1 -0
  249. package/types/transitions.d.ts +0 -7
  250. package/dist/core/render-context.d.ts +0 -77
  251. package/dist/core/render-context.js +0 -826
@@ -0,0 +1,896 @@
1
+ import colors from "piccolore";
2
+ import {
3
+ collapseDuplicateLeadingSlashes,
4
+ prependForwardSlash,
5
+ removeTrailingForwardSlash
6
+ } from "@astrojs/internal-helpers/path";
7
+ import { deserializeActionResult } from "../../actions/runtime/client.js";
8
+ import { createCallAction, createGetActionResult, hasActionPayload } from "../../actions/utils.js";
9
+ import { AstroCookies } from "../cookies/index.js";
10
+ import { Slots } from "../render/index.js";
11
+ import {
12
+ appSymbol,
13
+ ASTRO_GENERATOR,
14
+ fetchStateSymbol,
15
+ originPathnameSymbol,
16
+ pipelineSymbol,
17
+ responseSentSymbol
18
+ } from "../constants.js";
19
+ import { pushDirective } from "../csp/runtime.js";
20
+ import { generateCspDigest } from "../encryption.js";
21
+ import { AstroError, AstroErrorData } from "../errors/index.js";
22
+ import {
23
+ computeCurrentLocale as computeCurrentLocaleUtil,
24
+ computeCurrentLocaleFromParams,
25
+ computePreferredLocale as computePreferredLocaleUtil,
26
+ computePreferredLocaleList as computePreferredLocaleListUtil
27
+ } from "../../i18n/utils.js";
28
+ import { getParams, getProps } from "../render/index.js";
29
+ import { Rewrites } from "../rewrites/handler.js";
30
+ import { isRoute404or500, isRouteServerIsland } from "../routing/match.js";
31
+ import { normalizeUrl } from "../util/normalized-url.js";
32
+ import { getOriginPathname, setOriginPathname } from "../routing/rewrite.js";
33
+ import { computePathnameFromDomain } from "../i18n/domain.js";
34
+ import { getCustom404Route, routeHasHtmlExtension } from "../routing/helpers.js";
35
+ import { getRenderOptions } from "../app/render-options.js";
36
+ import { getFirstForwardedValue, validateForwardedHeaders } from "../app/validate-headers.js";
37
+ function getFetchStateFromAPIContext(context) {
38
+ const state = context[fetchStateSymbol];
39
+ if (!state) {
40
+ throw new Error(
41
+ "FetchState not found on APIContext. This is an internal error \u2014 the context was not created through Astro's request pipeline."
42
+ );
43
+ }
44
+ return state;
45
+ }
46
+ class FetchState {
47
+ pipeline;
48
+ /**
49
+ * The request to render. Mutated during rewrites so subsequent renders
50
+ * see the rewritten URL.
51
+ */
52
+ request;
53
+ routeData;
54
+ /**
55
+ * The pathname to use for routing and rendering. Starts out as the raw,
56
+ * base-stripped, decoded pathname from the request. May be further
57
+ * normalized by `AstroHandler` after routeData is known (in dev, when
58
+ * the matched route has no `.html` extension, `.html` / `/index.html`
59
+ * suffixes are stripped).
60
+ */
61
+ pathname;
62
+ /** Resolved render options (addCookieHeader, clientAddress, locals, etc.). */
63
+ renderOptions;
64
+ /** When the request started, used to log duration. */
65
+ timeStart;
66
+ /**
67
+ * The route's loaded component module. Set before middleware runs; may
68
+ * be swapped during in-flight rewrites from inside the middleware chain.
69
+ */
70
+ componentInstance;
71
+ /**
72
+ * Slot overrides supplied by the container API. `undefined` for HTTP
73
+ * requests — `PagesHandler` coalesces to `{}` on read so we don't
74
+ * allocate an empty object per request.
75
+ */
76
+ slots;
77
+ /**
78
+ * The `Response` produced by handlers, if any. Set after page
79
+ * rendering or middleware completes.
80
+ */
81
+ response;
82
+ /**
83
+ * Default HTTP status for the rendered response. Callers override
84
+ * before rendering runs (e.g. `AstroHandler` sets this from
85
+ * `BaseApp.getDefaultStatusCode`; error handlers set `404` / `500`).
86
+ */
87
+ status = 200;
88
+ /** Whether user middleware should be skipped for this request. */
89
+ skipMiddleware = false;
90
+ /** A flag that tells the render content if the rewriting was triggered. */
91
+ isRewriting = false;
92
+ /** A safety net in case of loops (rewrite counter). */
93
+ counter = 0;
94
+ /** Cookies for this request. Created lazily on first access. */
95
+ cookies;
96
+ /** Route params derived from routeData + pathname. Computed lazily. */
97
+ #params;
98
+ get params() {
99
+ if (!this.#params && this.routeData) {
100
+ this.#params = getParams(this.routeData, this.pathname);
101
+ }
102
+ return this.#params;
103
+ }
104
+ set params(value) {
105
+ this.#params = value;
106
+ }
107
+ /** Normalized URL for this request. */
108
+ url;
109
+ /** Client address for this request. */
110
+ clientAddress;
111
+ /** Whether this is a partial render (container API). */
112
+ partial;
113
+ /** Whether to inject CSP meta tags. */
114
+ shouldInjectCspMetaTags;
115
+ /** Request-scoped locals object, shared with user middleware. */
116
+ locals = {};
117
+ /**
118
+ * Memoized `props` (see `getProps`). `null` means "not yet computed"
119
+ * — using `null` (rather than `undefined`) keeps the hidden class
120
+ * stable and distinct from a valid-but-empty result.
121
+ */
122
+ props = null;
123
+ /** Memoized `ActionAPIContext` (see `getActionAPIContext`). */
124
+ actionApiContext = null;
125
+ /** Memoized `APIContext` (see `getAPIContext`). */
126
+ apiContext = null;
127
+ /** Registered context providers keyed by name. Lazy-initialized on first provide(). */
128
+ #providers;
129
+ /** Cached values from resolved providers. Lazy-initialized on first resolve(). */
130
+ #providersResolvedValues;
131
+ /** Cached promise for lazy component instance loading. */
132
+ #componentInstancePromise;
133
+ /** SSR result for the current page render. */
134
+ result;
135
+ /** Initial props (from container/error handler). */
136
+ initialProps = {};
137
+ /** Rewrites handler instance. Lazy-initialized on first rewrite(). */
138
+ #rewrites;
139
+ /** Memoized Astro page partial. */
140
+ #astroPagePartial;
141
+ /**
142
+ * Locale-prefixed pathname derived from the Host header for domain-based
143
+ * i18n routing (e.g. `/en/boats/1/foo`), or `undefined` when the request
144
+ * isn't served from a locale-mapped domain. When set, `this.pathname` is
145
+ * derived from it so locale/param resolution match the route pattern.
146
+ */
147
+ #domainPathname;
148
+ /** Memoized current locale. */
149
+ #currentLocale;
150
+ /** Memoized preferred locale. */
151
+ #preferredLocale;
152
+ /** Memoized preferred locale list. */
153
+ #preferredLocaleList;
154
+ constructor(pipeline, request, options) {
155
+ this.pipeline = pipeline;
156
+ this.request = request;
157
+ options ??= getRenderOptions(request);
158
+ this.routeData = options?.routeData;
159
+ this.renderOptions = options ?? {
160
+ addCookieHeader: false,
161
+ clientAddress: void 0,
162
+ locals: void 0,
163
+ prerenderedErrorPageFetch: fetch,
164
+ routeData: void 0,
165
+ waitUntil: void 0
166
+ };
167
+ this.componentInstance = void 0;
168
+ this.slots = void 0;
169
+ const url = new URL(request.url);
170
+ const domainPathname = computePathnameFromDomain(
171
+ request,
172
+ url,
173
+ pipeline.manifest.i18n,
174
+ pipeline.manifest.base,
175
+ pipeline.manifest.trailingSlash,
176
+ pipeline.logger
177
+ );
178
+ if (domainPathname) {
179
+ this.#domainPathname = domainPathname;
180
+ try {
181
+ this.pathname = decodeURI(domainPathname);
182
+ } catch {
183
+ this.pathname = domainPathname;
184
+ }
185
+ } else {
186
+ this.pathname = this.#computePathname(url);
187
+ }
188
+ this.timeStart = performance.now();
189
+ this.clientAddress = options?.clientAddress;
190
+ this.locals = options?.locals ?? {};
191
+ this.url = normalizeUrl(url);
192
+ this.cookies = new AstroCookies(request);
193
+ if (pipeline.manifest.allowedDomains && pipeline.manifest.allowedDomains.length > 0) {
194
+ this.#applyForwardedHeaders();
195
+ }
196
+ if (!Reflect.get(this.request, originPathnameSymbol)) {
197
+ setOriginPathname(
198
+ this.request,
199
+ this.pathname,
200
+ pipeline.manifest.trailingSlash,
201
+ pipeline.manifest.buildFormat
202
+ );
203
+ }
204
+ this.#resolveRouteData();
205
+ }
206
+ /**
207
+ * Triggers a rewrite. Delegates to the Rewrites handler.
208
+ */
209
+ rewrite(payload) {
210
+ return (this.#rewrites ??= new Rewrites()).execute(this, payload);
211
+ }
212
+ /**
213
+ * Creates the SSR result for the current page render.
214
+ */
215
+ async createResult(mod, ctx) {
216
+ const pipeline = this.pipeline;
217
+ const { clientDirectives, inlinedScripts, compressHTML, manifest, renderers, resolve } = pipeline;
218
+ const routeData = this.routeData;
219
+ const { links, scripts, styles } = await pipeline.headElements(routeData);
220
+ const extraStyleHashes = [];
221
+ const extraScriptHashes = [];
222
+ const shouldInjectCspMetaTags = this.shouldInjectCspMetaTags ?? manifest.shouldInjectCspMetaTags;
223
+ const cspAlgorithm = manifest.csp?.algorithm ?? "SHA-256";
224
+ if (shouldInjectCspMetaTags) {
225
+ for (const style of styles) {
226
+ extraStyleHashes.push(await generateCspDigest(style.children, cspAlgorithm));
227
+ }
228
+ for (const script of scripts) {
229
+ extraScriptHashes.push(await generateCspDigest(script.children, cspAlgorithm));
230
+ }
231
+ }
232
+ const componentMetadata = await pipeline.componentMetadata(routeData) ?? manifest.componentMetadata;
233
+ const headers = new Headers({ "Content-Type": "text/html" });
234
+ const partial = typeof this.partial === "boolean" ? this.partial : Boolean(mod.partial);
235
+ const actionResult = hasActionPayload(this.locals) ? deserializeActionResult(this.locals._actionPayload.actionResult) : void 0;
236
+ const status = this.status;
237
+ const response = {
238
+ status: actionResult?.error ? actionResult?.error.status : status,
239
+ statusText: actionResult?.error ? actionResult?.error.type : "OK",
240
+ get headers() {
241
+ return headers;
242
+ },
243
+ set headers(_) {
244
+ throw new AstroError(AstroErrorData.AstroResponseHeadersReassigned);
245
+ }
246
+ };
247
+ const state = this;
248
+ const result = {
249
+ base: manifest.base,
250
+ userAssetsBase: manifest.userAssetsBase,
251
+ cancelled: false,
252
+ clientDirectives,
253
+ inlinedScripts,
254
+ componentMetadata,
255
+ compressHTML,
256
+ cookies: this.cookies,
257
+ createAstro: (props, slots) => state.createAstro(result, props, slots, ctx),
258
+ links,
259
+ // SAFETY: createResult is only called after route resolution, so routeData
260
+ // is always set and the params getter always returns a value.
261
+ params: this.params,
262
+ partial,
263
+ pathname: this.pathname,
264
+ renderers,
265
+ resolve,
266
+ response,
267
+ request: this.request,
268
+ scripts,
269
+ styles,
270
+ actionResult,
271
+ async getServerIslandNameMap() {
272
+ const serverIslands = await pipeline.getServerIslands();
273
+ return serverIslands.serverIslandNameMap ?? /* @__PURE__ */ new Map();
274
+ },
275
+ key: manifest.key,
276
+ trailingSlash: manifest.trailingSlash,
277
+ _experimentalQueuedRendering: {
278
+ pool: pipeline.nodePool,
279
+ htmlStringCache: pipeline.htmlStringCache,
280
+ enabled: manifest.experimentalQueuedRendering?.enabled,
281
+ poolSize: manifest.experimentalQueuedRendering?.poolSize,
282
+ contentCache: manifest.experimentalQueuedRendering?.contentCache
283
+ },
284
+ _metadata: {
285
+ hasHydrationScript: false,
286
+ rendererSpecificHydrationScripts: /* @__PURE__ */ new Set(),
287
+ hasRenderedHead: false,
288
+ renderedScripts: /* @__PURE__ */ new Set(),
289
+ hasDirectives: /* @__PURE__ */ new Set(),
290
+ hasRenderedServerIslandRuntime: false,
291
+ headInTree: false,
292
+ extraHead: [],
293
+ extraStyleHashes,
294
+ extraScriptHashes,
295
+ propagators: /* @__PURE__ */ new Set(),
296
+ templateDepth: 0
297
+ },
298
+ cspDestination: manifest.csp?.cspDestination ?? (routeData.prerender ? "meta" : "header"),
299
+ shouldInjectCspMetaTags,
300
+ cspAlgorithm,
301
+ scriptHashes: manifest.csp?.scriptHashes ? [...manifest.csp.scriptHashes] : [],
302
+ scriptResources: manifest.csp?.scriptResources ? [...manifest.csp.scriptResources] : [],
303
+ styleHashes: manifest.csp?.styleHashes ? [...manifest.csp.styleHashes] : [],
304
+ styleResources: manifest.csp?.styleResources ? [...manifest.csp.styleResources] : [],
305
+ directives: manifest.csp?.directives ? [...manifest.csp.directives] : [],
306
+ isStrictDynamic: manifest.csp?.isStrictDynamic ?? false,
307
+ internalFetchHeaders: manifest.internalFetchHeaders
308
+ };
309
+ this.result = result;
310
+ return result;
311
+ }
312
+ /**
313
+ * Creates the Astro global object for a component render.
314
+ */
315
+ createAstro(result, props, slotValues, apiContext) {
316
+ let astroPagePartial;
317
+ if (this.isRewriting) {
318
+ this.#astroPagePartial = this.createAstroPagePartial(result, apiContext);
319
+ }
320
+ this.#astroPagePartial ??= this.createAstroPagePartial(result, apiContext);
321
+ astroPagePartial = this.#astroPagePartial;
322
+ const astroComponentPartial = { props, self: null };
323
+ const Astro = Object.assign(
324
+ Object.create(astroPagePartial),
325
+ astroComponentPartial
326
+ );
327
+ let _slots;
328
+ Object.defineProperty(Astro, "slots", {
329
+ get: () => {
330
+ if (!_slots) {
331
+ _slots = new Slots(
332
+ result,
333
+ slotValues,
334
+ this.pipeline.logger
335
+ );
336
+ }
337
+ return _slots;
338
+ }
339
+ });
340
+ return Astro;
341
+ }
342
+ /**
343
+ * Creates the Astro page-level partial (prototype for Astro global).
344
+ */
345
+ createAstroPagePartial(result, apiContext) {
346
+ const state = this;
347
+ const { cookies, locals, params, pipeline, url } = this;
348
+ const { response } = result;
349
+ const redirect = (path, status = 302) => {
350
+ if (state.request[responseSentSymbol]) {
351
+ throw new AstroError({
352
+ ...AstroErrorData.ResponseSentError
353
+ });
354
+ }
355
+ return new Response(null, { status, headers: { Location: path } });
356
+ };
357
+ const rewrite = async (reroutePayload) => {
358
+ return await state.rewrite(reroutePayload);
359
+ };
360
+ const callAction = createCallAction(apiContext);
361
+ const partial = {
362
+ generator: ASTRO_GENERATOR,
363
+ routePattern: this.routeData.route,
364
+ isPrerendered: this.routeData.prerender,
365
+ cookies,
366
+ get clientAddress() {
367
+ return state.getClientAddress();
368
+ },
369
+ get currentLocale() {
370
+ return state.computeCurrentLocale();
371
+ },
372
+ params,
373
+ get preferredLocale() {
374
+ return state.computePreferredLocale();
375
+ },
376
+ get preferredLocaleList() {
377
+ return state.computePreferredLocaleList();
378
+ },
379
+ locals,
380
+ redirect,
381
+ rewrite,
382
+ request: this.request,
383
+ response,
384
+ site: pipeline.site,
385
+ getActionResult: createGetActionResult(locals),
386
+ get callAction() {
387
+ return callAction;
388
+ },
389
+ url,
390
+ get originPathname() {
391
+ return getOriginPathname(state.request);
392
+ },
393
+ get csp() {
394
+ return state.getCsp();
395
+ },
396
+ get logger() {
397
+ return {
398
+ info(msg) {
399
+ pipeline.logger.info(null, msg);
400
+ },
401
+ warn(msg) {
402
+ pipeline.logger.warn(null, msg);
403
+ },
404
+ error(msg) {
405
+ pipeline.logger.error(null, msg);
406
+ }
407
+ };
408
+ }
409
+ };
410
+ this.defineProviderGetters(partial);
411
+ return partial;
412
+ }
413
+ getClientAddress() {
414
+ const { pipeline, clientAddress } = this;
415
+ const routeData = this.routeData;
416
+ if (routeData.prerender) {
417
+ throw new AstroError({
418
+ ...AstroErrorData.PrerenderClientAddressNotAvailable,
419
+ message: AstroErrorData.PrerenderClientAddressNotAvailable.message(routeData.component)
420
+ });
421
+ }
422
+ if (clientAddress) {
423
+ return clientAddress;
424
+ }
425
+ if (pipeline.adapterName) {
426
+ throw new AstroError({
427
+ ...AstroErrorData.ClientAddressNotAvailable,
428
+ message: AstroErrorData.ClientAddressNotAvailable.message(pipeline.adapterName)
429
+ });
430
+ }
431
+ throw new AstroError(AstroErrorData.StaticClientAddressNotAvailable);
432
+ }
433
+ getCookies() {
434
+ return this.cookies;
435
+ }
436
+ getCsp() {
437
+ const state = this;
438
+ const { pipeline } = this;
439
+ if (!pipeline.manifest.csp) {
440
+ if (pipeline.runtimeMode === "production") {
441
+ pipeline.logger.warn(
442
+ "csp",
443
+ `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`
444
+ );
445
+ }
446
+ return void 0;
447
+ }
448
+ return {
449
+ insertDirective(payload) {
450
+ if (state.result) {
451
+ state.result.directives = pushDirective(state.result.directives, payload);
452
+ }
453
+ },
454
+ insertScriptResource(resource) {
455
+ state.result?.scriptResources.push(resource);
456
+ },
457
+ insertStyleResource(resource) {
458
+ state.result?.styleResources.push(resource);
459
+ },
460
+ insertStyleHash(hash) {
461
+ state.result?.styleHashes.push(hash);
462
+ },
463
+ insertScriptHash(hash) {
464
+ state.result?.scriptHashes.push(hash);
465
+ }
466
+ };
467
+ }
468
+ computeCurrentLocale() {
469
+ const {
470
+ url,
471
+ pipeline: { i18n },
472
+ routeData
473
+ } = this;
474
+ if (!i18n || !routeData) return;
475
+ const { defaultLocale, locales, strategy } = i18n;
476
+ const fallbackTo = strategy === "pathname-prefix-other-locales" || strategy === "domains-prefix-other-locales" ? defaultLocale : void 0;
477
+ if (this.#currentLocale) {
478
+ return this.#currentLocale;
479
+ }
480
+ let computedLocale;
481
+ if (isRouteServerIsland(routeData)) {
482
+ let referer = this.request.headers.get("referer");
483
+ if (referer) {
484
+ if (URL.canParse(referer)) {
485
+ referer = new URL(referer).pathname;
486
+ }
487
+ computedLocale = computeCurrentLocaleUtil(referer, locales, defaultLocale);
488
+ }
489
+ } else {
490
+ let pathname = routeData.pathname;
491
+ if (this.#domainPathname) {
492
+ pathname = this.pathname;
493
+ } else if (url && !routeData.pattern.test(url.pathname)) {
494
+ for (const fallbackRoute of routeData.fallbackRoutes) {
495
+ if (fallbackRoute.pattern.test(url.pathname)) {
496
+ pathname = fallbackRoute.pathname;
497
+ break;
498
+ }
499
+ }
500
+ }
501
+ pathname = pathname && !isRoute404or500(routeData) ? pathname : url.pathname ?? this.pathname;
502
+ computedLocale = computeCurrentLocaleUtil(pathname, locales, defaultLocale);
503
+ if (routeData.params.length > 0) {
504
+ const localeFromParams = computeCurrentLocaleFromParams(this.params, locales);
505
+ if (localeFromParams) {
506
+ computedLocale = localeFromParams;
507
+ }
508
+ }
509
+ }
510
+ this.#currentLocale = computedLocale ?? fallbackTo;
511
+ return this.#currentLocale;
512
+ }
513
+ computePreferredLocale() {
514
+ const {
515
+ pipeline: { i18n },
516
+ request
517
+ } = this;
518
+ if (!i18n) return;
519
+ return this.#preferredLocale ??= computePreferredLocaleUtil(request, i18n.locales);
520
+ }
521
+ computePreferredLocaleList() {
522
+ const {
523
+ pipeline: { i18n },
524
+ request
525
+ } = this;
526
+ if (!i18n) return;
527
+ return this.#preferredLocaleList ??= computePreferredLocaleListUtil(request, i18n.locales);
528
+ }
529
+ /**
530
+ * Lazily loads the route's component module. Returns the cached
531
+ * instance if already loaded. The promise is cached so concurrent
532
+ * callers share the same load.
533
+ */
534
+ async loadComponentInstance() {
535
+ if (this.componentInstance) return this.componentInstance;
536
+ if (this.#componentInstancePromise) return this.#componentInstancePromise;
537
+ this.#componentInstancePromise = this.pipeline.getComponentByRoute(this.routeData).then((mod) => {
538
+ this.componentInstance = mod;
539
+ return mod;
540
+ });
541
+ return this.#componentInstancePromise;
542
+ }
543
+ /**
544
+ * Registers a context provider under the given key. Handlers call
545
+ * this to contribute values to the request context (e.g. sessions).
546
+ * The `create` factory is called lazily on the first `resolve(key)`.
547
+ */
548
+ provide(key, provider) {
549
+ (this.#providers ??= /* @__PURE__ */ new Map()).set(key, provider);
550
+ }
551
+ /**
552
+ * Lazily resolves a provider registered under `key`. Calls
553
+ * `provider.create()` on first access and caches the result.
554
+ * Returns `undefined` if no provider was registered for the key.
555
+ */
556
+ resolve(key) {
557
+ if (this.#providersResolvedValues?.has(key)) {
558
+ return this.#providersResolvedValues.get(key);
559
+ }
560
+ const provider = this.#providers?.get(key);
561
+ if (!provider) return void 0;
562
+ const value = provider.create();
563
+ (this.#providersResolvedValues ??= /* @__PURE__ */ new Map()).set(key, value);
564
+ return value;
565
+ }
566
+ /**
567
+ * Runs all registered `finalize` callbacks. Should be called after
568
+ * the response is produced, typically in a `finally` block.
569
+ *
570
+ * Returns synchronously (no promise allocation) when nothing needs
571
+ * finalizing — important for the hot path where sessions are not used.
572
+ */
573
+ finalizeAll() {
574
+ if (!this.#providersResolvedValues || this.#providersResolvedValues.size === 0) return;
575
+ let chain;
576
+ for (const [key, provider] of this.#providers) {
577
+ if (provider.finalize && this.#providersResolvedValues.has(key)) {
578
+ const result = provider.finalize(this.#providersResolvedValues.get(key));
579
+ if (result) {
580
+ chain = chain ? chain.then(() => result) : result;
581
+ }
582
+ }
583
+ }
584
+ return chain;
585
+ }
586
+ /**
587
+ * Adds lazy getters to `target` for each registered provider key.
588
+ * Used by context creation (APIContext, Astro global) so that
589
+ * provider values like `session` and `cache` appear as properties
590
+ * without hard-coding the keys.
591
+ *
592
+ * Always defines a `session` getter (returning `undefined` when no
593
+ * provider is registered) so `ctx.session` / `Astro.session` is a
594
+ * present property regardless of whether the sessions handler was
595
+ * included in the pipeline.
596
+ */
597
+ defineProviderGetters(target) {
598
+ const state = this;
599
+ if (this.#providers) {
600
+ for (const key of this.#providers.keys()) {
601
+ Object.defineProperty(target, key, {
602
+ get: () => state.resolve(key),
603
+ enumerable: true,
604
+ configurable: true
605
+ });
606
+ }
607
+ }
608
+ if (!this.#providers?.has("session")) {
609
+ let warned = false;
610
+ Object.defineProperty(target, "session", {
611
+ get() {
612
+ if (!warned) {
613
+ warned = true;
614
+ state.pipeline.logger.warn(
615
+ "session",
616
+ "`Astro.session` was accessed but no session storage is configured. Either configure the storage manually or use an adapter that provides session storage. For more information, see https://docs.astro.build/en/guides/sessions/"
617
+ );
618
+ }
619
+ return void 0;
620
+ },
621
+ enumerable: true,
622
+ configurable: true
623
+ });
624
+ }
625
+ }
626
+ /**
627
+ * Resolves the route to use for this request and stores it on
628
+ * `this.routeData`. If the adapter (or the dev server) provided a
629
+ * `routeData` via render options it's already set and this is a
630
+ * no-op. Otherwise we use the app's synchronous route matcher and
631
+ * fall back to a `404.astro` route so middleware can still run.
632
+ *
633
+ * Called eagerly from the constructor so individual handlers
634
+ * (actions, pages, middleware, etc.) always see a resolved route
635
+ * without the caller needing an extra setup step.
636
+ *
637
+ * Once routeData is known, finalizes `this.pathname`: in dev, if the
638
+ * matched route has no `.html` extension, strip `.html` / `/index.html`
639
+ * suffixes so the rendering pipeline sees the canonical pathname.
640
+ */
641
+ /**
642
+ * Strip `.html` / `/index.html` suffixes from the pathname so the
643
+ * rendering pipeline sees the canonical route path. Only applies to
644
+ * page routes where `.html` is framework-injected. Endpoint routes
645
+ * preserve `.html` because any such suffix is user-provided (e.g.
646
+ * from `getStaticPaths` params). Skipped when the matched route
647
+ * itself has an `.html` extension in its definition.
648
+ */
649
+ #stripHtmlExtension() {
650
+ if (this.routeData && this.routeData.type === "page" && !routeHasHtmlExtension(this.routeData)) {
651
+ this.pathname = this.pathname.replace(/\/index\.html$/, "/").replace(/\.html$/, "");
652
+ }
653
+ }
654
+ #resolveRouteData() {
655
+ const pipeline = this.pipeline;
656
+ if (this.routeData) {
657
+ this.#stripHtmlExtension();
658
+ return;
659
+ }
660
+ const matched = pipeline.matchRoute(this.pathname);
661
+ if (matched && matched.prerender && pipeline.manifest.serverLike) {
662
+ if (matched.params.length > 0) {
663
+ const allMatches = pipeline.matchAllRoutes(this.pathname);
664
+ this.routeData = allMatches.find((r) => !r.prerender);
665
+ } else {
666
+ this.routeData = void 0;
667
+ }
668
+ } else {
669
+ this.routeData = matched;
670
+ }
671
+ pipeline.logger.debug("router", "Astro matched the following route for " + this.request.url);
672
+ pipeline.logger.debug("router", "RouteData:\n" + this.routeData);
673
+ if (!this.routeData) {
674
+ const custom404 = getCustom404Route(pipeline.manifestData);
675
+ if (custom404 && !custom404.prerender) {
676
+ this.routeData = custom404;
677
+ }
678
+ }
679
+ if (!this.routeData) {
680
+ pipeline.logger.debug("router", "Astro hasn't found routes that match " + this.request.url);
681
+ pipeline.logger.debug("router", "Here's the available routes:\n", pipeline.manifestData);
682
+ return;
683
+ }
684
+ this.#stripHtmlExtension();
685
+ }
686
+ /**
687
+ * Strips the pipeline's base from the request URL, prepends a forward
688
+ * slash, and decodes the pathname. Falls back to the raw (not decoded)
689
+ * pathname if `decodeURI` throws.
690
+ *
691
+ * Mirrors `BaseApp.removeBase`, including the
692
+ * `collapseDuplicateLeadingSlashes` fix that prevents middleware
693
+ * authorization bypass when the URL starts with `//`.
694
+ */
695
+ #computePathname(url) {
696
+ let pathname = collapseDuplicateLeadingSlashes(url.pathname);
697
+ const base = this.pipeline.manifest.base;
698
+ if (pathname.startsWith(base)) {
699
+ const baseWithoutTrailingSlash = removeTrailingForwardSlash(base);
700
+ pathname = pathname.slice(baseWithoutTrailingSlash.length + 1);
701
+ }
702
+ pathname = prependForwardSlash(pathname);
703
+ try {
704
+ return decodeURI(pathname);
705
+ } catch (e) {
706
+ this.pipeline.logger.error(null, e.toString());
707
+ return pathname;
708
+ }
709
+ }
710
+ /**
711
+ * Reads X-Forwarded-Proto, X-Forwarded-Host, and X-Forwarded-Port
712
+ * from the request headers, validates them against the manifest's
713
+ * `allowedDomains`, and updates `this.url` accordingly. Also resolves
714
+ * `clientAddress` from X-Forwarded-For when the host is trusted.
715
+ *
716
+ * Only called when `allowedDomains` is configured — without it,
717
+ * forwarded headers are never trusted.
718
+ */
719
+ #applyForwardedHeaders() {
720
+ const headers = this.request.headers;
721
+ const allowedDomains = this.pipeline.manifest.allowedDomains;
722
+ const validated = validateForwardedHeaders(
723
+ getFirstForwardedValue(headers.get("x-forwarded-proto") ?? void 0),
724
+ getFirstForwardedValue(headers.get("x-forwarded-host") ?? void 0),
725
+ getFirstForwardedValue(headers.get("x-forwarded-port") ?? void 0),
726
+ allowedDomains
727
+ );
728
+ if (!validated.protocol && !validated.host && !validated.port) return;
729
+ if (validated.protocol) {
730
+ this.url.protocol = validated.protocol + ":";
731
+ }
732
+ if (validated.host) {
733
+ const colonIdx = validated.host.indexOf(":");
734
+ if (colonIdx !== -1) {
735
+ this.url.hostname = validated.host.slice(0, colonIdx);
736
+ this.url.port = validated.host.slice(colonIdx + 1);
737
+ } else {
738
+ this.url.hostname = validated.host;
739
+ this.url.port = "";
740
+ }
741
+ }
742
+ if (validated.port) {
743
+ this.url.port = validated.port;
744
+ }
745
+ const hostTrusted = validated.host !== void 0;
746
+ if (hostTrusted && !this.clientAddress) {
747
+ const forwardedFor = getFirstForwardedValue(
748
+ this.request.headers.get("x-forwarded-for") ?? void 0
749
+ );
750
+ if (forwardedFor) {
751
+ this.clientAddress = forwardedFor;
752
+ }
753
+ }
754
+ const oldRequest = this.request;
755
+ this.request = new Request(this.url, oldRequest);
756
+ const app = Reflect.get(oldRequest, appSymbol);
757
+ if (app !== void 0) {
758
+ Reflect.set(this.request, appSymbol, app);
759
+ }
760
+ }
761
+ /**
762
+ * Returns the resolved `props` for this render, computing them lazily
763
+ * from the route + component module on first access. If the
764
+ * `initialProps` already carries user-supplied props (e.g. the
765
+ * container API) those are used verbatim.
766
+ */
767
+ async getProps() {
768
+ if (this.props !== null) return this.props;
769
+ if (Object.keys(this.initialProps).length > 0) {
770
+ this.props = this.initialProps;
771
+ return this.props;
772
+ }
773
+ const pipeline = this.pipeline;
774
+ const mod = await this.loadComponentInstance();
775
+ this.props = await getProps({
776
+ mod,
777
+ routeData: this.routeData,
778
+ routeCache: pipeline.routeCache,
779
+ pathname: this.pathname,
780
+ logger: pipeline.logger,
781
+ serverLike: pipeline.manifest.serverLike,
782
+ base: pipeline.manifest.base,
783
+ trailingSlash: pipeline.manifest.trailingSlash
784
+ });
785
+ return this.props;
786
+ }
787
+ /**
788
+ * Returns the `ActionAPIContext` for this render, creating it lazily.
789
+ * Used by middleware, actions, and page dispatch.
790
+ */
791
+ getActionAPIContext() {
792
+ if (this.actionApiContext !== null) return this.actionApiContext;
793
+ const state = this;
794
+ const ctx = {
795
+ get cookies() {
796
+ return state.cookies;
797
+ },
798
+ routePattern: this.routeData.route,
799
+ isPrerendered: this.routeData.prerender,
800
+ get clientAddress() {
801
+ return state.getClientAddress();
802
+ },
803
+ get currentLocale() {
804
+ return state.computeCurrentLocale();
805
+ },
806
+ generator: ASTRO_GENERATOR,
807
+ get locals() {
808
+ return state.locals;
809
+ },
810
+ set locals(_) {
811
+ throw new AstroError(AstroErrorData.LocalsReassigned);
812
+ },
813
+ // SAFETY: getActionAPIContext is only called after route resolution,
814
+ // so routeData is always set and the params getter always returns a value.
815
+ params: this.params,
816
+ get preferredLocale() {
817
+ return state.computePreferredLocale();
818
+ },
819
+ get preferredLocaleList() {
820
+ return state.computePreferredLocaleList();
821
+ },
822
+ request: this.request,
823
+ site: this.pipeline.site,
824
+ url: this.url,
825
+ get originPathname() {
826
+ return getOriginPathname(state.request);
827
+ },
828
+ get csp() {
829
+ return state.getCsp();
830
+ },
831
+ get logger() {
832
+ if (!state.pipeline.manifest.experimentalLogger) {
833
+ state.pipeline.logger.warn(
834
+ null,
835
+ "The Astro.logger is available only when experimental.logger is defined."
836
+ );
837
+ return void 0;
838
+ }
839
+ return {
840
+ info(msg) {
841
+ state.pipeline.logger.info(null, msg);
842
+ },
843
+ warn(msg) {
844
+ state.pipeline.logger.warn(null, msg);
845
+ },
846
+ error(msg) {
847
+ state.pipeline.logger.error(null, msg);
848
+ }
849
+ };
850
+ }
851
+ };
852
+ this.defineProviderGetters(ctx);
853
+ this.actionApiContext = ctx;
854
+ return this.actionApiContext;
855
+ }
856
+ /**
857
+ * Returns the `APIContext` for this render, creating it lazily from
858
+ * the memoized props + action context.
859
+ *
860
+ * Callers must ensure `getProps()` has resolved at least once before
861
+ * calling this.
862
+ */
863
+ getAPIContext() {
864
+ if (this.apiContext !== null) return this.apiContext;
865
+ const actionApiContext = this.getActionAPIContext();
866
+ const state = this;
867
+ const redirect = (path, status = 302) => new Response(null, { status, headers: { Location: path } });
868
+ const rewrite = async (reroutePayload) => {
869
+ return await state.rewrite(reroutePayload);
870
+ };
871
+ Reflect.set(actionApiContext, pipelineSymbol, this.pipeline);
872
+ actionApiContext[fetchStateSymbol] = this;
873
+ this.apiContext = Object.assign(actionApiContext, {
874
+ props: this.props,
875
+ redirect,
876
+ rewrite,
877
+ getActionResult: createGetActionResult(actionApiContext.locals),
878
+ callAction: createCallAction(actionApiContext)
879
+ });
880
+ return this.apiContext;
881
+ }
882
+ /**
883
+ * Invalidates the cached `APIContext` so the next `getAPIContext()`
884
+ * call re-derives it from the (possibly mutated) state. Used
885
+ * after an in-flight rewrite swaps the route / request / params.
886
+ */
887
+ invalidateContexts() {
888
+ this.props = null;
889
+ this.actionApiContext = null;
890
+ this.apiContext = null;
891
+ }
892
+ }
893
+ export {
894
+ FetchState,
895
+ getFetchStateFromAPIContext
896
+ };