astro 7.2.2 → 7.2.4

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 (158) hide show
  1. package/dist/actions/handler.d.ts +6 -12
  2. package/dist/actions/handler.js +30 -40
  3. package/dist/actions/load.d.ts +12 -0
  4. package/dist/actions/load.js +55 -0
  5. package/dist/actions/runtime/entrypoints/server.js +5 -4
  6. package/dist/actions/runtime/server.js +8 -6
  7. package/dist/assets/fonts/providers/index.d.ts +1 -1
  8. package/dist/assets/fonts/providers/index.js +2 -12
  9. package/dist/assets/utils/vendor/image-size/types/heif.js +8 -3
  10. package/dist/assets/utils/vendor/image-size/types/icns.js +10 -2
  11. package/dist/assets/utils/vendor/image-size/types/jp2.js +2 -2
  12. package/dist/assets/utils/vendor/image-size/types/jxl.js +5 -2
  13. package/dist/assets/utils/vendor/image-size/types/utils.d.ts +1 -1
  14. package/dist/assets/utils/vendor/image-size/types/utils.js +20 -6
  15. package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
  16. package/dist/container/environment.d.ts +20 -0
  17. package/dist/container/environment.js +106 -0
  18. package/dist/container/index.js +73 -37
  19. package/dist/content/content-layer.js +3 -3
  20. package/dist/content/data-store-writer.d.ts +7 -10
  21. package/dist/content/data-store-writer.js +62 -27
  22. package/dist/content/data-store.d.ts +20 -3
  23. package/dist/content/data-store.js +28 -7
  24. package/dist/content/mutable-data-store.js +15 -10
  25. package/dist/content/runtime.d.ts +3 -2
  26. package/dist/content/runtime.js +43 -26
  27. package/dist/core/app/app.d.ts +0 -2
  28. package/dist/core/app/app.js +0 -7
  29. package/dist/core/app/base.d.ts +32 -20
  30. package/dist/core/app/base.js +79 -73
  31. package/dist/core/app/dev-facade.d.ts +27 -0
  32. package/dist/core/app/dev-facade.js +51 -0
  33. package/dist/core/app/entrypoints/index.d.ts +0 -1
  34. package/dist/core/app/entrypoints/index.js +0 -2
  35. package/dist/core/app/entrypoints/virtual/dev.js +24 -19
  36. package/dist/core/app/node.js +13 -14
  37. package/dist/core/app/prepare-response.d.ts +1 -1
  38. package/dist/core/app/validate-headers.js +7 -3
  39. package/dist/core/build/app.d.ts +31 -6
  40. package/dist/core/build/app.js +31 -13
  41. package/dist/core/build/environment.d.ts +25 -0
  42. package/dist/core/build/environment.js +157 -0
  43. package/dist/core/cache/handler.d.ts +13 -7
  44. package/dist/core/cache/handler.js +55 -51
  45. package/dist/core/cache/provider.d.ts +4 -0
  46. package/dist/core/cache/provider.js +15 -0
  47. package/dist/core/constants.d.ts +0 -11
  48. package/dist/core/constants.js +1 -5
  49. package/dist/core/dev/dev.js +1 -1
  50. package/dist/core/environment/dev-nonrunnable.d.ts +6 -0
  51. package/dist/core/environment/dev-nonrunnable.js +170 -0
  52. package/dist/core/environment/index.d.ts +90 -0
  53. package/dist/core/environment/index.js +12 -0
  54. package/dist/core/environment/production.d.ts +6 -0
  55. package/dist/core/environment/production.js +117 -0
  56. package/dist/core/errors/build-handler.d.ts +5 -10
  57. package/dist/core/errors/build-handler.js +11 -17
  58. package/dist/core/errors/default-handler.d.ts +4 -9
  59. package/dist/core/errors/default-handler.js +92 -107
  60. package/dist/core/errors/dev-handler.d.ts +7 -11
  61. package/dist/core/errors/dev-handler.js +71 -69
  62. package/dist/core/errors/errors-data.d.ts +18 -0
  63. package/dist/core/errors/errors-data.js +7 -0
  64. package/dist/core/errors/handler.d.ts +22 -3
  65. package/dist/core/errors/handler.js +25 -0
  66. package/dist/core/fetch/default-handler.d.ts +15 -8
  67. package/dist/core/fetch/default-handler.js +12 -34
  68. package/dist/core/fetch/features.d.ts +23 -0
  69. package/dist/core/fetch/features.js +27 -0
  70. package/dist/core/fetch/fetch-state.d.ts +52 -7
  71. package/dist/core/fetch/fetch-state.js +99 -92
  72. package/dist/core/fetch/index.d.ts +9 -2
  73. package/dist/core/fetch/index.js +18 -79
  74. package/dist/core/fetch/vite-plugin.js +2 -1
  75. package/dist/core/i18n/domain.js +4 -11
  76. package/dist/core/i18n/handler.d.ts +28 -13
  77. package/dist/core/i18n/handler.js +100 -100
  78. package/dist/core/logger/manifest-logger.d.ts +31 -0
  79. package/dist/core/logger/manifest-logger.js +37 -0
  80. package/dist/core/manifest/ambient-source.d.ts +2 -0
  81. package/dist/core/manifest/ambient-source.js +4 -0
  82. package/dist/core/manifest/ambient.d.ts +16 -0
  83. package/dist/core/manifest/ambient.js +22 -0
  84. package/dist/core/manifest/derived.d.ts +3 -0
  85. package/dist/core/manifest/derived.js +10 -0
  86. package/dist/core/manifest/memo.d.ts +31 -0
  87. package/dist/core/manifest/memo.js +47 -0
  88. package/dist/core/messages/runtime.js +1 -1
  89. package/dist/core/middleware/astro-middleware.d.ts +25 -35
  90. package/dist/core/middleware/astro-middleware.js +61 -81
  91. package/dist/core/middleware/load.d.ts +19 -0
  92. package/dist/core/middleware/load.js +36 -0
  93. package/dist/core/middleware/sequence.js +15 -7
  94. package/dist/core/pages/handler.d.ts +18 -25
  95. package/dist/core/pages/handler.js +68 -84
  96. package/dist/core/redirects/render.js +3 -8
  97. package/dist/core/render/index.d.ts +0 -1
  98. package/dist/core/render/index.js +0 -2
  99. package/dist/core/render/route-cache.d.ts +6 -1
  100. package/dist/core/render/route-cache.js +11 -1
  101. package/dist/core/rewrites/handler.d.ts +4 -6
  102. package/dist/core/rewrites/handler.js +19 -20
  103. package/dist/core/routing/default.d.ts +2 -0
  104. package/dist/core/routing/default.js +7 -1
  105. package/dist/core/routing/dev.d.ts +1 -3
  106. package/dist/core/routing/dev.js +12 -5
  107. package/dist/core/routing/handler.d.ts +6 -16
  108. package/dist/core/routing/handler.js +126 -164
  109. package/dist/core/routing/helpers.d.ts +7 -1
  110. package/dist/core/routing/helpers.js +21 -0
  111. package/dist/core/routing/match-request.d.ts +10 -0
  112. package/dist/core/routing/match-request.js +46 -0
  113. package/dist/core/routing/route-table.d.ts +34 -0
  114. package/dist/core/routing/route-table.js +41 -0
  115. package/dist/core/routing/trailing-slash-handler.d.ts +4 -14
  116. package/dist/core/routing/trailing-slash-handler.js +39 -50
  117. package/dist/core/server-islands/mappings.d.ts +6 -0
  118. package/dist/core/server-islands/mappings.js +12 -0
  119. package/dist/core/session/driver.d.ts +4 -0
  120. package/dist/core/session/driver.js +14 -0
  121. package/dist/core/session/handler.d.ts +1 -1
  122. package/dist/core/session/handler.js +8 -8
  123. package/dist/core/session/provider-disabled.js +2 -2
  124. package/dist/entrypoints/prerender.js +5 -1
  125. package/dist/i18n/middleware.d.ts +4 -4
  126. package/dist/i18n/middleware.js +3 -3
  127. package/dist/manifest/serialized.d.ts +1 -0
  128. package/dist/manifest/serialized.js +9 -2
  129. package/dist/runtime/prerender/static-paths.d.ts +14 -2
  130. package/dist/runtime/prerender/static-paths.js +4 -3
  131. package/dist/types/public/config.d.ts +433 -241
  132. package/dist/vite-plugin-app/createAstroServerApp.js +22 -18
  133. package/dist/vite-plugin-app/environment.d.ts +18 -0
  134. package/dist/vite-plugin-app/environment.js +210 -0
  135. package/dist/vite-plugin-app/handle-request.d.ts +30 -0
  136. package/dist/vite-plugin-app/handle-request.js +129 -0
  137. package/dist/vite-plugin-app/index.d.ts +1 -1
  138. package/dist/vite-plugin-app/index.js +1 -1
  139. package/package.json +14 -7
  140. package/src/core/README.md +37 -0
  141. package/src/core/manifest/ambient-source.ts +9 -0
  142. package/src/types/README.md +5 -0
  143. package/dist/container/pipeline.d.ts +0 -14
  144. package/dist/container/pipeline.js +0 -78
  145. package/dist/core/app/dev/app.d.ts +0 -31
  146. package/dist/core/app/dev/app.js +0 -80
  147. package/dist/core/app/dev/pipeline.d.ts +0 -17
  148. package/dist/core/app/dev/pipeline.js +0 -133
  149. package/dist/core/app/pipeline.d.ts +0 -14
  150. package/dist/core/app/pipeline.js +0 -123
  151. package/dist/core/base-pipeline.d.ts +0 -183
  152. package/dist/core/base-pipeline.js +0 -293
  153. package/dist/core/build/pipeline.d.ts +0 -38
  154. package/dist/core/build/pipeline.js +0 -202
  155. package/dist/vite-plugin-app/app.d.ts +0 -62
  156. package/dist/vite-plugin-app/app.js +0 -237
  157. package/dist/vite-plugin-app/pipeline.d.ts +0 -25
  158. package/dist/vite-plugin-app/pipeline.js +0 -189
