astro 3.4.4 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/client.d.ts +86 -0
  2. package/components/Code.astro +15 -2
  3. package/components/Picture.astro +2 -1
  4. package/components/ViewTransitions.astro +39 -38
  5. package/content-module.template.mjs +4 -14
  6. package/dist/@types/astro.d.ts +222 -5
  7. package/dist/assets/build/generate.d.ts +2 -1
  8. package/dist/assets/build/generate.js +16 -5
  9. package/dist/assets/consts.d.ts +1 -0
  10. package/dist/assets/consts.js +2 -0
  11. package/dist/assets/endpoint/generic.js +6 -2
  12. package/dist/assets/internal.js +9 -2
  13. package/dist/assets/services/service.d.ts +8 -3
  14. package/dist/assets/services/service.js +2 -1
  15. package/dist/assets/services/vendor/squoosh/image-pool.d.ts +1 -2
  16. package/dist/assets/types.d.ts +9 -5
  17. package/dist/assets/utils/emitAsset.js +5 -0
  18. package/dist/assets/utils/metadata.d.ts +1 -2
  19. package/dist/assets/utils/proxy.d.ts +1 -0
  20. package/dist/assets/utils/proxy.js +16 -0
  21. package/dist/assets/utils/queryParams.d.ts +1 -1
  22. package/dist/assets/utils/transformToPath.d.ts +1 -1
  23. package/dist/assets/utils/transformToPath.js +8 -3
  24. package/dist/assets/vite-plugin-assets.js +26 -11
  25. package/dist/cli/build/index.js +1 -1
  26. package/dist/content/consts.d.ts +1 -0
  27. package/dist/content/consts.js +2 -0
  28. package/dist/content/runtime-assets.d.ts +9 -1
  29. package/dist/content/runtime-assets.js +1 -1
  30. package/dist/content/runtime.d.ts +1 -0
  31. package/dist/content/runtime.js +8 -2
  32. package/dist/content/utils.d.ts +1 -0
  33. package/dist/content/utils.js +9 -0
  34. package/dist/content/vite-plugin-content-assets.js +49 -23
  35. package/dist/content/vite-plugin-content-imports.js +9 -3
  36. package/dist/content/vite-plugin-content-virtual-mod.d.ts +17 -12
  37. package/dist/content/vite-plugin-content-virtual-mod.js +136 -57
  38. package/dist/core/app/index.js +19 -4
  39. package/dist/core/app/types.d.ts +7 -1
  40. package/dist/core/build/buildPipeline.js +17 -4
  41. package/dist/core/build/common.js +2 -0
  42. package/dist/core/build/generate.js +64 -34
  43. package/dist/core/build/index.d.ts +0 -8
  44. package/dist/core/build/index.js +9 -2
  45. package/dist/core/build/internal.d.ts +11 -1
  46. package/dist/core/build/internal.js +23 -1
  47. package/dist/core/build/page-data.js +46 -18
  48. package/dist/core/build/plugin.d.ts +12 -10
  49. package/dist/core/build/plugin.js +14 -22
  50. package/dist/core/build/plugins/index.js +4 -0
  51. package/dist/core/build/plugins/plugin-alias-resolve.js +1 -1
  52. package/dist/core/build/plugins/plugin-analyzer.js +1 -1
  53. package/dist/core/build/plugins/plugin-chunks.d.ts +4 -0
  54. package/dist/core/build/plugins/plugin-chunks.js +31 -0
  55. package/dist/core/build/plugins/plugin-component-entry.js +1 -1
  56. package/dist/core/build/plugins/plugin-content.d.ts +4 -0
  57. package/dist/core/build/plugins/plugin-content.js +273 -0
  58. package/dist/core/build/plugins/plugin-css.js +9 -4
  59. package/dist/core/build/plugins/plugin-hoisted-scripts.js +1 -1
  60. package/dist/core/build/plugins/plugin-internals.js +1 -1
  61. package/dist/core/build/plugins/plugin-manifest.js +14 -5
  62. package/dist/core/build/plugins/plugin-middleware.d.ts +1 -3
  63. package/dist/core/build/plugins/plugin-middleware.js +5 -57
  64. package/dist/core/build/plugins/plugin-pages.js +3 -3
  65. package/dist/core/build/plugins/plugin-prerender.js +2 -5
  66. package/dist/core/build/plugins/plugin-renderers.js +1 -1
  67. package/dist/core/build/plugins/plugin-ssr.js +6 -5
  68. package/dist/core/build/plugins/util.d.ts +3 -3
  69. package/dist/core/build/static-build.d.ts +2 -1
  70. package/dist/core/build/static-build.js +52 -28
  71. package/dist/core/build/types.d.ts +1 -1
  72. package/dist/core/build/util.d.ts +7 -0
  73. package/dist/core/build/util.js +37 -1
  74. package/dist/core/compile/compile.js +1 -0
  75. package/dist/core/config/config.js +3 -0
  76. package/dist/core/config/schema.d.ts +208 -0
  77. package/dist/core/config/schema.js +55 -2
  78. package/dist/core/config/settings.js +1 -0
  79. package/dist/core/constants.js +1 -1
  80. package/dist/core/create-vite.js +9 -3
  81. package/dist/core/dev/dev.js +1 -1
  82. package/dist/core/endpoint/index.d.ts +4 -3
  83. package/dist/core/endpoint/index.js +29 -3
  84. package/dist/core/errors/errors-data.d.ts +11 -0
  85. package/dist/core/errors/errors-data.js +17 -0
  86. package/dist/core/messages.js +2 -2
  87. package/dist/core/middleware/index.d.ts +7 -3
  88. package/dist/core/middleware/index.js +3 -2
  89. package/dist/core/middleware/loadMiddleware.d.ts +1 -2
  90. package/dist/core/middleware/loadMiddleware.js +3 -4
  91. package/dist/core/middleware/sequence.d.ts +2 -2
  92. package/dist/core/middleware/sequence.js +3 -2
  93. package/dist/core/middleware/vite-plugin.d.ts +9 -0
  94. package/dist/core/middleware/vite-plugin.js +101 -0
  95. package/dist/core/pipeline.d.ts +1 -1
  96. package/dist/core/pipeline.js +6 -4
  97. package/dist/core/redirects/helpers.d.ts +1 -0
  98. package/dist/core/redirects/helpers.js +4 -0
  99. package/dist/core/render/context.d.ts +24 -1
  100. package/dist/core/render/context.js +96 -2
  101. package/dist/core/render/core.d.ts +2 -14
  102. package/dist/core/render/core.js +12 -52
  103. package/dist/core/render/index.d.ts +2 -3
  104. package/dist/core/render/index.js +3 -4
  105. package/dist/core/render/params-and-props.d.ts +1 -1
  106. package/dist/core/render/params-and-props.js +5 -2
  107. package/dist/core/render/result.d.ts +1 -0
  108. package/dist/core/render/result.js +23 -0
  109. package/dist/core/render/route-cache.d.ts +1 -1
  110. package/dist/core/render/route-cache.js +17 -11
  111. package/dist/core/routing/manifest/create.js +118 -4
  112. package/dist/core/sync/index.d.ts +2 -24
  113. package/dist/i18n/index.d.ts +54 -0
  114. package/dist/i18n/index.js +91 -0
  115. package/dist/i18n/middleware.d.ts +2 -0
  116. package/dist/i18n/middleware.js +62 -0
  117. package/dist/i18n/vite-plugin-i18n.d.ts +7 -0
  118. package/dist/i18n/vite-plugin-i18n.js +62 -0
  119. package/dist/integrations/astroFeaturesValidation.js +4 -1
  120. package/dist/integrations/index.js +12 -0
  121. package/dist/prefetch/index.d.ts +31 -0
  122. package/dist/prefetch/index.js +176 -0
  123. package/dist/prefetch/vite-plugin-prefetch.d.ts +5 -0
  124. package/dist/prefetch/vite-plugin-prefetch.js +43 -0
  125. package/dist/runtime/client/dev-overlay/plugins/audit.js +17 -9
  126. package/dist/runtime/server/index.d.ts +0 -2
  127. package/dist/runtime/server/render/component.js +3 -5
  128. package/dist/transitions/router.d.ts +1 -0
  129. package/dist/transitions/router.js +9 -4
  130. package/dist/transitions/vite-plugin-transitions.d.ts +4 -1
  131. package/dist/transitions/vite-plugin-transitions.js +7 -1
  132. package/dist/vite-plugin-astro-server/devPipeline.d.ts +1 -0
  133. package/dist/vite-plugin-astro-server/devPipeline.js +2 -0
  134. package/dist/vite-plugin-astro-server/plugin.js +11 -1
  135. package/dist/vite-plugin-astro-server/route.js +113 -51
  136. package/dist/vite-plugin-head/index.js +1 -1
  137. package/dist/vite-plugin-markdown/index.js +1 -0
  138. package/package.json +7 -5
  139. package/tsconfigs/base.json +1 -1
  140. package/dist/core/endpoint/dev/index.d.ts +0 -2
  141. package/dist/core/endpoint/dev/index.js +0 -17
