astro 4.4.0 → 4.4.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 (100) hide show
  1. package/dist/@types/astro.d.ts +42 -42
  2. package/dist/assets/build/generate.d.ts +1 -1
  3. package/dist/assets/build/generate.js +1 -2
  4. package/dist/cli/add/babel.d.ts +1 -1
  5. package/dist/cli/add/index.js +1 -1
  6. package/dist/cli/db/index.js +2 -0
  7. package/dist/cli/info/index.js +2 -0
  8. package/dist/cli/preferences/index.js +2 -0
  9. package/dist/content/types-generator.js +4 -4
  10. package/dist/core/app/index.js +40 -123
  11. package/dist/core/app/pipeline.d.ts +7 -0
  12. package/dist/core/app/pipeline.js +39 -0
  13. package/dist/core/app/types.d.ts +2 -2
  14. package/dist/core/base-pipeline.d.ts +59 -0
  15. package/dist/core/base-pipeline.js +27 -0
  16. package/dist/core/build/generate.d.ts +1 -1
  17. package/dist/core/build/generate.js +41 -110
  18. package/dist/core/build/index.js +0 -4
  19. package/dist/core/build/{buildPipeline.d.ts → pipeline.d.ts} +13 -13
  20. package/dist/core/build/pipeline.js +180 -0
  21. package/dist/core/build/plugins/plugin-manifest.js +3 -2
  22. package/dist/core/build/types.d.ts +0 -2
  23. package/dist/core/config/schema.d.ts +37 -54
  24. package/dist/core/config/schema.js +10 -39
  25. package/dist/core/constants.d.ts +10 -1
  26. package/dist/core/constants.js +14 -4
  27. package/dist/core/dev/dev.js +1 -1
  28. package/dist/core/dev/restart.js +1 -1
  29. package/dist/core/endpoint/index.d.ts +6 -5
  30. package/dist/core/endpoint/index.js +7 -34
  31. package/dist/core/errors/errors-data.d.ts +3 -3
  32. package/dist/core/messages.js +2 -2
  33. package/dist/core/middleware/callMiddleware.d.ts +1 -1
  34. package/dist/core/middleware/callMiddleware.js +2 -9
  35. package/dist/core/middleware/index.d.ts +2 -2
  36. package/dist/core/middleware/index.js +74 -9
  37. package/dist/core/module-loader/vite.js +4 -4
  38. package/dist/core/preview/index.js +2 -0
  39. package/dist/core/preview/static-preview-server.js +1 -7
  40. package/dist/core/redirects/helpers.d.ts +1 -3
  41. package/dist/core/redirects/helpers.js +0 -29
  42. package/dist/core/redirects/index.d.ts +2 -1
  43. package/dist/core/redirects/index.js +3 -3
  44. package/dist/core/redirects/render.d.ts +2 -0
  45. package/dist/core/redirects/render.js +33 -0
  46. package/dist/core/render/index.d.ts +7 -13
  47. package/dist/core/render/index.js +7 -7
  48. package/dist/core/render/params-and-props.d.ts +8 -3
  49. package/dist/core/render/params-and-props.js +24 -16
  50. package/dist/core/render/result.d.ts +8 -7
  51. package/dist/core/render/result.js +4 -5
  52. package/dist/core/render-context.d.ts +32 -0
  53. package/dist/core/render-context.js +219 -0
  54. package/dist/core/routing/index.d.ts +0 -1
  55. package/dist/core/routing/index.js +0 -2
  56. package/dist/core/routing/manifest/create.js +5 -3
  57. package/dist/core/routing/params.d.ts +1 -7
  58. package/dist/core/routing/params.js +0 -15
  59. package/dist/core/sync/index.js +3 -3
  60. package/dist/i18n/index.d.ts +4 -4
  61. package/dist/i18n/index.js +2 -2
  62. package/dist/i18n/middleware.d.ts +0 -5
  63. package/dist/i18n/middleware.js +62 -70
  64. package/dist/i18n/utils.d.ts +26 -0
  65. package/dist/{core/render/context.js → i18n/utils.js} +32 -50
  66. package/dist/prerender/routing.d.ts +1 -1
  67. package/dist/prerender/routing.js +2 -3
  68. package/dist/runtime/client/dev-toolbar/apps/astro.js +13 -9
  69. package/dist/runtime/client/dev-toolbar/apps/audit/a11y.js +2 -2
  70. package/dist/runtime/server/endpoint.js +2 -2
  71. package/dist/virtual-modules/i18n.js +7 -5
  72. package/dist/vite-plugin-astro/hmr.d.ts +1 -0
  73. package/dist/vite-plugin-astro/hmr.js +7 -4
  74. package/dist/vite-plugin-astro-server/error.d.ts +2 -2
  75. package/dist/vite-plugin-astro-server/error.js +2 -5
  76. package/dist/vite-plugin-astro-server/index.d.ts +0 -6
  77. package/dist/vite-plugin-astro-server/index.js +0 -19
  78. package/dist/vite-plugin-astro-server/pipeline.d.ts +19 -0
  79. package/dist/vite-plugin-astro-server/pipeline.js +117 -0
  80. package/dist/vite-plugin-astro-server/plugin.js +5 -5
  81. package/dist/vite-plugin-astro-server/request.d.ts +3 -4
  82. package/dist/vite-plugin-astro-server/request.js +6 -9
  83. package/dist/vite-plugin-astro-server/route.d.ts +3 -4
  84. package/dist/vite-plugin-astro-server/route.js +34 -162
  85. package/dist/vite-plugin-dev-toolbar/vite-plugin-dev-toolbar.js +3 -3
  86. package/package.json +3 -8
  87. package/dist/core/app/ssrPipeline.d.ts +0 -3
  88. package/dist/core/app/ssrPipeline.js +0 -6
  89. package/dist/core/build/buildPipeline.js +0 -150
  90. package/dist/core/pipeline.d.ts +0 -39
  91. package/dist/core/pipeline.js +0 -107
  92. package/dist/core/render/context.d.ts +0 -52
  93. package/dist/core/render/core.d.ts +0 -10
  94. package/dist/core/render/core.js +0 -65
  95. package/dist/core/render/environment.d.ts +0 -34
  96. package/dist/core/render/environment.js +0 -6
  97. package/dist/runtime/server/consts.d.ts +0 -1
  98. package/dist/runtime/server/consts.js +0 -4
  99. package/dist/vite-plugin-astro-server/devPipeline.d.ts +0 -22
  100. package/dist/vite-plugin-astro-server/devPipeline.js +0 -65