@@ -0,0 +1,34 @@
1
+ import type { RouteData, SSRManifest } from '../../types/public/internal.js';
2
+ import { Router } from './router.js';
3
+ export interface RouteTable {
4
+ /** Route data derived from the manifest, used for route matching. */
5
+ routes: RouteData[];
6
+ /** Pattern-matching router compiled from `routes`. */
7
+ router: Router;
8
+ }
9
+ /**
10
+ * The route table for a manifest: the derived route list (with the default
11
+ * 404 ensured) and the compiled router. All route reads — matching, rewrites,
12
+ * custom-404 fallbacks, `manifestData` accessors — go through this single
13
+ * entry so dev HMR updates are visible to every consumer at once.
14
+ */
15
+ export declare function getRouteTable(manifest: SSRManifest): RouteTable;
16
+ /**
17
+ * Atomically replaces the route table for a manifest (dev `astro:routes-updated`).
18
+ * Runs `ensure404Route` on the new list, compiles a fresh `Router`, and swaps
19
+ * the memo entry in one step, so no consumer can observe a half-updated table.
20
+ */
21
+ export declare function updateRouteTable(manifest: SSRManifest, routes: RouteData[]): void;
22
+ /**
23
+ * Low-level route matching against the manifest routes. Returns the matched
24
+ * `RouteData` or `undefined`. Does not filter prerendered routes or check
25
+ * public assets — use the app-level match for that.
26
+ */
27
+ export declare function matchRoute(manifest: SSRManifest, pathname: string): RouteData | undefined;
28
+ /**
29
+ * Returns all routes matching the given pathname, in priority order. Used when
30
+ * the first match cannot serve the request (e.g. a prerendered dynamic route
31
+ * that doesn't cover this specific path) and the caller needs to try
32
+ * subsequent matches.
33
+ */
34
+ export declare function matchAllRoutes(manifest: SSRManifest, pathname: string): RouteData[];
@@ -0,0 +1,41 @@
1
+ import { createManifestMemo } from "../manifest/memo.js";
2
+ import { ensure404Route } from "./astro-designed-error-pages.js";
3
+ import { Router } from "./router.js";
4
+ function compileRouteTable(manifest, routes) {
5
+ const routesList = ensure404Route({ routes });
6
+ const router = new Router(routesList.routes, {
7
+ base: manifest.base,
8
+ trailingSlash: manifest.trailingSlash,
9
+ buildFormat: manifest.buildFormat
10
+ });
11
+ return { routes: routesList.routes, router };
12
+ }
13
+ const routeTables = createManifestMemo(
14
+ (manifest) => (
15
+ // Fresh array: `ensure404Route` mutates the DERIVED list, never `manifest.routes`.
16
+ compileRouteTable(
17
+ manifest,
18
+ (manifest.routes ?? []).map((route) => route.routeData)
19
+ )
20
+ )
21
+ );
22
+ function getRouteTable(manifest) {
23
+ return routeTables.get(manifest);
24
+ }
25
+ function updateRouteTable(manifest, routes) {
26
+ routeTables.set(manifest, compileRouteTable(manifest, [...routes]));
27
+ }
28
+ function matchRoute(manifest, pathname) {
29
+ const match = getRouteTable(manifest).router.match(pathname, { allowWithoutBase: true });
30
+ if (match.type !== "match") return void 0;
31
+ return match.route;
32
+ }
33
+ function matchAllRoutes(manifest, pathname) {
34
+ return getRouteTable(manifest).router.matchAll(pathname, { allowWithoutBase: true });
35
+ }
36
+ export {
37
+ getRouteTable,
38
+ matchAllRoutes,
39
+ matchRoute,
40
+ updateRouteTable
41
+ };
@@ -1,18 +1,8 @@
1
- import type { BaseApp } from '../app/base.js';
2
- import type { Pipeline } from '../base-pipeline.js';
3
1
  import type { FetchState } from '../fetch/fetch-state.js';