@@ -4,6 +4,8 @@ import { ASTRO_VERSION } from "../constants.js";
4
4
  import { AstroCookies, attachCookiesToResponse } from "../cookies/index.js";
5
5
  import { AstroError, AstroErrorData } from "../errors/index.js";
6
6
  import { callMiddleware } from "../middleware/callMiddleware.js";
7
+ import { computePreferredLocale, computePreferredLocaleList } from "../render/context.js";
8
+ import {} from "../render/index.js";
7
9
  const encoder = new TextEncoder();
8
10
  const clientAddressSymbol = Symbol.for("astro.clientAddress");
9
11
  const clientLocalsSymbol = Symbol.for("astro.locals");
@@ -12,8 +14,11 @@ function createAPIContext({
12
14
  params,
13
15
  site,
14
16
  props,
15
- adapterName
17
+ adapterName,
18
+ locales
16
19
  }) {
20
+ let preferredLocale = void 0;
21
+ let preferredLocaleList = void 0;
17
22
  const context = {
18
23
  cookies: new AstroCookies(request),
19
24
  request,
@@ -30,6 +35,26 @@ function createAPIContext({
30
35
  });
31
36
  },
32
37
  ResponseWithEncoding,
38
+ get preferredLocale() {
39
+ if (preferredLocale) {
40
+ return preferredLocale;
41
+ }
42
+ if (locales) {
43
+ preferredLocale = computePreferredLocale(request, locales);
44
+ return preferredLocale;
45
+ }
46
+ return void 0;
47
+ },
48
+ get preferredLocaleList() {
49
+ if (preferredLocaleList) {
50
+ return preferredLocaleList;
51
+ }
52
+ if (locales) {
53
+ preferredLocaleList = computePreferredLocaleList(request, locales);
54
+ return preferredLocaleList;
55
+ }
56
+ return void 0;
57
+ },
33
58
  url: new URL(request.url),
34
59
  get clientAddress() {
35
60
  if (clientAddressSymbol in request) {
@@ -81,13 +106,14 @@ class ResponseWithEncoding extends Response {
81
106
  }
82
107
  }
83
108
  }
84
- async function callEndpoint(mod, env, ctx, onRequest) {
109
+ async function callEndpoint(mod, env, ctx, onRequest, locales) {
85
110
  const context = createAPIContext({
86
111
  request: ctx.request,
87
112
  params: ctx.params,
88
113
  props: ctx.props,
89
114
  site: env.site,
90
- adapterName: env.adapterName
115
+ adapterName: env.adapterName,
116
+ locales
91
117
  });
92
118
  let response;
93
119
  if (onRequest) {
@@ -1139,6 +1139,17 @@ export declare const UnsupportedConfigTransformError: {
1139
1139
  message: (parseError: string) => string;
1140
1140
  hint: string;
1141
1141
  };
1142
+ export declare const MissingLocale: {
1143
+ name: string;
1144
+ title: string;
1145
+ message: (locale: string, locales: string[]) => string;
1146
+ };
1147
+ export declare const CantRenderPage: {
1148
+ name: string;
1149
+ title: string;
1150
+ message: string;
1151
+ hint: string;
1152
+ };
1142
1153
  export declare const UnknownError: {
1143
1154
  name: string;
1144
1155
  title: string;
@@ -426,11 +426,27 @@ const UnsupportedConfigTransformError = {
426
426
  Full error: ${parseError}`,
427
427
  hint: "See the devalue library for all supported types: https://github.com/rich-harris/devalue"
428
428
  };
429
+ const MissingLocale = {
430
+ name: "MissingLocaleError",
431
+ title: "The provided locale does not exist.",
432
+ message: (locale, locales) => {
433
+ return `The locale \`${locale}\` does not exist in the configured locales. Available locales: ${locales.join(
434
+ ", "
435
+ )}.`;
436
+ }
437
+ };
438
+ const CantRenderPage = {
439
+ name: "CantRenderPage",
440
+ title: "Astro can't render the route.",
441
+ message: "Astro cannot find any content to render for this route. There is no file or redirect associated with this route.",
442
+ hint: "If you expect to find a route here, this may be an Astro bug. Please file an issue/restart the dev server"
443
+ };
429
444
  const UnknownError = { name: "UnknownError", title: "Unknown Error." };
430
445
  export {
431
446
  AstroGlobNoMatch,
432
447
  AstroGlobUsedOutside,
433
448
  CSSSyntaxError,
449
+ CantRenderPage,
434
450
  ClientAddressNotAvailable,
435
451
  CollectionDoesNotExistError,
436
452
  ConfigLegacyKey,
@@ -470,6 +486,7 @@ export {
470
486
  MiddlewareNoDataOrNextCalled,
471
487
  MiddlewareNotAResponse,
472
488
  MissingImageDimension,
489
+ MissingLocale,
473
490
  MissingMediaQueryDirective,
474
491
  MissingSharp,
475
492
  MixedContentDataCollectionError,
@@ -50,7 +50,7 @@ function serverStart({
50
50
  base,
51
51
  isRestart = false
52
52
  }) {
53
- const version = "3.4.4";
53
+ const version = "3.5.0";
54
54
  const localPrefix = `${dim("\u2503")} Local `;
55
55
  const networkPrefix = `${dim("\u2503")} Network `;
56
56
  const emptyPrefix = " ".repeat(11);
@@ -235,7 +235,7 @@ function printHelp({
235
235
  message.push(
236
236
  linebreak(),
237
237
  ` ${bgGreen(black(` ${commandName} `))} ${green(
238
- `v${"3.4.4"}`
238
+ `v${"3.5.0"}`
239
239
  )} ${headline}`
240
240
  );
241
241
  }
@@ -1,6 +1,6 @@
1
- import type { MiddlewareResponseHandler, Params } from '../../@types/astro.js';
1
+ import type { MiddlewareEndpointHandler, Params } from '../../@types/astro.js';
2
2
  import { sequence } from './sequence.js';
3
- declare function defineMiddleware(fn: MiddlewareResponseHandler): MiddlewareResponseHandler;
3
+ declare function defineMiddleware(fn: MiddlewareEndpointHandler): MiddlewareEndpointHandler;
4
4
  /**
5
5
  * Payload for creating a context to be passed to Astro middleware
6
6
  */
@@ -13,11 +13,15 @@ export type CreateContext = {
13
13
  * Optional parameters
14
14
  */
15
15
  params?: Params;
16
+ /**
17
+ * A list of locales that are supported by the user
18
+ */
19
+ userDefinedLocales?: string[];
16
20
  };
17
21
  /**
18
22
  * Creates a context to be passed to Astro middleware `onRequest` function.
19
23
  */
20
- declare function createContext({ request, params }: CreateContext): import("../../@types/astro.js").APIContext<Record<string, any>, Record<string, string | undefined>>;
24
+ declare function createContext({ request, params, userDefinedLocales }: CreateContext): import("../../@types/astro.js").APIContext<Record<string, any>, Record<string, string | undefined>>;
21
25
  /**
22
26
  * It attempts to serialize `value` and return it as a string.
23
27
  *
@@ -3,12 +3,13 @@ import { sequence } from "./sequence.js";
3
3
  function defineMiddleware(fn) {
4
4
  return fn;
5
5
  }
6
- function createContext({ request, params }) {
6
+ function createContext({ request, params, userDefinedLocales = [] }) {
7
7
  return createAPIContext({
8
8
  request,
9
9
  params: params ?? {},
10
10
  props: {},
11
- site: void 0
11
+ site: void 0,
12
+ locales: userDefinedLocales
12
13
  });
13
14
  }
14
15
  function isLocalsSerializable(value) {
@@ -1,8 +1,7 @@
1
- import type { AstroSettings } from '../../@types/astro.js';
2
1
  import type { ModuleLoader } from '../module-loader/index.js';
3
2
  /**
4
3
  * It accepts a module loader and the astro settings, and it attempts to load the middlewares defined in the configuration.
5
4
  *
6
5
  * If not middlewares were not set, the function returns an empty array.
7
6
  */
8
- export declare function loadMiddleware(moduleLoader: ModuleLoader, srcDir: AstroSettings['config']['srcDir']): Promise<Record<string, any> | undefined>;
7
+ export declare function loadMiddleware(moduleLoader: ModuleLoader): Promise<Record<string, any> | undefined>;
@@ -1,8 +1,7 @@
1
- import { MIDDLEWARE_PATH_SEGMENT_NAME } from "../constants.js";
2
- async function loadMiddleware(moduleLoader, srcDir) {
3
- let middlewarePath = `${decodeURI(srcDir.pathname)}${MIDDLEWARE_PATH_SEGMENT_NAME}`;
1
+ import { MIDDLEWARE_MODULE_ID } from "./vite-plugin.js";
2
+ async function loadMiddleware(moduleLoader) {
4
3
  try {
5
- const module = await moduleLoader.import(middlewarePath);
4
+ const module = await moduleLoader.import(MIDDLEWARE_MODULE_ID);
6
5
  return module;
7
6
  } catch {
8
7
  return void 0;
@@ -1,6 +1,6 @@
1
- import type { MiddlewareResponseHandler } from '../../@types/astro.js';
1
+ import type { MiddlewareEndpointHandler } from '../../@types/astro.js';
2
2
  /**
3
3
  *
4
4
  * It accepts one or more middleware handlers and makes sure that they are run in sequence.
5
5
  */
6
- export declare function sequence(...handlers: MiddlewareResponseHandler[]): MiddlewareResponseHandler;
6
+ export declare function sequence(...handlers: MiddlewareEndpointHandler[]): MiddlewareEndpointHandler;
@@ -1,6 +1,7 @@
1
1
  import { defineMiddleware } from "./index.js";
2
2
  function sequence(...handlers) {
3
- const length = handlers.length;
3
+ const filtered = handlers.filter((h) => !!h);
4
+ const length = filtered.length;
4
5
  if (!length) {
5
6
  const handler = defineMiddleware((context, next) => {
6
7
  return next();
@@ -10,7 +11,7 @@ function sequence(...handlers) {
10
11
  return defineMiddleware((context, next) => {
11
12
  return applyHandle(0, context);
12
13
  function applyHandle(i, handleContext) {
13
- const handle = handlers[i];
14
+ const handle = filtered[i];
14
15
  const result = handle(handleContext, async () => {
15
16
  if (i < length - 1) {
16
17
  return applyHandle(i + 1, handleContext);
@@ -0,0 +1,9 @@
1
+ import type { Plugin as VitePlugin } from 'vite';
2
+ import type { AstroSettings } from '../../@types/astro.js';
3
+ import type { BuildInternals } from '../build/internal.js';
4
+ import type { StaticBuildOptions } from '../build/types.js';
5
+ export declare const MIDDLEWARE_MODULE_ID = "@astro-middleware";
6
+ export declare function vitePluginMiddleware({ settings }: {
7
+ settings: AstroSettings;
8
+ }): VitePlugin;
9
+ export declare function vitePluginMiddlewareBuild(opts: StaticBuildOptions, internals: BuildInternals): VitePlugin;
@@ -0,0 +1,101 @@
1
+ import { normalizePath } from "vite";
2
+ import { getOutputDirectory } from "../../prerender/utils.js";
3
+ import { addRollupInput } from "../build/add-rollup-input.js";
4
+ import { MIDDLEWARE_PATH_SEGMENT_NAME } from "../constants.js";
5
+ const MIDDLEWARE_MODULE_ID = "@astro-middleware";
6
+ const EMPTY_MIDDLEWARE = "\0empty-middleware";
7
+ function vitePluginMiddleware({ settings }) {
8
+ let isCommandBuild = false;
9
+ let resolvedMiddlewareId = void 0;
10
+ const hasIntegrationMiddleware = settings.middlewares.pre.length > 0 || settings.middlewares.post.length > 0;
11
+ return {
12
+ name: "@astro/plugin-middleware",
13
+ config(opts, { command }) {
14
+ isCommandBuild = command === "build";
15
+ return opts;
16
+ },
17
+ async resolveId(id) {
18
+ if (id === MIDDLEWARE_MODULE_ID) {
19
+ const middlewareId = await this.resolve(
20
+ `${decodeURI(settings.config.srcDir.pathname)}${MIDDLEWARE_PATH_SEGMENT_NAME}`
21
+ );
22
+ if (middlewareId) {
23
+ resolvedMiddlewareId = middlewareId.id;
24
+ return MIDDLEWARE_MODULE_ID;
25
+ } else if (hasIntegrationMiddleware) {
26
+ return MIDDLEWARE_MODULE_ID;
27
+ } else {
28
+ return EMPTY_MIDDLEWARE;
29
+ }
30
+ }
31
+ if (id === EMPTY_MIDDLEWARE) {
32
+ return EMPTY_MIDDLEWARE;
33
+ }
34
+ },
35
+ async load(id) {
36
+ if (id === EMPTY_MIDDLEWARE) {
37
+ return "export const onRequest = undefined";
38
+ } else if (id === MIDDLEWARE_MODULE_ID) {
39
+ if (isCommandBuild) {
40
+ this.emitFile({
41
+ type: "chunk",
42
+ preserveSignature: "strict",
43
+ fileName: "middleware.mjs",
44
+ id
45
+ });
46
+ }
47
+ const preMiddleware = createMiddlewareImports(settings.middlewares.pre, "pre");
48
+ const postMiddleware = createMiddlewareImports(settings.middlewares.post, "post");
49
+ const source = `
50
+ import { onRequest as userOnRequest } from '${resolvedMiddlewareId}';
51
+ import { sequence } from 'astro:middleware';
52
+ ${preMiddleware.importsCode}${postMiddleware.importsCode}
53
+
54
+ export const onRequest = sequence(
55
+ ${preMiddleware.sequenceCode}${preMiddleware.sequenceCode ? "," : ""}
56
+ userOnRequest${postMiddleware.sequenceCode ? "," : ""}
57
+ ${postMiddleware.sequenceCode}
58
+ );
59
+ `.trim();
60
+ return source;
61
+ }
62
+ }
63
+ };
64
+ }
65
+ function createMiddlewareImports(entrypoints, prefix) {
66
+ let importsRaw = "";
67
+ let sequenceRaw = "";
68
+ let index = 0;
69
+ for (const entrypoint of entrypoints) {
70
+ const name = `_${prefix}_${index}`;
71
+ importsRaw += `import { onRequest as ${name} } from '${normalizePath(entrypoint)}';
72
+ `;
73
+ sequenceRaw += `${index > 0 ? "," : ""}${name}`;
74
+ index++;
75
+ }
76
+ return {
77
+ importsCode: importsRaw,
78
+ sequenceCode: sequenceRaw
79
+ };
80
+ }
81
+ function vitePluginMiddlewareBuild(opts, internals) {
82
+ return {
83
+ name: "@astro/plugin-middleware-build",
84
+ options(options) {
85
+ return addRollupInput(options, [MIDDLEWARE_MODULE_ID]);
86
+ },
87
+ writeBundle(_, bundle) {
88
+ for (const [chunkName, chunk] of Object.entries(bundle)) {
89
+ if (chunk.type !== "asset" && chunk.fileName === "middleware.mjs") {
90
+ const outputDirectory = getOutputDirectory(opts.settings.config);
91
+ internals.middlewareEntryPoint = new URL(chunkName, outputDirectory);
92
+ }
93
+ }
94
+ }
95
+ };
96
+ }
97
+ export {
98
+ MIDDLEWARE_MODULE_ID,
99
+ vitePluginMiddleware,
100
+ vitePluginMiddlewareBuild
101
+ };
@@ -36,6 +36,6 @@ export declare class Pipeline {
36
36
  /**
37
37
  * The main function of the pipeline. Use this function to render any route known to Astro;
38
38
  */
39
- renderRoute(renderContext: RenderContext, componentInstance: ComponentInstance): Promise<Response>;
39
+ renderRoute(renderContext: RenderContext, componentInstance: ComponentInstance | undefined): Promise<Response>;
40
40
  }
41
41
  export {};
@@ -82,10 +82,12 @@ class Pipeline {
82
82
  params: renderContext.params,
83
83
  props: renderContext.props,
84
84
  site: env.site,
85
- adapterName: env.adapterName
85
+ adapterName: env.adapterName,
86
+ locales: renderContext.locales
86
87
  });
87
88
  switch (renderContext.route.type) {
88
89
  case "page":
90
+ case "fallback":
89
91
  case "redirect": {
90
92
  if (onRequest) {
91
93
  return await callMiddleware(
@@ -111,13 +113,13 @@ class Pipeline {
111
113
  }
112
114
  }
113
115
  case "endpoint": {
114
- const result = await callEndpoint(
116
+ return await callEndpoint(
115
117
  mod,
116
118
  env,
117
119
  renderContext,
118
- onRequest
120
+ onRequest,
121
+ renderContext.locales
119
122
  );
120
- return result;
121
123
  }
122
124
  default:
123
125
  throw new Error(`Couldn't find route of type [${renderContext.route.type}]`);
@@ -1,4 +1,5 @@
1
1
  import type { Params, RedirectRouteData, RouteData, ValidRedirectStatus } from '../../@types/astro.js';
2
2
  export declare function routeIsRedirect(route: RouteData | undefined): route is RedirectRouteData;
3
+ export declare function routeIsFallback(route: RouteData | undefined): route is RedirectRouteData;
3
4
  export declare function redirectRouteGenerate(redirectRoute: RouteData, data: Params): string;
4
5
  export declare function redirectRouteStatus(redirectRoute: RouteData, method?: string): ValidRedirectStatus;
@@ -1,6 +1,9 @@
1
1
  function routeIsRedirect(route) {
2
2
  return route?.type === "redirect";
3
3
  }
4
+ function routeIsFallback(route) {
5
+ return route?.type === "fallback";
6
+ }
4
7
  function redirectRouteGenerate(redirectRoute, data) {
5
8
  const routeData = redirectRoute.redirectRoute;
6
9
  const route = redirectRoute.redirect;
@@ -25,5 +28,6 @@ function redirectRouteStatus(redirectRoute, method = "GET") {
25
28
  export {
26
29
  redirectRouteGenerate,
27
30
  redirectRouteStatus,
31
+ routeIsFallback,
28
32
  routeIsRedirect
29
33
  };
@@ -15,11 +15,34 @@ export interface RenderContext {
15
15
  params: Params;
16
16
  props: Props;
17
17
  locals?: object;
18
+ locales: string[] | undefined;
18
19
  }
19
20
  export type CreateRenderContextArgs = Partial<Omit<RenderContext, 'params' | 'props' | 'locals'>> & {
20
21
  route: RouteData;
21
22
  request: RenderContext['request'];
22
- mod: ComponentInstance;
23
+ mod: ComponentInstance | undefined;
23
24
  env: Environment;
24
25
  };
25
26
  export declare function createRenderContext(options: CreateRenderContextArgs): Promise<RenderContext>;
27
+ type BrowserLocale = {
28
+ locale: string;
29
+ qualityValue: number | undefined;
30
+ };
31
+ /**
32
+ * Parses the value of the `Accept-Header` language:
33
+ *
34
+ * More info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language
35
+ *
36
+ * Complex example: `fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5`
37
+ *
38
+ */
39
+ export declare function parseLocale(header: string): BrowserLocale[];
40
+ /**
41
+ * Set the current locale by parsing the value passed from the `Accept-Header`.
42
+ *
43
+ * If multiple locales are present in the header, they are sorted by their quality value and the highest is selected as current locale.
44
+ *
45
+ */
46
+ export declare function computePreferredLocale(request: Request, locales: string[]): string | undefined;
47
+ export declare function computePreferredLocaleList(request: Request, locales: string[]): string[];
48
+ export {};
@@ -1,3 +1,4 @@
1
+ import { normalizeTheLocale } from "../../i18n/index.js";
1
2
  import { AstroError, AstroErrorData } from "../errors/index.js";
2
3
  import { getParamsAndProps } from "./params-and-props.js";
3
4
  const clientLocalsSymbol = Symbol.for("astro.locals");
@@ -16,7 +17,8 @@ async function createRenderContext(options) {
16
17
  ...options,
17
18
  pathname,
18
19
  params,
19
- props
20
+ props,
21
+ locales: options.locales
20
22
  };
21
23
  Object.defineProperty(context, "locals", {
22
24
  enumerable: true,
@@ -33,6 +35,98 @@ async function createRenderContext(options) {
33
35
  });
34
36
  return context;
35
37
  }
38
+ function parseLocale(header) {
39
+ if (header === "*") {
40
+ return [{ locale: header, qualityValue: void 0 }];
41
+ }
42
+ const result = [];
43
+ const localeValues = header.split(",").map((str) => str.trim());
44
+ for (const localeValue of localeValues) {
45
+ const split = localeValue.split(";").map((str) => str.trim());
46
+ const localeName = split[0];
47
+ const qualityValue = split[1];
48
+ if (!split) {
49
+ continue;
50
+ }
51
+ if (qualityValue && qualityValue.startsWith("q=")) {
52
+ const qualityValueAsFloat = Number.parseFloat(qualityValue.slice("q=".length));
53
+ if (Number.isNaN(qualityValueAsFloat) || qualityValueAsFloat > 1) {
54
+ result.push({
55
+ locale: localeName,
56
+ qualityValue: void 0
57
+ });
58
+ } else {
59
+ result.push({
60
+ locale: localeName,
61
+ qualityValue: qualityValueAsFloat
62
+ });
63
+ }
64
+ } else {
65
+ result.push({
66
+ locale: localeName,
67
+ qualityValue: void 0
68
+ });
69
+ }
70
+ }
71
+ return result;
72
+ }
73
+ function sortAndFilterLocales(browserLocaleList, locales) {
74
+ const normalizedLocales = locales.map(normalizeTheLocale);
75
+ return browserLocaleList.filter((browserLocale) => {
76
+ if (browserLocale.locale !== "*") {
77
+ return normalizedLocales.includes(normalizeTheLocale(browserLocale.locale));
78
+ }
79
+ return true;
80
+ }).sort((a, b) => {
81
+ if (a.qualityValue && b.qualityValue) {
82
+ if (a.qualityValue > b.qualityValue) {
83
+ return -1;
84
+ } else if (a.qualityValue < b.qualityValue) {
85
+ return 1;
86
+ }
87
+ }
88
+ return 0;
89
+ });
90
+ }
91
+ function computePreferredLocale(request, locales) {
92
+ const acceptHeader = request.headers.get("Accept-Language");
93
+ let result = void 0;
94
+ if (acceptHeader) {
95
+ const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales);
96
+ const firstResult = browserLocaleList.at(0);
97
+ if (firstResult) {
98
+ if (firstResult.locale !== "*") {
99
+ result = locales.find(
100
+ (locale) => normalizeTheLocale(locale) === normalizeTheLocale(firstResult.locale)
101
+ );
102
+ }
103
+ }
104
+ }
105
+ return result;
106
+ }
107
+ function computePreferredLocaleList(request, locales) {
108
+ const acceptHeader = request.headers.get("Accept-Language");
109
+ let result = [];
110
+ if (acceptHeader) {
111
+ const browserLocaleList = sortAndFilterLocales(parseLocale(acceptHeader), locales);
112
+ if (browserLocaleList.length === 1 && browserLocaleList.at(0).locale === "*") {
113
+ return locales;
114
+ } else if (browserLocaleList.length > 0) {
115
+ for (const browserLocale of browserLocaleList) {
116
+ const found = locales.find(
117
+ (l) => normalizeTheLocale(l) === normalizeTheLocale(browserLocale.locale)
118
+ );
119
+ if (found) {
120
+ result.push(found);
121
+ }
122
+ }
123
+ }
124
+ }
125
+ return result;
126
+ }
36
127
  export {
37
- createRenderContext
128
+ computePreferredLocale,
129
+ computePreferredLocaleList,
130
+ createRenderContext,
131
+ parseLocale
38
132
  };
@@ -1,22 +1,10 @@
1
- import type { AstroCookies, ComponentInstance, MiddlewareHandler } from '../../@types/astro.js';
1
+ import type { AstroCookies, ComponentInstance } from '../../@types/astro.js';
2
2
  import type { RenderContext } from './context.js';
3
3
  import type { Environment } from './environment.js';
4
4
  export type RenderPage = {
5
- mod: ComponentInstance;
5
+ mod: ComponentInstance | undefined;
6
6
  renderContext: RenderContext;
7
7
  env: Environment;
8
8
  cookies: AstroCookies;
9
9
  };
10
10
  export declare function renderPage({ mod, renderContext, env, cookies }: RenderPage): Promise<Response>;
11
- /**
12
- * It attempts to render a route. A route can be a:
13
- * - page
14
- * - redirect
15
- * - endpoint
16
- *
17
- * ## Errors
18
- *
19
- * It throws an error if the page can't be rendered.
20
- * @deprecated Use the pipeline instead
21
- */
22
- export declare function tryRenderRoute<MiddlewareReturnType = Response>(renderContext: Readonly<RenderContext>, env: Readonly<Environment>, mod: Readonly<ComponentInstance>, onRequest?: MiddlewareHandler<MiddlewareReturnType>): Promise<Response>;
@@ -1,7 +1,8 @@
1
1
  import { renderPage as runtimeRenderPage } from "../../runtime/server/index.js";
2
2
  import { attachCookiesToResponse } from "../cookies/index.js";
3
- import { callEndpoint, createAPIContext } from "../endpoint/index.js";
4
- import { callMiddleware } from "../middleware/callMiddleware.js";
3
+ import { CantRenderPage } from "../errors/errors-data.js";
4
+ import { AstroError } from "../errors/index.js";
5
+ import { routeIsFallback } from "../redirects/helpers.js";
5
6
  import { redirectRouteGenerate, redirectRouteStatus, routeIsRedirect } from "../redirects/index.js";
6
7
  import { createResult } from "./result.js";
7
8
  async function renderPage({ mod, renderContext, env, cookies }) {
@@ -12,6 +13,12 @@ async function renderPage({ mod, renderContext, env, cookies }) {
12
13
  location: redirectRouteGenerate(renderContext.route, renderContext.params)
13
14
  }
14
15
  });
16
+ } else if (routeIsFallback(renderContext.route)) {
17
+ return new Response(null, {
18
+ status: 404
19
+ });
20
+ } else if (!mod) {
21
+ throw new AstroError(CantRenderPage);
15
22
  }
16
23
  const Component = mod.default;
17
24
  if (!Component)
@@ -35,7 +42,8 @@ async function renderPage({ mod, renderContext, env, cookies }) {
35
42
  ssr: env.ssr,
36
43
  status: renderContext.status ?? 200,
37
44
  cookies,
38
- locals: renderContext.locals ?? {}
45
+ locals: renderContext.locals ?? {},
46
+ locales: renderContext.locales
39
47
  });
40
48
  if (mod.frontmatter && typeof mod.frontmatter === "object" && "draft" in mod.frontmatter) {
41
49
  env.logger.warn(
@@ -56,54 +64,6 @@ async function renderPage({ mod, renderContext, env, cookies }) {
56
64
  }
57
65
  return response;
58
66
  }
59
- async function tryRenderRoute(renderContext, env, mod, onRequest) {
60
- const apiContext = createAPIContext({
61
- request: renderContext.request,
62
- params: renderContext.params,
63
- props: renderContext.props,
64
- site: env.site,
65
- adapterName: env.adapterName
66
- });
67
- switch (renderContext.route.type) {
68
- case "page":
69
- case "redirect": {
70
- if (onRequest) {
71
- return await callMiddleware(
72
- env.logger,
73
- onRequest,
74
- apiContext,
75
- () => {
76
- return renderPage({
77
- mod,
78
- renderContext,
79
- env,
80
- cookies: apiContext.cookies
81
- });
82
- }
83
- );
84
- } else {
85
- return await renderPage({
86
- mod,
87
- renderContext,
88
- env,
89
- cookies: apiContext.cookies
90
- });
91
- }
92
- }
93
- case "endpoint": {
94
- const result = await callEndpoint(
95
- mod,
96
- env,
97
- renderContext,
98
- onRequest
99
- );
100
- return result;
101
- }
102
- default:
103
- throw new Error(`Couldn't find route of type [${renderContext.route.type}]`);
104
- }
105
- }
106
67
  export {
107
- renderPage,
108
- tryRenderRoute
68
+ renderPage
109
69
  };