@@ -1,6 +1,5 @@
1
1
  import { fileURLToPath } from "node:url";
2
2
  import { performance } from "perf_hooks";
3
- import enableDestroy from "server-destroy";
4
3
  import { preview } from "vite";
5
4
  import * as msg from "../messages.js";
6
5
  import { getResolvedHostForHttpServer } from "./util.js";
@@ -30,7 +29,6 @@ async function createStaticPreviewServer(settings, logger) {
30
29
  }
31
30
  throw err;
32
31
  }
33
- enableDestroy(previewServer.httpServer);
34
32
  logger.info(
35
33
  "SKIP_FORMAT",
36
34
  msg.serverStart({
@@ -51,11 +49,7 @@ async function createStaticPreviewServer(settings, logger) {
51
49
  port: settings.config.server.port,
52
50
  closed,
53
51
  server: previewServer.httpServer,
54
- stop: async () => {
55
- await new Promise((resolve, reject) => {
56
- previewServer.httpServer.destroy((err) => err ? reject(err) : resolve(void 0));
57
- });
58
- }
52
+ stop: previewServer.close.bind(previewServer)
59
53
  };
60
54
  }
61
55
  export {
@@ -1,5 +1,3 @@
1
- import type { Params, RedirectRouteData, RouteData, ValidRedirectStatus } from '../../@types/astro.js';
1
+ import type { RedirectRouteData, RouteData } from '../../@types/astro.js';
2
2
  export declare function routeIsRedirect(route: RouteData | undefined): route is RedirectRouteData;
3
3
  export declare function routeIsFallback(route: RouteData | undefined): route is RedirectRouteData;
4
- export declare function redirectRouteGenerate(redirectRoute: RouteData, data: Params): string;
5
- export declare function redirectRouteStatus(redirectRoute: RouteData, method?: string): ValidRedirectStatus;
@@ -4,36 +4,7 @@ function routeIsRedirect(route) {
4
4
  function routeIsFallback(route) {
5
5
  return route?.type === "fallback";
6
6
  }
7
- function redirectRouteGenerate(redirectRoute, data) {
8
- const routeData = redirectRoute.redirectRoute;
9
- const route = redirectRoute.redirect;
10
- if (typeof routeData !== "undefined") {
11
- return routeData?.generate(data) || routeData?.pathname || "/";
12
- } else if (typeof route === "string") {
13
- let target = route;
14
- for (const param of Object.keys(data)) {
15
- const paramValue = data[param];
16
- target = target.replace(`[${param}]`, paramValue);
17
- target = target.replace(`[...${param}]`, paramValue);
18
- }
19
- return target;
20
- } else if (typeof route === "undefined") {
21
- return "/";
22
- }
23
- return route.destination;
24
- }
25
- function redirectRouteStatus(redirectRoute, method = "GET") {
26
- const routeData = redirectRoute.redirectRoute;
27
- if (routeData && typeof redirectRoute.redirect === "object") {
28
- return redirectRoute.redirect.status;
29
- } else if (method !== "GET") {
30
- return 308;
31
- }
32
- return 301;
33
- }
34
7
  export {
35
- redirectRouteGenerate,
36
- redirectRouteStatus,
37
8
  routeIsFallback,
38
9
  routeIsRedirect
39
10
  };
@@ -1,3 +1,4 @@
1
1
  export { RedirectComponentInstance, RedirectSinglePageBuiltModule } from './component.js';
2
- export { redirectRouteGenerate, redirectRouteStatus, routeIsRedirect } from './helpers.js';
2
+ export { routeIsRedirect } from './helpers.js';
3
3
  export { getRedirectLocationOrThrow } from './validate.js';
4
+ export { renderRedirect } from './render.js';
@@ -1,11 +1,11 @@
1
1
  import { RedirectComponentInstance, RedirectSinglePageBuiltModule } from "./component.js";
2
- import { redirectRouteGenerate, redirectRouteStatus, routeIsRedirect } from "./helpers.js";
2
+ import { routeIsRedirect } from "./helpers.js";
3
3
  import { getRedirectLocationOrThrow } from "./validate.js";
4
+ import { renderRedirect } from "./render.js";
4
5
  export {
5
6
  RedirectComponentInstance,
6
7
  RedirectSinglePageBuiltModule,
7
8
  getRedirectLocationOrThrow,
8
- redirectRouteGenerate,
9
- redirectRouteStatus,
9
+ renderRedirect,
10
10
  routeIsRedirect
11
11
  };
@@ -0,0 +1,2 @@
1
+ import type { RenderContext } from '../render-context.js';
2
+ export declare function renderRedirect(renderContext: RenderContext): Promise<Response>;
@@ -0,0 +1,33 @@
1
+ async function renderRedirect(renderContext) {
2
+ const {
3
+ request: { method },
4
+ routeData
5
+ } = renderContext;
6
+ const { redirect, redirectRoute } = routeData;
7
+ const status = redirectRoute && typeof redirect === "object" ? redirect.status : method === "GET" ? 301 : 308;
8
+ const headers = { location: redirectRouteGenerate(renderContext) };
9
+ return new Response(null, { status, headers });
10
+ }
11
+ function redirectRouteGenerate(renderContext) {
12
+ const {
13
+ params,
14
+ routeData: { redirect, redirectRoute }
15
+ } = renderContext;
16
+ if (typeof redirectRoute !== "undefined") {
17
+ return redirectRoute?.generate(params) || redirectRoute?.pathname || "/";
18
+ } else if (typeof redirect === "string") {
19
+ let target = redirect;
20
+ for (const param of Object.keys(params)) {
21
+ const paramValue = params[param];
22
+ target = target.replace(`[${param}]`, paramValue);
23
+ target = target.replace(`[...${param}]`, paramValue);
24
+ }
25
+ return target;
26
+ } else if (typeof redirect === "undefined") {
27
+ return "/";
28
+ }
29
+ return redirect.destination;
30
+ }
31
+ export {
32
+ renderRedirect
33
+ };
@@ -1,14 +1,12 @@
1
- import type { AstroMiddlewareInstance, ComponentInstance, RouteData } from '../../@types/astro.js';
2
- import type { Environment } from './environment.js';
3
- export { computePreferredLocale, createRenderContext } from './context.js';
4
- export type { RenderContext } from './context.js';
5
- export { createEnvironment } from './environment.js';
6
- export { getParamsAndProps } from './params-and-props.js';
1
+ import type { ComponentInstance, RouteData } from '../../@types/astro.js';
2
+ import type { Pipeline } from '../base-pipeline.js';
3
+ export { Pipeline } from '../base-pipeline.js';
4
+ export { getParams, getProps } from './params-and-props.js';
7
5
  export { loadRenderer } from './renderer.js';
8
- export type { Environment };
6
+ export { createResult } from './result.js';
9
7
  export interface SSROptions {
10
- /** The environment instance */
11
- env: Environment;
8
+ /** The pipeline instance */
9
+ pipeline: Pipeline;
12
10
  /** location of file on disk */
13
11
  filePath: URL;
14
12
  /** the web request (needed for dynamic routes) */
@@ -19,8 +17,4 @@ export interface SSROptions {
19
17
  request: Request;
20
18
  /** optional, in case we need to render something outside a dev server */
21
19
  route: RouteData;
22
- /**
23
- * Optional middlewares
24
- */
25
- middleware?: AstroMiddlewareInstance;
26
20
  }
@@ -1,11 +1,11 @@
1
- import { computePreferredLocale, createRenderContext } from "./context.js";
2
- import { createEnvironment } from "./environment.js";
3
- import { getParamsAndProps } from "./params-and-props.js";
1
+ import { Pipeline } from "../base-pipeline.js";
2
+ import { getParams, getProps } from "./params-and-props.js";
4
3
  import { loadRenderer } from "./renderer.js";
4
+ import { createResult } from "./result.js";
5
5
  export {
6
- computePreferredLocale,
7
- createEnvironment,
8
- createRenderContext,
9
- getParamsAndProps,
6
+ Pipeline,
7
+ createResult,
8
+ getParams,
9
+ getProps,
10
10
  loadRenderer
11
11
  };
@@ -3,11 +3,16 @@ import type { Logger } from '../logger/core.js';
3
3
  import type { RouteCache } from './route-cache.js';
4
4
  interface GetParamsAndPropsOptions {
5
5
  mod: ComponentInstance | undefined;
6
- route?: RouteData | undefined;
6
+ routeData?: RouteData | undefined;
7
7
  routeCache: RouteCache;
8
8
  pathname: string;
9
9
  logger: Logger;
10
- ssr: boolean;
10
+ serverLike: boolean;
11
11
  }
12
- export declare function getParamsAndProps(opts: GetParamsAndPropsOptions): Promise<[Params, Props]>;
12
+ export declare function getProps(opts: GetParamsAndPropsOptions): Promise<Props>;
13
+ /**
14
+ * When given a route with the pattern `/[x]/[y]/[z]/svelte`, and a pathname `/a/b/c/svelte`,
15
+ * returns the params object: { x: "a", y: "b", z: "c" }.
16
+ */
17
+ export declare function getParams(route: RouteData, pathname: string): Params;
13
18
  export {};
@@ -1,17 +1,16 @@
1
1
  import { AstroError, AstroErrorData } from "../errors/index.js";
2
2
  import { routeIsFallback } from "../redirects/helpers.js";
3
3
  import { routeIsRedirect } from "../redirects/index.js";
4
- import { getParams } from "../routing/params.js";
5
4
  import { callGetStaticPaths, findPathItemByKey } from "./route-cache.js";
6
- async function getParamsAndProps(opts) {
7
- const { logger, mod, route, routeCache, pathname, ssr } = opts;
5
+ async function getProps(opts) {
6
+ const { logger, mod, routeData: route, routeCache, pathname, serverLike } = opts;
8
7
  if (!route || route.pathname) {
9
- return [{}, {}];
8
+ return {};
10
9
  }
11
- const params = getRouteParams(route, pathname) ?? {};
12
10
  if (routeIsRedirect(route) || routeIsFallback(route)) {
13
- return [params, {}];
11
+ return {};
14
12
  }
13
+ const params = getParams(route, pathname);
15
14
  if (mod) {
16
15
  validatePrerenderEndpointCollision(route, mod, params);
17
16
  }
@@ -20,10 +19,10 @@ async function getParamsAndProps(opts) {
20
19
  route,
21
20
  routeCache,
22
21
  logger,
23
- ssr
22
+ ssr: serverLike
24
23
  });
25
24
  const matchedStaticPath = findPathItemByKey(staticPaths, params, route, logger);
26
- if (!matchedStaticPath && (ssr ? route.prerender : true)) {
25
+ if (!matchedStaticPath && (serverLike ? route.prerender : true)) {
27
26
  throw new AstroError({
28
27
  ...AstroErrorData.NoMatchingStaticPathFound,
29
28
  message: AstroErrorData.NoMatchingStaticPathFound.message(pathname),
@@ -31,15 +30,23 @@ async function getParamsAndProps(opts) {
31
30
  });
32
31
  }
33
32
  const props = matchedStaticPath?.props ? { ...matchedStaticPath.props } : {};
34
- return [params, props];
33
+ return props;
35
34
  }
36
- function getRouteParams(route, pathname) {
37
- if (route.params.length) {
38
- const paramsMatch = route.pattern.exec(decodeURIComponent(pathname));
39
- if (paramsMatch) {
40
- return getParams(route.params)(paramsMatch);
35
+ function getParams(route, pathname) {
36
+ if (!route.params.length)
37
+ return {};
38
+ const paramsMatch = route.pattern.exec(decodeURIComponent(pathname));
39
+ if (!paramsMatch)
40
+ return {};
41
+ const params = {};
42
+ route.params.forEach((key, i) => {
43
+ if (key.startsWith("...")) {
44
+ params[key.slice(3)] = paramsMatch[i + 1] ? paramsMatch[i + 1] : void 0;
45
+ } else {
46
+ params[key] = paramsMatch[i + 1];
41
47
  }
42
- }
48
+ });
49
+ return params;
43
50
  }
44
51
  function validatePrerenderEndpointCollision(route, mod, params) {
45
52
  if (route.type === "endpoint" && mod.getStaticPaths) {
@@ -59,5 +66,6 @@ function validatePrerenderEndpointCollision(route, mod, params) {
59
66
  }
60
67
  }
61
68
  export {
62
- getParamsAndProps
69
+ getParams,
70
+ getProps
63
71
  };
@@ -1,7 +1,7 @@
1
1
  import type { Locales, Params, SSRElement, SSRLoadedRenderer, SSRResult } from '../../@types/astro.js';
2
2
  import { AstroCookies } from '../cookies/index.js';
3
3
  import type { Logger } from '../logger/core.js';
4
- import type { RoutingStrategies } from '../config/schema.js';
4
+ import { type RoutingStrategies } from '../../i18n/utils.js';
5
5
  export interface CreateResultArgs {
6
6
  /**
7
7
  * Used to provide better error messages for `Astro.clientAddress`
@@ -23,16 +23,17 @@ export interface CreateResultArgs {
23
23
  * Used for `Astro.site`
24
24
  */
25
25
  site: string | undefined;
26
- links?: Set<SSRElement>;
27
- scripts?: Set<SSRElement>;
28
- styles?: Set<SSRElement>;
29
- componentMetadata?: SSRResult['componentMetadata'];
26
+ links: Set<SSRElement>;
27
+ scripts: Set<SSRElement>;
28
+ styles: Set<SSRElement>;
29
+ componentMetadata: SSRResult['componentMetadata'];
30
30
  request: Request;
31
31
  status: number;
32
32
  locals: App.Locals;
33
- cookies?: AstroCookies;
33
+ cookies: AstroCookies;
34
34
  locales: Locales | undefined;
35
35
  defaultLocale: string | undefined;
36
- routingStrategy: RoutingStrategies | undefined;
36
+ route: string;
37
+ strategy: RoutingStrategies | undefined;
37
38
  }
38
39
  export declare function createResult(args: CreateResultArgs): SSRResult;
@@ -7,9 +7,8 @@ import {
7
7
  computeCurrentLocale,
8
8
  computePreferredLocale,
9
9
  computePreferredLocaleList
10
- } from "./context.js";
11
- const clientAddressSymbol = Symbol.for("astro.clientAddress");
12
- const responseSentSymbol = Symbol.for("astro.responseSent");
10
+ } from "../../i18n/utils.js";
11
+ import { clientAddressSymbol, responseSentSymbol } from "../constants.js";
13
12
  function getFunctionExpression(slot) {
14
13
  if (!slot)
15
14
  return;
@@ -160,9 +159,9 @@ function createResult(args) {
160
159
  }
161
160
  if (args.locales) {
162
161
  currentLocale = computeCurrentLocale(
163
- request,
162
+ url.pathname,
164
163
  args.locales,
165
- args.routingStrategy,
164
+ args.strategy,
166
165
  args.defaultLocale
167
166
  );
168
167
  if (currentLocale) {
@@ -0,0 +1,32 @@
1
+ import type { APIContext, ComponentInstance, MiddlewareHandler, RouteData } from '../@types/astro.js';
2
+ import { AstroCookies } from './cookies/index.js';
3
+ import { type Pipeline } from './render/index.js';
4
+ export declare class RenderContext {
5
+ #private;
6
+ readonly pipeline: Pipeline;
7
+ locals: App.Locals;
8
+ readonly middleware: MiddlewareHandler;
9
+ readonly pathname: string;
10
+ readonly request: Request;
11
+ readonly routeData: RouteData;
12
+ status: number;
13
+ readonly cookies: AstroCookies;
14
+ readonly params: import("../@types/astro.js").Params;
15
+ private constructor();
16
+ static create({ locals, middleware, pathname, pipeline, request, routeData, status, }: Pick<RenderContext, 'pathname' | 'pipeline' | 'request' | 'routeData'> & Partial<Pick<RenderContext, 'locals' | 'middleware' | 'status'>>): RenderContext;
17
+ /**
18
+ * The main function of the RenderContext.
19
+ *
20
+ * Use this function to render any route known to Astro.
21
+ * It attempts to render a route. A route can be a:
22
+ *
23
+ * - page
24
+ * - redirect
25
+ * - endpoint
26
+ * - fallback
27
+ */
28
+ render(componentInstance: ComponentInstance | undefined): Promise<Response>;
29
+ createAPIContext(props: APIContext['props']): APIContext;
30
+ createResult(mod: ComponentInstance): Promise<import("../@types/astro.js").SSRResult>;
31
+ get i18nData(): Pick<APIContext<Record<string, any>, Record<string, string | undefined>>, "currentLocale" | "preferredLocale" | "preferredLocaleList">;
32
+ }
@@ -0,0 +1,219 @@
1
+ import { renderEndpoint } from "../runtime/server/endpoint.js";
2
+ import { attachCookiesToResponse } from "./cookies/index.js";
3
+ import { callMiddleware } from "./middleware/callMiddleware.js";
4
+ import { sequence } from "./middleware/index.js";
5
+ import { AstroCookies } from "./cookies/index.js";
6
+ import { createResult } from "./render/index.js";
7
+ import { renderPage } from "../runtime/server/index.js";
8
+ import {
9
+ ASTRO_VERSION,
10
+ ROUTE_TYPE_HEADER,
11
+ clientAddressSymbol,
12
+ clientLocalsSymbol
13
+ } from "./constants.js";
14
+ import { getParams, getProps } from "./render/index.js";
15
+ import { AstroError, AstroErrorData } from "./errors/index.js";
16
+ import {
17
+ computeCurrentLocale,
18
+ computePreferredLocale,
19
+ computePreferredLocaleList
20
+ } from "../i18n/utils.js";
21
+ import { renderRedirect } from "./redirects/render.js";
22
+ class RenderContext {
23
+ constructor(pipeline, locals, middleware, pathname, request, routeData, status, cookies = new AstroCookies(request), params = getParams(routeData, pathname)) {
24
+ this.pipeline = pipeline;
25
+ this.locals = locals;
26
+ this.middleware = middleware;
27
+ this.pathname = pathname;
28
+ this.request = request;
29
+ this.routeData = routeData;
30
+ this.status = status;
31
+ this.cookies = cookies;
32
+ this.params = params;
33
+ }
34
+ static create({
35
+ locals = {},
36
+ middleware,
37
+ pathname,
38
+ pipeline,
39
+ request,
40
+ routeData,
41
+ status = 200
42
+ }) {
43
+ return new RenderContext(
44
+ pipeline,
45
+ locals,
46
+ sequence(...pipeline.internalMiddleware, middleware ?? pipeline.middleware),
47
+ pathname,
48
+ request,
49
+ routeData,
50
+ status
51
+ );
52
+ }
53
+ /**
54
+ * The main function of the RenderContext.
55
+ *
56
+ * Use this function to render any route known to Astro.
57
+ * It attempts to render a route. A route can be a:
58
+ *
59
+ * - page
60
+ * - redirect
61
+ * - endpoint
62
+ * - fallback
63
+ */
64
+ async render(componentInstance) {
65
+ const { cookies, middleware, pathname, pipeline, routeData } = this;
66
+ const { logger, routeCache, serverLike, streaming } = pipeline;
67
+ const props = await getProps({
68
+ mod: componentInstance,
69
+ routeData,
70
+ routeCache,
71
+ pathname,
72
+ logger,
73
+ serverLike
74
+ });
75
+ const apiContext = this.createAPIContext(props);
76
+ const { type } = routeData;
77
+ const lastNext = type === "endpoint" ? () => renderEndpoint(componentInstance, apiContext, serverLike, logger) : type === "redirect" ? () => renderRedirect(this) : type === "page" ? async () => {
78
+ const result = await this.createResult(componentInstance);
79
+ const response2 = await renderPage(
80
+ result,
81
+ componentInstance?.default,
82
+ props,
83
+ {},
84
+ streaming,
85
+ routeData
86
+ );
87
+ response2.headers.set(ROUTE_TYPE_HEADER, "page");
88
+ return response2;
89
+ } : type === "fallback" ? () => new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: "fallback" } }) : () => {
90
+ throw new Error("Unknown type of route: " + type);
91
+ };
92
+ const response = await callMiddleware(middleware, apiContext, lastNext);
93
+ if (response.headers.get(ROUTE_TYPE_HEADER)) {
94
+ response.headers.delete(ROUTE_TYPE_HEADER);
95
+ }
96
+ attachCookiesToResponse(response, cookies);
97
+ return response;
98
+ }
99
+ createAPIContext(props) {
100
+ const renderContext = this;
101
+ const { cookies, i18nData, params, pipeline, request } = this;
102
+ const { currentLocale, preferredLocale, preferredLocaleList } = i18nData;
103
+ const generator = `Astro v${ASTRO_VERSION}`;
104
+ const redirect = (path, status = 302) => new Response(null, { status, headers: { Location: path } });
105
+ const site = pipeline.site ? new URL(pipeline.site) : void 0;
106
+ const url = new URL(request.url);
107
+ return {
108
+ cookies,
109
+ currentLocale,
110
+ generator,
111
+ params,
112
+ preferredLocale,
113
+ preferredLocaleList,
114
+ props,
115
+ redirect,
116
+ request,
117
+ site,
118
+ url,
119
+ get clientAddress() {
120
+ if (clientAddressSymbol in request) {
121
+ return Reflect.get(request, clientAddressSymbol);
122
+ }
123
+ if (pipeline.adapterName) {
124
+ throw new AstroError({
125
+ ...AstroErrorData.ClientAddressNotAvailable,
126
+ message: AstroErrorData.ClientAddressNotAvailable.message(pipeline.adapterName)
127
+ });
128
+ } else {
129
+ throw new AstroError(AstroErrorData.StaticClientAddressNotAvailable);
130
+ }
131
+ },
132
+ get locals() {
133
+ return renderContext.locals;
134
+ },
135
+ // TODO(breaking): disallow replacing the locals object
136
+ set locals(val) {
137
+ if (typeof val !== "object") {
138
+ throw new AstroError(AstroErrorData.LocalsNotAnObject);
139
+ } else {
140
+ renderContext.locals = val;
141
+ Reflect.set(request, clientLocalsSymbol, val);
142
+ }
143
+ }
144
+ };
145
+ }
146
+ async createResult(mod) {
147
+ const { cookies, locals, params, pathname, pipeline, request, routeData, status } = this;
148
+ const {
149
+ adapterName,
150
+ clientDirectives,
151
+ compressHTML,
152
+ i18n,
153
+ manifest,
154
+ logger,
155
+ renderers,
156
+ resolve,
157
+ site,
158
+ serverLike
159
+ } = pipeline;
160
+ const { links, scripts, styles } = await pipeline.headElements(routeData);
161
+ const componentMetadata = await pipeline.componentMetadata(routeData) ?? manifest.componentMetadata;
162
+ const { defaultLocale, locales, strategy } = i18n ?? {};
163
+ const partial = Boolean(mod.partial);
164
+ return createResult({
165
+ adapterName,
166
+ clientDirectives,
167
+ componentMetadata,
168
+ compressHTML,
169
+ cookies,
170
+ defaultLocale,
171
+ locales,
172
+ locals,
173
+ logger,
174
+ links,
175
+ params,
176
+ partial,
177
+ pathname,
178
+ renderers,
179
+ resolve,
180
+ request,
181
+ route: routeData.route,
182
+ strategy,
183
+ site,
184
+ scripts,
185
+ ssr: serverLike,
186
+ status,
187
+ styles
188
+ });
189
+ }
190
+ /**
191
+ * API Context may be created multiple times per request, i18n data needs to be computed only once.
192
+ * So, it is computed and saved here on creation of the first APIContext and reused for later ones.
193
+ */
194
+ #i18nData;
195
+ get i18nData() {
196
+ if (this.#i18nData)
197
+ return this.#i18nData;
198
+ const {
199
+ pipeline: { i18n },
200
+ request,
201
+ routeData
202
+ } = this;
203
+ if (!i18n)
204
+ return {
205
+ currentLocale: void 0,
206
+ preferredLocale: void 0,
207
+ preferredLocaleList: void 0
208
+ };
209
+ const { defaultLocale, locales, strategy } = i18n;
210
+ return this.#i18nData = {
211
+ currentLocale: computeCurrentLocale(routeData.route, locales, strategy, defaultLocale),
212
+ preferredLocale: computePreferredLocale(request, locales),
213
+ preferredLocaleList: computePreferredLocaleList(request, locales)
214
+ };
215
+ }
216
+ }
217
+ export {
218
+ RenderContext
219
+ };
@@ -1,5 +1,4 @@
1
1
  export { createRouteManifest } from './manifest/create.js';
2
2
  export { deserializeRouteData, serializeRouteData } from './manifest/serialization.js';
3
3
  export { matchAllRoutes, matchRoute } from './match.js';
4
- export { getParams } from './params.js';
5
4
  export { validateDynamicRouteModule, validateGetStaticPathsResult } from './validation.js';
@@ -1,12 +1,10 @@
1
1
  import { createRouteManifest } from "./manifest/create.js";
2
2
  import { deserializeRouteData, serializeRouteData } from "./manifest/serialization.js";
3
3
  import { matchAllRoutes, matchRoute } from "./match.js";
4
- import { getParams } from "./params.js";
5
4
  import { validateDynamicRouteModule, validateGetStaticPathsResult } from "./validation.js";
6
5
  export {
7
6
  createRouteManifest,
8
7
  deserializeRouteData,
9
- getParams,
10
8
  matchAllRoutes,
11
9
  matchRoute,
12
10
  serializeRouteData,
@@ -10,6 +10,7 @@ import { AstroError } from "../../errors/index.js";
10
10
  import { removeLeadingForwardSlash, slash } from "../../path.js";
11
11
  import { resolvePages } from "../../util.js";
12
12
  import { getRouteGenerator } from "./generator.js";
13
+ import { toRoutingStrategy } from "../../../i18n/utils.js";
13
14
  const require2 = createRequire(import.meta.url);
14
15
  function countOccurrences(needle, haystack) {
15
16
  let count = 0;
@@ -423,7 +424,8 @@ function createRouteManifest(params, logger) {
423
424
  }
424
425
  const i18n = settings.config.i18n;
425
426
  if (i18n) {
426
- if (i18n.routing === "pathname-prefix-always") {
427
+ const strategy = toRoutingStrategy(i18n);
428
+ if (strategy === "pathname-prefix-always") {
427
429
  let index = routes.find((route) => route.route === "/");
428
430
  if (!index) {
429
431
  let relativePath = path.relative(
@@ -475,7 +477,7 @@ function createRouteManifest(params, logger) {
475
477
  }
476
478
  setRoutes.delete(route);
477
479
  }
478
- if (i18n.routing === "pathname-prefix-always") {
480
+ if (strategy === "pathname-prefix-always") {
479
481
  const defaultLocaleRoutes = routesByLocale.get(i18n.defaultLocale);
480
482
  if (defaultLocaleRoutes) {
481
483
  const indexDefaultRoute = defaultLocaleRoutes.find(({ route }) => route === "/") ?? defaultLocaleRoutes.find(({ route }) => route === `/${i18n.defaultLocale}`);
@@ -523,7 +525,7 @@ function createRouteManifest(params, logger) {
523
525
  if (!hasRoute) {
524
526
  let pathname;
525
527
  let route;
526
- if (fallbackToLocale === i18n.defaultLocale && i18n.routing === "pathname-prefix-other-locales") {
528
+ if (fallbackToLocale === i18n.defaultLocale && strategy === "pathname-prefix-other-locales") {
527
529
  if (fallbackToRoute.pathname) {
528
530
  pathname = `/${fallbackFromLocale}${fallbackToRoute.pathname}`;
529
531
  }
@@ -1,10 +1,4 @@
1
- import type { GetStaticPathsItem, Params, RouteData } from '../../@types/astro.js';
2
- /**
3
- * given an array of params like `['x', 'y', 'z']` for
4
- * src/routes/[x]/[y]/[z]/svelte, create a function
5
- * that turns a RegExpExecArray into ({ x, y, z })
6
- */
7
- export declare function getParams(array: string[]): (match: RegExpExecArray) => Params;
1
+ import type { GetStaticPathsItem, RouteData } from '../../@types/astro.js';
8
2
  /**
9
3
  * given a route's Params object, validate parameter
10
4
  * values and create a stringified key for the route