4
2
  /**
5
3
  * Handles trailing-slash normalization for incoming requests. If the
6
- * request's pathname does not match the app's configured `trailingSlash`
7
- * policy, a redirect response is returned. Otherwise, returns `undefined`
8
- * so the caller can continue processing the request.
4
+ * request's pathname does not match the manifest's configured
5
+ * `trailingSlash` policy, a redirect `Response` is returned. Otherwise,
6
+ * returns `undefined` so the caller can continue processing the request.
9
7
  */
10
- export declare class TrailingSlashHandler {
11
- #private;
12
- constructor(app: BaseApp<Pipeline>);
13
- /**
14
- * Returns a redirect `Response` if the request pathname needs
15
- * normalization, or `undefined` if no redirect is required.
16
- */
17
- handle(state: FetchState): Response | undefined;
18
- }
8
+ export declare function handleTrailingSlash(state: FetchState): Response | undefined;
@@ -7,61 +7,50 @@ import {
7
7
  } from "@astrojs/internal-helpers/path";
8
8
  import { prepareResponse } from "../app/prepare-response.js";
9
9
  import { redirectTemplate } from "./3xx.js";
10
- class TrailingSlashHandler {
11
- #app;
12
- constructor(app) {
13
- this.#app = app;
10
+ function handleTrailingSlash(state) {
11
+ const url = new URL(state.request.url);
12
+ const redirect = redirectTrailingSlash(state.manifest.trailingSlash, url.pathname);
13
+ if (redirect === url.pathname) {
14
+ return void 0;
14
15
  }
15
- /**
16
- * Returns a redirect `Response` if the request pathname needs
17
- * normalization, or `undefined` if no redirect is required.
18
- */
19
- handle(state) {
20
- const url = new URL(state.request.url);
21
- const redirect = this.#redirectTrailingSlash(url.pathname);
22
- if (redirect === url.pathname) {
23
- return void 0;
24
- }
25
- const addCookieHeader = state.renderOptions.addCookieHeader;
26
- const status = state.request.method === "GET" ? 301 : 308;
27
- const response = new Response(
28
- redirectTemplate({
29
- status,
30
- relativeLocation: url.pathname,
31
- absoluteLocation: redirect,
32
- from: state.request.url
33
- }),
34
- {
35
- status,
36
- headers: {
37
- location: redirect + url.search
38
- }
16
+ const addCookieHeader = state.renderOptions.addCookieHeader;
17
+ const status = state.request.method === "GET" ? 301 : 308;
18
+ const response = new Response(
19
+ redirectTemplate({
20
+ status,
21
+ relativeLocation: url.pathname,
22
+ absoluteLocation: redirect,
23
+ from: state.request.url
24
+ }),
25
+ {
26
+ status,
27
+ headers: {
28
+ location: redirect + url.search
39
29
  }
40
- );
41
- prepareResponse(response, { addCookieHeader });
42
- return response;
43
- }
44
- #redirectTrailingSlash(pathname) {
45
- const { trailingSlash } = this.#app.manifest;
46
- if (pathname === "/" || isInternalPath(pathname)) {
47
- return pathname;
48
- }
49
- const path = collapseDuplicateTrailingSlashes(pathname, trailingSlash !== "never");
50
- if (path !== pathname) {
51
- return path;
52
- }
53
- if (trailingSlash === "ignore") {
54
- return pathname;
55
- }
56
- if (trailingSlash === "always" && !hasFileExtension(pathname)) {
57
- return appendForwardSlash(pathname);
58
- }
59
- if (trailingSlash === "never") {
60
- return removeTrailingForwardSlash(pathname);
61
30
  }
31
+ );
32
+ prepareResponse(response, { addCookieHeader });
33
+ return response;
34
+ }
35
+ function redirectTrailingSlash(trailingSlash, pathname) {
36
+ if (pathname === "/" || isInternalPath(pathname)) {
37
+ return pathname;
38
+ }
39
+ const path = collapseDuplicateTrailingSlashes(pathname, trailingSlash !== "never");
40
+ if (path !== pathname) {
41
+ return path;
42
+ }
43
+ if (trailingSlash === "ignore") {
62
44
  return pathname;
63
45
  }
46
+ if (trailingSlash === "always" && !hasFileExtension(pathname)) {
47
+ return appendForwardSlash(pathname);
48
+ }
49
+ if (trailingSlash === "never") {
50
+ return removeTrailingForwardSlash(pathname);
51
+ }
52
+ return pathname;
64
53
  }
65
54
  export {
66
- TrailingSlashHandler
55
+ handleTrailingSlash
67
56
  };
@@ -0,0 +1,6 @@
1
+ import type { ServerIslandMappings, SSRManifest } from '../app/types.js';
2
+ /**
3
+ * The server-island mappings for a manifest. Deliberately NOT memoized: the
4
+ * manifest thunk is a module import, which is cheap.
5
+ */
6
+ export declare function getServerIslands(manifest: SSRManifest): Promise<ServerIslandMappings>;
@@ -0,0 +1,12 @@
1
+ async function getServerIslands(manifest) {
2
+ if (manifest.serverIslandMappings) {
3
+ return manifest.serverIslandMappings();
4
+ }
5
+ return {
6
+ serverIslandMap: /* @__PURE__ */ new Map(),
7
+ serverIslandNameMap: /* @__PURE__ */ new Map()
8
+ };
9
+ }
10
+ export {
11
+ getServerIslands
12
+ };
@@ -0,0 +1,4 @@
1
+ import type { SSRManifest } from '../app/types.js';
2
+ import type { SessionDriverFactory } from './types.js';
3
+ /** Resolves the session driver factory from the manifest, `null` when none. */
4
+ export declare function getSessionDriver(manifest: SSRManifest): Promise<SessionDriverFactory | null>;
@@ -0,0 +1,14 @@
1
+ import { createAsyncManifestMemo } from "../manifest/memo.js";
2
+ const sessionDriverMemo = createAsyncManifestMemo(async (manifest) => {
3
+ if (manifest.sessionDriver) {
4
+ const driverModule = await manifest.sessionDriver();
5
+ return driverModule?.default || null;
6
+ }
7
+ return null;
8
+ });
9
+ function getSessionDriver(manifest) {
10
+ return sessionDriverMemo.get(manifest);
11
+ }
12
+ export {
13
+ getSessionDriver
14
+ };
@@ -6,6 +6,6 @@ import type { FetchState } from '../fetch/fetch-state.js';
6
6
  * persisted.
7
7
  *
8
8
  * No-op (returns synchronously) if sessions are not configured on the
9
- * pipeline, avoiding promise allocation on the hot path.
9
+ * manifest, avoiding promise allocation on the hot path.
10
10
  */
11
11
  export declare function provideSession(state: FetchState): Promise<void> | void;
@@ -1,16 +1,16 @@
1
- import { PipelineFeatures } from "../base-pipeline.js";
1
+ import { getEnvironment } from "../environment/index.js";
2
+ import { markFeatureUsed, FetchFeatures } from "../fetch/features.js";
3
+ import { getSessionDriver } from "./driver.js";
2
4
  import { AstroSession, PERSIST_SYMBOL } from "./runtime.js";
3
5
  const SESSION_KEY = "session";
4
6
  function provideSession(state) {
5
- state.pipeline.usedFeatures |= PipelineFeatures.sessions;
6
- const pipeline = state.pipeline;
7
- const config = pipeline.manifest.sessionConfig;
7
+ markFeatureUsed(state.manifest, FetchFeatures.sessions);
8
+ const config = state.manifest.sessionConfig;
8
9
  if (!config) return;
9
10
  return provideSessionAsync(state, config);
10
11
  }
11
12
  async function provideSessionAsync(state, config) {
12
- const pipeline = state.pipeline;
13
- const driverFactory = await pipeline.getSessionDriver();
13
+ const driverFactory = await getSessionDriver(state.manifest);
14
14
  if (!driverFactory) return;
15
15
  state.provide(SESSION_KEY, {
16
16
  create() {
@@ -18,10 +18,10 @@ async function provideSessionAsync(state, config) {
18
18
  return new AstroSession({
19
19
  cookies,
20
20
  config,
21
- runtimeMode: pipeline.runtimeMode,
21
+ runtimeMode: getEnvironment(state.manifest).runtimeMode,
22
22
  driverFactory,
23
23
  mockStorage: null,
24
- logger: pipeline.logger
24
+ logger: state.logger
25
25
  });
26
26
  },
27
27
  finalize(session) {
@@ -1,6 +1,6 @@
1
- import { PipelineFeatures } from "../base-pipeline.js";
1
+ import { markFeatureUsed, FetchFeatures } from "../fetch/features.js";
2
2
  function provideSession(state) {
3
- state.pipeline.usedFeatures |= PipelineFeatures.sessions;
3
+ markFeatureUsed(state.manifest, FetchFeatures.sessions);
4
4
  }
5
5
  export {
6
6
  provideSession
@@ -1,6 +1,10 @@
1
1
  import { manifest } from "virtual:astro:manifest";
2
+ import { createBuildEnvironment } from "../core/build/environment.js";
2
3
  import { BuildApp } from "../core/build/app.js";
3
- const app = new BuildApp(manifest);
4
+ import { setEnvironment } from "../core/environment/index.js";
5
+ const buildEnv = createBuildEnvironment();
6
+ setEnvironment(manifest, buildEnv.env);
7
+ const app = new BuildApp(manifest, buildEnv);
4
8
  export {
5
9
  app,
6
10
  manifest
@@ -3,11 +3,11 @@ import type { MiddlewareHandler } from '../types/public/common.js';
3
3
  /**
4
4
  * Builds a `MiddlewareHandler` that post-processes the rendered response
5
5
  * against the given i18n configuration. This is a thin wrapper around
6
- * `core/i18n/handler.ts#I18n` that preserves the middleware-shaped API
7
- * exposed to users via `astro:i18n.middleware(...)` for the manual
6
+ * `core/i18n/handler.ts#finalizeI18n` that preserves the middleware-shaped
7
+ * API exposed to users via `astro:i18n.middleware(...)` for the manual
8
8
  * routing strategy.
9
9
  *
10
- * Internal request handling no longer uses this — `AstroHandler.render`
11
- * invokes `I18n.finalize` directly as an explicit post-processing step.
10
+ * Only user middleware goes through this wrapper — `handleRequest`
11
+ * invokes `finalizeI18n` directly as an explicit post-processing step.
12
12
  */
13
13
  export declare function createI18nMiddleware(i18n: SSRManifest['i18n'], base: SSRManifest['base'], trailingSlash: SSRManifest['trailingSlash'], format: SSRManifest['buildFormat']): MiddlewareHandler;
@@ -1,11 +1,11 @@
1
1
  import { getFetchStateFromAPIContext } from "../core/fetch/fetch-state.js";
2
- import { I18n } from "../core/i18n/handler.js";
2
+ import { compileI18n, finalizeI18n } from "../core/i18n/handler.js";
3
3
  function createI18nMiddleware(i18n, base, trailingSlash, format) {
4
4
  if (!i18n) return (_, next) => next();
5
- const handler = new I18n(i18n, base, trailingSlash, format);
5
+ const compiled = compileI18n(i18n, base, trailingSlash, format);
6
6
  return async (context, next) => {
7
7
  const response = await next();
8
- return handler.finalize(getFetchStateFromAPIContext(context), response);
8
+ return finalizeI18n(compiled, getFetchStateFromAPIContext(context), response);
9
9
  };
10
10
  }
11
11
  export {
@@ -2,6 +2,7 @@ import { type Plugin } from 'vite';
2
2
  import type { AstroSettings } from '../types/astro.js';
3
3
  export declare const SERIALIZED_MANIFEST_ID = "virtual:astro:manifest";
4
4
  export declare const SERIALIZED_MANIFEST_RESOLVED_ID: string;
5
+ export declare const AMBIENT_MANIFEST_SPECIFIER = "#astro-internal/ambient-manifest";
5
6
  export declare function serializedManifestPlugin({ settings, command, sync, }: {
6
7
  settings: AstroSettings;
7
8
  command: 'dev' | 'build';
@@ -30,6 +30,7 @@ import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../core/constants.js";
30
30
  import { resolveMiddlewareMode } from "../integrations/adapter-utils.js";
31
31
  const SERIALIZED_MANIFEST_ID = "virtual:astro:manifest";
32
32
  const SERIALIZED_MANIFEST_RESOLVED_ID = "\0" + SERIALIZED_MANIFEST_ID;
33
+ const AMBIENT_MANIFEST_SPECIFIER = "#astro-internal/ambient-manifest";
33
34
  function serializedManifestPlugin({
34
35
  settings,
35
36
  command,
@@ -67,7 +68,7 @@ function serializedManifestPlugin({
67
68
  },
68
69
  resolveId: {
69
70
  filter: {
70
- id: new RegExp(`^${SERIALIZED_MANIFEST_ID}$`)
71
+ id: new RegExp(`^(${SERIALIZED_MANIFEST_ID}|${AMBIENT_MANIFEST_SPECIFIER})$`)
71
72
  },
72
73
  handler() {
73
74
  return SERIALIZED_MANIFEST_RESOLVED_ID;
@@ -89,7 +90,12 @@ function serializedManifestPlugin({
89
90
  const cacheProviderLine = hasCacheConfig ? `cacheProvider: () => import('${VIRTUAL_CACHE_PROVIDER_ID}'),` : "";
90
91
  const loggerLine = settings.config.logger ? `logger: () => import('${VIRTUAL_LOGGER_ID}'),` : "";
91
92
  const code = `
92
- import { deserializeManifest as _deserializeManifest } from 'astro/app';
93
+ // 'astro/app/manifest' (not the 'astro/app' barrel): the barrel pulls in
94
+ // BaseApp -> DefaultFetchHandler -> the ambient-manifest module, which
95
+ // resolves to THIS virtual module \u2014 importing the barrel here would close
96
+ // a top-level import cycle that leaves deserializeManifest uninitialized
97
+ // when the dev module graph re-evaluates after invalidation.
98
+ import { deserializeManifest as _deserializeManifest } from 'astro/app/manifest';
93
99
  import { renderers } from '${ASTRO_RENDERERS_MODULE_ID}';
94
100
  import { routes } from '${ASTRO_ROUTES_MODULE_ID}';
95
101
  import { pageMap } from '${VIRTUAL_PAGES_MODULE_ID}';
@@ -213,6 +219,7 @@ async function createSerializedManifest(settings, encodedKey) {
213
219
  };
214
220
  }
215
221
  export {
222
+ AMBIENT_MANIFEST_SPECIFIER,
216
223
  SERIALIZED_MANIFEST_ID,
217
224
  SERIALIZED_MANIFEST_RESOLVED_ID,
218
225
  serializedManifestPlugin
@@ -1,14 +1,26 @@
1
+ import type { ComponentInstance } from '../../types/astro.js';
1
2
  import type { SSRManifest } from '../../core/app/types.js';
2
- import type { Pipeline } from '../../core/base-pipeline.js';
3
3
  import type { PathWithRoute } from '../../types/public/integrations.js';
4
+ import type { RouteData } from '../../types/public/internal.js';
5
+ import type { RouteCache } from '../../core/render/route-cache.js';
4
6
  export type { PathWithRoute } from '../../types/public/integrations.js';
5
7
  /**
6
8
  * Minimal interface for what StaticPaths needs from an App.
7
9
  * This allows adapters to pass any App-like object (BuildApp, NodeApp, etc).
10
+ * Only the manifest is required: the route cache and the component loader can
11
+ * be reached through the manifest-keyed functional core.
12
+ *
13
+ * When the caller's app provides `routeCache` / `getComponentByRoute`
14
+ * (`BuildApp` does), those are preferred: they execute inside the app's own
15
+ * module graph, which matters when `StaticPaths` and the app come from
16
+ * different bundles (the default prerenderer imports the prerender bundle's
17
+ * `BuildApp`, whose per-manifest state lives in the bundle's copies of the
18
+ * core modules).
8
19
  */
9
20
  export interface StaticPathsApp {
10
21
  manifest: SSRManifest;
11
- pipeline: Pick<Pipeline, 'routeCache' | 'getComponentByRoute'>;
22
+ routeCache?: RouteCache;
23
+ getComponentByRoute?(route: RouteData): Promise<ComponentInstance>;
12
24
  }
13
25
  /**
14
26
  * Collects all static paths for prerendering.
@@ -1,6 +1,7 @@
1
+ import { getEnvironment } from "../../core/environment/index.js";
1
2
  import { stringifyParams } from "../../core/routing/params.js";
2
3
  import { getFallbackRoute, routeIsFallback, routeIsRedirect } from "../../core/routing/helpers.js";
3
- import { callGetStaticPaths } from "../../core/render/route-cache.js";
4
+ import { callGetStaticPaths, getRouteCache } from "../../core/render/route-cache.js";
4
5
  class StaticPaths {
5
6
  #app;
6
7
  constructor(app) {
@@ -43,12 +44,12 @@ class StaticPaths {
43
44
  async #getPathsForRoute(route) {
44
45
  const paths = [];
45
46
  const manifest = this.#app.manifest;
46
- const routeCache = this.#app.pipeline.routeCache;
47
+ const routeCache = this.#app.routeCache ?? getRouteCache(manifest);
47
48
  if (route.pathname) {
48
49
  paths.push({ pathname: route.pathname, route });
49
50
  return paths;
50
51
  }
51
- const componentInstance = await this.#app.pipeline.getComponentByRoute(route);
52
+ const componentInstance = this.#app.getComponentByRoute ? await this.#app.getComponentByRoute(route) : await getEnvironment(manifest).getComponentByRoute(manifest, route);
52
53
  const routeToProcess = routeIsRedirect(route) ? route.redirectRoute : routeIsFallback(route) ? getFallbackRoute(route, manifest.routes) : route;
53
54
  const actualRoute = routeToProcess ?? route;
54
55
  const staticPaths = await callGetStaticPaths({