astro 4.5.18 → 4.6.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 (54) hide show
  1. package/dist/@types/astro.d.ts +96 -3
  2. package/dist/core/app/index.js +8 -0
  3. package/dist/core/app/middlewares.d.ts +7 -0
  4. package/dist/core/app/middlewares.js +26 -0
  5. package/dist/core/app/types.d.ts +2 -1
  6. package/dist/core/base-pipeline.js +6 -3
  7. package/dist/core/build/generate.js +3 -2
  8. package/dist/core/build/plugins/plugin-manifest.js +3 -2
  9. package/dist/core/config/schema.d.ts +168 -65
  10. package/dist/core/config/schema.js +20 -13
  11. package/dist/core/constants.js +1 -1
  12. package/dist/core/cookies/cookies.d.ts +3 -11
  13. package/dist/core/cookies/cookies.js +9 -7
  14. package/dist/core/dev/dev.js +1 -1
  15. package/dist/core/errors/dev/utils.js +1 -1
  16. package/dist/core/errors/errors-data.d.ts +23 -0
  17. package/dist/core/errors/errors-data.js +13 -1
  18. package/dist/core/errors/overlay.js +2 -1
  19. package/dist/core/messages.js +2 -2
  20. package/dist/core/middleware/vite-plugin.js +8 -0
  21. package/dist/core/render/index.d.ts +1 -1
  22. package/dist/core/render/index.js +1 -1
  23. package/dist/core/render/{result.js → slots.js} +4 -2
  24. package/dist/core/routing/manifest/create.js +1 -1
  25. package/dist/i18n/index.d.ts +18 -1
  26. package/dist/i18n/index.js +107 -0
  27. package/dist/i18n/middleware.d.ts +1 -1
  28. package/dist/i18n/middleware.js +40 -81
  29. package/dist/i18n/utils.d.ts +2 -2
  30. package/dist/i18n/utils.js +20 -21
  31. package/dist/runtime/client/dev-toolbar/apps/astro.js +6 -1
  32. package/dist/runtime/client/dev-toolbar/apps/audit/rules/a11y.js +1 -1
  33. package/dist/runtime/client/dev-toolbar/apps/settings.js +38 -1
  34. package/dist/runtime/client/dev-toolbar/apps/utils/window.d.ts +2 -1
  35. package/dist/runtime/client/dev-toolbar/apps/utils/window.js +18 -2
  36. package/dist/runtime/client/dev-toolbar/apps/xray.js +6 -1
  37. package/dist/runtime/client/dev-toolbar/entrypoint.js +3 -1
  38. package/dist/runtime/client/dev-toolbar/settings.d.ts +4 -1
  39. package/dist/runtime/client/dev-toolbar/settings.js +2 -1
  40. package/dist/runtime/client/dev-toolbar/toolbar.d.ts +2 -0
  41. package/dist/runtime/client/dev-toolbar/toolbar.js +25 -3
  42. package/dist/runtime/client/dev-toolbar/ui-library/index.d.ts +1 -0
  43. package/dist/runtime/client/dev-toolbar/ui-library/index.js +2 -0
  44. package/dist/runtime/client/dev-toolbar/ui-library/select.d.ts +15 -0
  45. package/dist/runtime/client/dev-toolbar/ui-library/select.js +100 -0
  46. package/dist/runtime/client/dev-toolbar/ui-library/window.d.ts +9 -0
  47. package/dist/runtime/client/dev-toolbar/ui-library/window.js +53 -3
  48. package/dist/runtime/server/render/astro/render-template.d.ts +1 -1
  49. package/dist/virtual-modules/i18n.d.ts +102 -0
  50. package/dist/virtual-modules/i18n.js +86 -6
  51. package/dist/vite-plugin-astro-server/plugin.js +2 -1
  52. package/dist/vite-plugin-astro-server/route.js +1 -1
  53. package/package.json +6 -5
  54. /package/dist/core/render/{result.d.ts → slots.d.ts} +0 -0
@@ -954,6 +954,19 @@ export declare const MissingIndexForInternationalization: {
954
954
  message: (defaultLocale: string) => string;
955
955
  hint: (src: string) => string;
956
956
  };
957
+ /**
958
+ * @docs
959
+ * @description
960
+ * Some internationalization functions are only available when Astro's own i18n routing is disabled by the configuration setting `i18n.routing: "manual"`.
961
+ *
962
+ * @see
963
+ * - [`i18n` routing](https://docs.astro.build/en/guides/internationalization/#routing)
964
+ */
965
+ export declare const IncorrectStrategyForI18n: {
966
+ name: string;
967
+ title: string;
968
+ message: (functionName: string) => string;
969
+ };
957
970
  /**
958
971
  * @docs
959
972
  * @description
@@ -964,6 +977,16 @@ export declare const NoPrerenderedRoutesWithDomains: {
964
977
  title: string;
965
978
  message: (component: string) => string;
966
979
  };
980
+ /**
981
+ * @docs
982
+ * @description
983
+ * Astro throws an error if the user enables manual routing, but it doesn't have a middleware file.
984
+ */
985
+ export declare const MissingMiddlewareForInternationalization: {
986
+ name: string;
987
+ title: string;
988
+ message: string;
989
+ };
967
990
  /**
968
991
  * @docs
969
992
  * @description
@@ -337,10 +337,20 @@ const MissingIndexForInternationalization = {
337
337
  message: (defaultLocale) => `Could not find index page. A root index page is required in order to create a redirect to the index URL of the default locale. (\`/${defaultLocale}\`)`,
338
338
  hint: (src) => `Create an index page (\`index.astro, index.md, etc.\`) in \`${src}\`.`
339
339
  };
340
+ const IncorrectStrategyForI18n = {
341
+ name: "IncorrectStrategyForI18n",
342
+ title: "You can't use the current function with the current strategy",
343
+ message: (functionName) => `The function \`${functionName}' can only be used when the \`i18n.routing.strategy\` is set to \`"manual"\`.`
344
+ };
340
345
  const NoPrerenderedRoutesWithDomains = {
341
346
  name: "NoPrerenderedRoutesWithDomains",
342
347
  title: "Prerendered routes aren't supported when internationalization domains are enabled.",
343
- message: (component) => `Static pages aren't yet supported with multiple domains. If you wish to enable this feature, you have to disable prerendering for the page ${component}`
348
+ message: (component) => `Static pages aren't yet supported with multiple domains. To enable this feature, you must disable prerendering for the page ${component}`
349
+ };
350
+ const MissingMiddlewareForInternationalization = {
351
+ name: "MissingMiddlewareForInternationalization",
352
+ title: "Enabled manual internationalization routing without having a middleware.",
353
+ message: "Your configuration setting `i18n.routing: 'manual'` requires you to provide your own i18n `middleware` file."
344
354
  };
345
355
  const CantRenderPage = {
346
356
  name: "CantRenderPage",
@@ -520,6 +530,7 @@ export {
520
530
  ImageMissingAlt,
521
531
  ImageNotFound,
522
532
  IncompatibleDescriptorOptions,
533
+ IncorrectStrategyForI18n,
523
534
  InvalidComponentArgs,
524
535
  InvalidContentEntryFrontmatterError,
525
536
  InvalidContentEntrySlugError,
@@ -543,6 +554,7 @@ export {
543
554
  MissingIndexForInternationalization,
544
555
  MissingLocale,
545
556
  MissingMediaQueryDirective,
557
+ MissingMiddlewareForInternationalization,
546
558
  MissingSharp,
547
559
  MixedContentDataCollectionError,
548
560
  NoAdapterInstalled,
@@ -588,13 +588,14 @@ class ErrorOverlay extends HTMLElement {
588
588
  const themeToggle = this.root.querySelector(".theme-toggle-checkbox");
589
589
  if (localStorage.astroErrorOverlayTheme === "dark" || !("astroErrorOverlayTheme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches) {
590
590
  this?.classList.add("astro-dark");
591
+ localStorage.astroErrorOverlayTheme = "dark";
591
592
  themeToggle.checked = true;
592
593
  } else {
593
594
  this?.classList.remove("astro-dark");
594
595
  themeToggle.checked = false;
595
596
  }
596
597
  themeToggle?.addEventListener("click", () => {
597
- const isDark = localStorage.astroErrorOverlayTheme === "dark";
598
+ const isDark = localStorage.astroErrorOverlayTheme === "dark" || this?.classList.contains("astro-dark");
598
599
  this?.classList.toggle("astro-dark", !isDark);
599
600
  localStorage.astroErrorOverlayTheme = isDark ? "light" : "dark";
600
601
  });
@@ -36,7 +36,7 @@ function serverStart({
36
36
  host,
37
37
  base
38
38
  }) {
39
- const version = "4.5.18";
39
+ const version = "4.6.0";
40
40
  const localPrefix = `${dim("\u2503")} Local `;
41
41
  const networkPrefix = `${dim("\u2503")} Network `;
42
42
  const emptyPrefix = " ".repeat(11);
@@ -261,7 +261,7 @@ function printHelp({
261
261
  message.push(
262
262
  linebreak(),
263
263
  ` ${bgGreen(black(` ${commandName} `))} ${green(
264
- `v${"4.5.18"}`
264
+ `v${"4.6.0"}`
265
265
  )} ${headline}`
266
266
  );
267
267
  }
@@ -2,6 +2,8 @@ import { normalizePath } from "vite";
2
2
  import { getOutputDirectory } from "../../prerender/utils.js";
3
3
  import { addRollupInput } from "../build/add-rollup-input.js";
4
4
  import { MIDDLEWARE_PATH_SEGMENT_NAME } from "../constants.js";
5
+ import { MissingMiddlewareForInternationalization } from "../errors/errors-data.js";
6
+ import { AstroError } from "../errors/index.js";
5
7
  const MIDDLEWARE_MODULE_ID = "\0astro-internal:middleware";
6
8
  const NOOP_MIDDLEWARE = "\0noop-middleware";
7
9
  function vitePluginMiddleware({ settings }) {
@@ -36,8 +38,14 @@ function vitePluginMiddleware({ settings }) {
36
38
  },
37
39
  async load(id) {
38
40
  if (id === NOOP_MIDDLEWARE) {
41
+ if (!userMiddlewareIsPresent && settings.config.i18n?.routing === "manual") {
42
+ throw new AstroError(MissingMiddlewareForInternationalization);
43
+ }
39
44
  return "export const onRequest = (_, next) => next()";
40
45
  } else if (id === MIDDLEWARE_MODULE_ID) {
46
+ if (!userMiddlewareIsPresent && settings.config.i18n?.routing === "manual") {
47
+ throw new AstroError(MissingMiddlewareForInternationalization);
48
+ }
41
49
  if (isCommandBuild) {
42
50
  this.emitFile({
43
51
  type: "chunk",
@@ -3,7 +3,7 @@ import type { Pipeline } from '../base-pipeline.js';
3
3
  export { Pipeline } from '../base-pipeline.js';
4
4
  export { getParams, getProps } from './params-and-props.js';
5
5
  export { loadRenderer } from './renderer.js';
6
- export { Slots } from './result.js';
6
+ export { Slots } from './slots.js';
7
7
  export interface SSROptions {
8
8
  /** The pipeline instance */
9
9
  pipeline: Pipeline;
@@ -1,7 +1,7 @@
1
1
  import { Pipeline } from "../base-pipeline.js";
2
2
  import { getParams, getProps } from "./params-and-props.js";
3
3
  import { loadRenderer } from "./renderer.js";
4
- import { Slots } from "./result.js";
4
+ import { Slots } from "./slots.js";
5
5
  export {
6
6
  Pipeline,
7
7
  Slots,
@@ -1,13 +1,15 @@
1
1
  import { renderSlotToString } from "../../runtime/server/index.js";
2
2
  import { renderJSX } from "../../runtime/server/jsx.js";
3
3
  import { chunkToString } from "../../runtime/server/render/index.js";
4
+ import { isRenderInstruction } from "../../runtime/server/render/instruction.js";
4
5
  import { AstroError, AstroErrorData } from "../errors/index.js";
5
6
  function getFunctionExpression(slot) {
6
7
  if (!slot)
7
8
  return;
8
- if (slot.expressions?.length !== 1)
9
+ const expressions = slot?.expressions?.filter((e) => isRenderInstruction(e) === false);
10
+ if (expressions?.length !== 1)
9
11
  return;
10
- return slot.expressions[0];
12
+ return expressions[0];
11
13
  }
12
14
  class Slots {
13
15
  #result;
@@ -384,7 +384,7 @@ function createRouteManifest(params, logger) {
384
384
  }
385
385
  const i18n = settings.config.i18n;
386
386
  if (i18n) {
387
- const strategy = toRoutingStrategy(i18n);
387
+ const strategy = toRoutingStrategy(i18n.routing, i18n.domains);
388
388
  if (strategy === "pathname-prefix-always") {
389
389
  let index = routes.find((route) => route.route === "/");
390
390
  if (!index) {
@@ -1,5 +1,7 @@
1
- import type { AstroConfig, Locales } from '../@types/astro.js';
1
+ import type { APIContext, AstroConfig, Locales, SSRManifest, ValidRedirectStatus } from '../@types/astro.js';
2
2
  import type { RoutingStrategies } from './utils.js';
3
+ export declare function requestHasLocale(locales: Locales): (context: APIContext) => boolean;
4
+ export declare function pathHasLocale(path: string, locales: Locales): boolean;
3
5
  type GetLocaleRelativeUrl = GetLocaleOptions & {
4
6
  locale: string;
5
7
  base: string;
@@ -80,4 +82,19 @@ export declare function toCodes(locales: Locales): string[];
80
82
  * @param locales
81
83
  */
82
84
  export declare function toPaths(locales: Locales): string[];
85
+ export type MiddlewarePayload = {
86
+ base: string;
87
+ locales: Locales;
88
+ trailingSlash: AstroConfig['trailingSlash'];
89
+ format: AstroConfig['build']['format'];
90
+ strategy: RoutingStrategies;
91
+ defaultLocale: string;
92
+ domains: Record<string, string> | undefined;
93
+ fallback: Record<string, string> | undefined;
94
+ };
95
+ export declare function redirectToDefaultLocale({ trailingSlash, format, base, defaultLocale, }: MiddlewarePayload): (context: APIContext, statusCode?: ValidRedirectStatus) => Response;
96
+ export declare function notFound({ base, locales }: MiddlewarePayload): (context: APIContext, response?: Response) => Response | undefined;
97
+ export type RedirectToFallback = (context: APIContext, response: Response) => Response;
98
+ export declare function redirectToFallback({ fallback, locales, defaultLocale, strategy, }: MiddlewarePayload): (context: APIContext, response: Response) => Response;
99
+ export declare function createMiddleware(i18nManifest: SSRManifest['i18n'], base: SSRManifest['base'], trailingSlash: SSRManifest['trailingSlash'], format: SSRManifest['buildFormat']): import("../@types/astro.js").MiddlewareHandler;
83
100
  export {};
@@ -1,7 +1,29 @@
1
1
  import { appendForwardSlash, joinPaths } from "@astrojs/internal-helpers/path";
2
2
  import { shouldAppendForwardSlash } from "../core/build/util.js";
3
+ import { REROUTE_DIRECTIVE_HEADER } from "../core/constants.js";
3
4
  import { MissingLocale } from "../core/errors/errors-data.js";
4
5
  import { AstroError } from "../core/errors/index.js";
6
+ import { createI18nMiddleware } from "./middleware.js";
7
+ function requestHasLocale(locales) {
8
+ return function(context) {
9
+ return pathHasLocale(context.url.pathname, locales);
10
+ };
11
+ }
12
+ function pathHasLocale(path, locales) {
13
+ const segments = path.split("/");
14
+ for (const segment of segments) {
15
+ for (const locale of locales) {
16
+ if (typeof locale === "string") {
17
+ if (normalizeTheLocale(segment) === normalizeTheLocale(locale)) {
18
+ return true;
19
+ }
20
+ } else if (segment === locale.path) {
21
+ return true;
22
+ }
23
+ }
24
+ }
25
+ return false;
26
+ }
5
27
  function getLocaleRelativeUrl({
6
28
  locale,
7
29
  base,
@@ -145,7 +167,87 @@ class Unreachable extends Error {
145
167
  );
146
168
  }
147
169
  }
170
+ function redirectToDefaultLocale({
171
+ trailingSlash,
172
+ format,
173
+ base,
174
+ defaultLocale
175
+ }) {
176
+ return function(context, statusCode) {
177
+ if (shouldAppendForwardSlash(trailingSlash, format)) {
178
+ return context.redirect(`${appendForwardSlash(joinPaths(base, defaultLocale))}`, statusCode);
179
+ } else {
180
+ return context.redirect(`${joinPaths(base, defaultLocale)}`, statusCode);
181
+ }
182
+ };
183
+ }
184
+ function notFound({ base, locales }) {
185
+ return function(context, response) {
186
+ if (response?.headers.get(REROUTE_DIRECTIVE_HEADER) === "no")
187
+ return response;
188
+ const url = context.url;
189
+ const isRoot = url.pathname === base + "/" || url.pathname === base;
190
+ if (!(isRoot || pathHasLocale(url.pathname, locales))) {
191
+ if (response) {
192
+ response.headers.set(REROUTE_DIRECTIVE_HEADER, "no");
193
+ return new Response(null, {
194
+ status: 404,
195
+ headers: response.headers
196
+ });
197
+ } else {
198
+ return new Response(null, {
199
+ status: 404,
200
+ headers: {
201
+ [REROUTE_DIRECTIVE_HEADER]: "no"
202
+ }
203
+ });
204
+ }
205
+ }
206
+ return void 0;
207
+ };
208
+ }
209
+ function redirectToFallback({
210
+ fallback,
211
+ locales,
212
+ defaultLocale,
213
+ strategy
214
+ }) {
215
+ return function(context, response) {
216
+ if (response.status >= 300 && fallback) {
217
+ const fallbackKeys = fallback ? Object.keys(fallback) : [];
218
+ const segments = context.url.pathname.split("/");
219
+ const urlLocale = segments.find((segment) => {
220
+ for (const locale of locales) {
221
+ if (typeof locale === "string") {
222
+ if (locale === segment) {
223
+ return true;
224
+ }
225
+ } else if (locale.path === segment) {
226
+ return true;
227
+ }
228
+ }
229
+ return false;
230
+ });
231
+ if (urlLocale && fallbackKeys.includes(urlLocale)) {
232
+ const fallbackLocale = fallback[urlLocale];
233
+ const pathFallbackLocale = getPathByLocale(fallbackLocale, locales);
234
+ let newPathname;
235
+ if (pathFallbackLocale === defaultLocale && strategy === "pathname-prefix-other-locales") {
236
+ newPathname = context.url.pathname.replace(`/${urlLocale}`, ``);
237
+ } else {
238
+ newPathname = context.url.pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`);
239
+ }
240
+ return context.redirect(newPathname);
241
+ }
242
+ }
243
+ return response;
244
+ };
245
+ }
246
+ function createMiddleware(i18nManifest, base, trailingSlash, format) {
247
+ return createI18nMiddleware(i18nManifest, base, trailingSlash, format);
248
+ }
148
249
  export {
250
+ createMiddleware,
149
251
  getLocaleAbsoluteUrl,
150
252
  getLocaleAbsoluteUrlList,
151
253
  getLocaleByPath,
@@ -153,6 +255,11 @@ export {
153
255
  getLocaleRelativeUrlList,
154
256
  getPathByLocale,
155
257
  normalizeTheLocale,
258
+ notFound,
259
+ pathHasLocale,
260
+ redirectToDefaultLocale,
261
+ redirectToFallback,
262
+ requestHasLocale,
156
263
  toCodes,
157
264
  toPaths
158
265
  };
@@ -1,2 +1,2 @@
1
1
  import type { MiddlewareHandler, SSRManifest } from '../@types/astro.js';
2
- export declare function createI18nMiddleware(i18n: SSRManifest['i18n'], base: SSRManifest['base'], trailingSlash: SSRManifest['trailingSlash'], buildFormat: SSRManifest['buildFormat']): MiddlewareHandler;
2
+ export declare function createI18nMiddleware(i18n: SSRManifest['i18n'], base: SSRManifest['base'], trailingSlash: SSRManifest['trailingSlash'], format: SSRManifest['buildFormat']): MiddlewareHandler;
@@ -1,39 +1,38 @@
1
- import { appendForwardSlash, joinPaths } from "@astrojs/internal-helpers/path";
2
- import { shouldAppendForwardSlash } from "../core/build/util.js";
3
- import { REROUTE_DIRECTIVE_HEADER, ROUTE_TYPE_HEADER } from "../core/constants.js";
4
- import { getPathByLocale, normalizeTheLocale } from "./index.js";
5
- function pathnameHasLocale(pathname, locales) {
6
- const segments = pathname.split("/");
7
- for (const segment of segments) {
8
- for (const locale of locales) {
9
- if (typeof locale === "string") {
10
- if (normalizeTheLocale(segment) === normalizeTheLocale(locale)) {
11
- return true;
12
- }
13
- } else if (segment === locale.path) {
14
- return true;
15
- }
16
- }
17
- }
18
- return false;
19
- }
20
- function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
1
+ import { ROUTE_TYPE_HEADER } from "../core/constants.js";
2
+ import {
3
+ getPathByLocale,
4
+ normalizeTheLocale,
5
+ notFound,
6
+ redirectToDefaultLocale,
7
+ redirectToFallback,
8
+ requestHasLocale
9
+ } from "./index.js";
10
+ function createI18nMiddleware(i18n, base, trailingSlash, format) {
21
11
  if (!i18n)
22
12
  return (_, next) => next();
23
- const prefixAlways = (url, response, context) => {
13
+ const payload = {
14
+ ...i18n,
15
+ trailingSlash,
16
+ base,
17
+ format,
18
+ domains: {}
19
+ };
20
+ const _redirectToDefaultLocale = redirectToDefaultLocale(payload);
21
+ const _noFoundForNonLocaleRoute = notFound(payload);
22
+ const _requestHasLocale = requestHasLocale(payload.locales);
23
+ const _redirectToFallback = redirectToFallback(payload);
24
+ const prefixAlways = (context) => {
25
+ const url = context.url;
24
26
  if (url.pathname === base + "/" || url.pathname === base) {
25
- if (shouldAppendForwardSlash(trailingSlash, buildFormat)) {
26
- return context.redirect(`${appendForwardSlash(joinPaths(base, i18n.defaultLocale))}`);
27
- } else {
28
- return context.redirect(`${joinPaths(base, i18n.defaultLocale)}`);
29
- }
30
- } else if (!pathnameHasLocale(url.pathname, i18n.locales)) {
31
- return notFound(response);
27
+ return _redirectToDefaultLocale(context);
28
+ } else if (!_requestHasLocale(context)) {
29
+ return _noFoundForNonLocaleRoute(context);
32
30
  }
33
31
  return void 0;
34
32
  };
35
- const prefixOtherLocales = (url, response) => {
33
+ const prefixOtherLocales = (context, response) => {
36
34
  let pathnameContainsDefaultLocale = false;
35
+ const url = context.url;
37
36
  for (const segment of url.pathname.split("/")) {
38
37
  if (normalizeTheLocale(segment) === normalizeTheLocale(i18n.defaultLocale)) {
39
38
  pathnameContainsDefaultLocale = true;
@@ -43,14 +42,7 @@ function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
43
42
  if (pathnameContainsDefaultLocale) {
44
43
  const newLocation = url.pathname.replace(`/${i18n.defaultLocale}`, "");
45
44
  response.headers.set("Location", newLocation);
46
- return notFound(response);
47
- }
48
- return void 0;
49
- };
50
- const prefixAlwaysNoRedirect = (url, response) => {
51
- const isRoot = url.pathname === base + "/" || url.pathname === base;
52
- if (!(isRoot || pathnameHasLocale(url.pathname, i18n.locales))) {
53
- return notFound(response);
45
+ return _noFoundForNonLocaleRoute(context);
54
46
  }
55
47
  return void 0;
56
48
  };
@@ -60,12 +52,14 @@ function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
60
52
  if (type !== "page" && type !== "fallback") {
61
53
  return response;
62
54
  }
63
- const { url, currentLocale } = context;
64
- const { locales, defaultLocale, fallback, strategy } = i18n;
55
+ const { currentLocale } = context;
65
56
  switch (i18n.strategy) {
57
+ case "manual": {
58
+ return response;
59
+ }
66
60
  case "domains-prefix-other-locales": {
67
61
  if (localeHasntDomain(i18n, currentLocale)) {
68
- const result = prefixOtherLocales(url, response);
62
+ const result = prefixOtherLocales(context, response);
69
63
  if (result) {
70
64
  return result;
71
65
  }
@@ -73,7 +67,7 @@ function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
73
67
  break;
74
68
  }
75
69
  case "pathname-prefix-other-locales": {
76
- const result = prefixOtherLocales(url, response);
70
+ const result = prefixOtherLocales(context, response);
77
71
  if (result) {
78
72
  return result;
79
73
  }
@@ -81,7 +75,7 @@ function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
81
75
  }
82
76
  case "domains-prefix-always-no-redirect": {
83
77
  if (localeHasntDomain(i18n, currentLocale)) {
84
- const result = prefixAlwaysNoRedirect(url, response);
78
+ const result = _noFoundForNonLocaleRoute(context, response);
85
79
  if (result) {
86
80
  return result;
87
81
  }
@@ -89,14 +83,14 @@ function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
89
83
  break;
90
84
  }
91
85
  case "pathname-prefix-always-no-redirect": {
92
- const result = prefixAlwaysNoRedirect(url, response);
86
+ const result = _noFoundForNonLocaleRoute(context, response);
93
87
  if (result) {
94
88
  return result;
95
89
  }
96
90
  break;
97
91
  }
98
92
  case "pathname-prefix-always": {
99
- const result = prefixAlways(url, response, context);
93
+ const result = prefixAlways(context);
100
94
  if (result) {
101
95
  return result;
102
96
  }
@@ -104,7 +98,7 @@ function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
104
98
  }
105
99
  case "domains-prefix-always": {
106
100
  if (localeHasntDomain(i18n, currentLocale)) {
107
- const result = prefixAlways(url, response, context);
101
+ const result = prefixAlways(context);
108
102
  if (result) {
109
103
  return result;
110
104
  }
@@ -112,44 +106,9 @@ function createI18nMiddleware(i18n, base, trailingSlash, buildFormat) {
112
106
  break;
113
107
  }
114
108
  }
115
- if (response.status >= 300 && fallback) {
116
- const fallbackKeys = i18n.fallback ? Object.keys(i18n.fallback) : [];
117
- const segments = url.pathname.split("/");
118
- const urlLocale = segments.find((segment) => {
119
- for (const locale of locales) {
120
- if (typeof locale === "string") {
121
- if (locale === segment) {
122
- return true;
123
- }
124
- } else if (locale.path === segment) {
125
- return true;
126
- }
127
- }
128
- return false;
129
- });
130
- if (urlLocale && fallbackKeys.includes(urlLocale)) {
131
- const fallbackLocale = fallback[urlLocale];
132
- const pathFallbackLocale = getPathByLocale(fallbackLocale, locales);
133
- let newPathname;
134
- if (pathFallbackLocale === defaultLocale && strategy === "pathname-prefix-other-locales") {
135
- newPathname = url.pathname.replace(`/${urlLocale}`, ``);
136
- } else {
137
- newPathname = url.pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`);
138
- }
139
- return context.redirect(newPathname);
140
- }
141
- }
142
- return response;
109
+ return _redirectToFallback(context, response);
143
110
  };
144
111
  }
145
- function notFound(response) {
146
- if (response.headers.get(REROUTE_DIRECTIVE_HEADER) === "no")
147
- return response;
148
- return new Response(null, {
149
- status: 404,
150
- headers: response.headers
151
- });
152
- }
153
112
  function localeHasntDomain(i18n, currentLocale) {
154
113
  for (const domainLocale of Object.values(i18n.domainLookupTable)) {
155
114
  if (domainLocale === currentLocale) {
@@ -21,6 +21,6 @@ export declare function parseLocale(header: string): BrowserLocale[];
21
21
  export declare function computePreferredLocale(request: Request, locales: Locales): string | undefined;
22
22
  export declare function computePreferredLocaleList(request: Request, locales: Locales): string[];
23
23
  export declare function computeCurrentLocale(pathname: string, locales: Locales): undefined | string;
24
- export type RoutingStrategies = 'pathname-prefix-always' | 'pathname-prefix-other-locales' | 'pathname-prefix-always-no-redirect' | 'domains-prefix-always' | 'domains-prefix-other-locales' | 'domains-prefix-always-no-redirect';
25
- export declare function toRoutingStrategy(i18n: NonNullable<AstroConfig['i18n']>): RoutingStrategies;
24
+ export type RoutingStrategies = 'manual' | 'pathname-prefix-always' | 'pathname-prefix-other-locales' | 'pathname-prefix-always-no-redirect' | 'domains-prefix-always' | 'domains-prefix-other-locales' | 'domains-prefix-always-no-redirect';
25
+ export declare function toRoutingStrategy(routing: NonNullable<AstroConfig['i18n']>['routing'], domains: NonNullable<AstroConfig['i18n']>['domains']): RoutingStrategies;
26
26
  export {};
@@ -43,11 +43,7 @@ function sortAndFilterLocales(browserLocaleList, locales) {
43
43
  return true;
44
44
  }).sort((a, b) => {
45
45
  if (a.qualityValue && b.qualityValue) {
46
- if (a.qualityValue > b.qualityValue) {
47
- return -1;
48
- } else if (a.qualityValue < b.qualityValue) {
49
- return 1;
50
- }
46
+ return Math.sign(b.qualityValue - a.qualityValue);
51
47
  }
52
48
  return 0;
53
49
  });
@@ -132,29 +128,32 @@ function computeCurrentLocale(pathname, locales) {
132
128
  }
133
129
  }
134
130
  }
135
- function toRoutingStrategy(i18n) {
136
- let { routing, domains } = i18n;
131
+ function toRoutingStrategy(routing, domains) {
137
132
  let strategy;
138
133
  const hasDomains = domains ? Object.keys(domains).length > 0 : false;
139
- if (!hasDomains) {
140
- if (routing?.prefixDefaultLocale === true) {
141
- if (routing.redirectToDefaultLocale) {
142
- strategy = "pathname-prefix-always";
134
+ if (routing === "manual") {
135
+ strategy = "manual";
136
+ } else {
137
+ if (!hasDomains) {
138
+ if (routing?.prefixDefaultLocale === true) {
139
+ if (routing.redirectToDefaultLocale) {
140
+ strategy = "pathname-prefix-always";
141
+ } else {
142
+ strategy = "pathname-prefix-always-no-redirect";
143
+ }
143
144
  } else {
144
- strategy = "pathname-prefix-always-no-redirect";
145
+ strategy = "pathname-prefix-other-locales";
145
146
  }
146
147
  } else {
147
- strategy = "pathname-prefix-other-locales";
148
- }
149
- } else {
150
- if (routing?.prefixDefaultLocale === true) {
151
- if (routing.redirectToDefaultLocale) {
152
- strategy = "domains-prefix-always";
148
+ if (routing?.prefixDefaultLocale === true) {
149
+ if (routing.redirectToDefaultLocale) {
150
+ strategy = "domains-prefix-always";
151
+ } else {
152
+ strategy = "domains-prefix-always-no-redirect";
153
+ }
153
154
  } else {
154
- strategy = "domains-prefix-always-no-redirect";
155
+ strategy = "domains-prefix-other-locales";
155
156
  }
156
- } else {
157
- strategy = "domains-prefix-other-locales";
158
157
  }
159
158
  }
160
159
  return strategy;
@@ -1,6 +1,10 @@
1
1
  import { isDefinedIcon } from "../ui-library/icons.js";
2
2
  import { colorForIntegration, iconForIntegration } from "./utils/icons.js";
3
- import { closeOnOutsideClick, createWindowElement } from "./utils/window.js";
3
+ import {
4
+ closeOnOutsideClick,
5
+ createWindowElement,
6
+ synchronizePlacementOnUpdate
7
+ } from "./utils/window.js";
4
8
  const astroLogo = '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 99 26" width="100"><path fill="#fff" d="M6.70402 22.1453c-1.17459-1.0737-1.51748-3.3297-1.02811-4.9641.84853 1.0304 2.02424 1.3569 3.24204 1.5411 1.88005.2844 3.72635.178 5.47285-.6813.1998-.0984.3844-.2292.6027-.3617.1639.4755.2065.9554.1493 1.4439-.1392 1.1898-.7313 2.1088-1.673 2.8054-.3765.2787-.775.5278-1.1639.7905-1.1948.8075-1.518 1.7544-1.0691 3.1318.0107.0336.0202.0671.0444.149-.6101-.273-1.0557-.6705-1.39518-1.1931-.3586-.5517-.52921-1.1619-.53819-1.8221-.00449-.3213-.00449-.6455-.0477-.9623-.10551-.7722-.46804-1.118-1.15102-1.1379-.70094-.0205-1.2554.4129-1.40244 1.0953-.01122.0523-.02749.1041-.04377.1649l.00112.0006Z"/><path fill="url(#paint0_linear_386_2739)" d="M6.70402 22.1453c-1.17459-1.0737-1.51748-3.3297-1.02811-4.9641.84853 1.0304 2.02424 1.3569 3.24204 1.5411 1.88005.2844 3.72635.178 5.47285-.6813.1998-.0984.3844-.2292.6027-.3617.1639.4755.2065.9554.1493 1.4439-.1392 1.1898-.7313 2.1088-1.673 2.8054-.3765.2787-.775.5278-1.1639.7905-1.1948.8075-1.518 1.7544-1.0691 3.1318.0107.0336.0202.0671.0444.149-.6101-.273-1.0557-.6705-1.39518-1.1931-.3586-.5517-.52921-1.1619-.53819-1.8221-.00449-.3213-.00449-.6455-.0477-.9623-.10551-.7722-.46804-1.118-1.15102-1.1379-.70094-.0205-1.2554.4129-1.40244 1.0953-.01122.0523-.02749.1041-.04377.1649l.00112.0006Z"/><path fill="#fff" d="M0 16.909s3.47815-1.6944 6.96603-1.6944l2.62973-8.13858c.09846-.39359.38592-.66106.71044-.66106.3246 0 .612.26747.7105.66106l2.6297 8.13858c4.1309 0 6.966 1.6944 6.966 1.6944S14.7045.814589 14.693.782298C14.5234.306461 14.2371 0 13.8512 0H6.76183c-.38593 0-.66063.306461-.84174.782298C5.90733.81398 0 16.909 0 16.909ZM36.671 11.7318c0 1.4262-1.7739 2.2779-4.2302 2.2779-1.5985 0-2.1638-.3962-2.1638-1.2281 0-.8715.7018-1.2875 2.3003-1.2875 1.4426 0 2.6707.0198 4.0937.1981v.0396Zm.0195-1.7629c-.8772-.19808-2.2028-.31693-3.7818-.31693-4.6006 0-6.7644 1.08943-6.7644 3.62483 0 2.6344 1.4815 3.6446 4.9125 3.6446 2.9046 0 4.8735-.7328 5.5947-2.5354h.117c-.0195.4358-.039.8716-.039 1.2083 0 .931.156 1.0102.9162 1.0102h3.5869c-.1949-.5546-.3119-2.1194-.3119-3.4663 0-1.446.0585-2.5355.0585-4.00123 0-2.99098-1.7934-4.89253-7.4077-4.89253-2.4173 0-5.1074.41596-7.1543 1.03.1949.81213.4679 2.45617.6043 3.5258 1.774-.83193 4.2887-1.18847 6.2381-1.18847 2.6902 0 3.4309.61404 3.4309 1.86193v.4952ZM46.5325 12.5637c-.4874.0594-1.1502.0594-1.8325.0594-.7213 0-1.3841-.0198-1.8324-.0792 0 .1585-.0195.3367-.0195.4952 0 2.476 1.618 3.922 7.3102 3.922 5.3609 0 7.0958-1.4262 7.0958-3.9418 0-2.3769-1.1501-3.5456-6.238-3.8031-3.9573-.17827-4.3082-.61404-4.3082-1.10924 0-.57442.5068-.87154 3.158-.87154 2.7487 0 3.4894.37635 3.4894 1.16866v.17827c.3899-.01981 1.0917-.03961 1.813-.03961.6823 0 1.423.0198 1.8519.05942 0-.17827.0195-.33674.0195-.47539 0-2.91175-2.4172-3.86252-7.0958-3.86252-5.2634 0-7.0373 1.2875-7.0373 3.8031 0 2.25805 1.423 3.66445 6.472 3.88235 3.7233.1188 4.1327.5348 4.1327 1.1092 0 .6141-.6043.8914-3.2165.8914-3.0021 0-3.7623-.416-3.7623-1.2677v-.1189ZM63.6883 2.125c-1.423 1.32712-3.9768 2.65425-5.3998 3.01079.0195.73289.0195 2.07982.0195 2.81271l1.3061.01981c-.0195 1.40635-.039 3.10979-.039 4.23889 0 2.6344 1.3841 4.6152 5.6922 4.6152 1.813 0 3.0216-.1981 4.5226-.515-.1559-.9706-.3314-2.4562-.3898-3.5852-.8968.2971-2.0274.4556-3.275.4556-1.735 0-2.4368-.4754-2.4368-1.8422 0-1.1884 0-2.29767.0195-3.32768 2.2223.01981 4.4446.05943 5.7507.09904-.0195-1.03.0195-2.51559.078-3.50598-1.8909.03961-4.0157.05942-5.7702.05942.0195-.87154.039-1.70347.0585-2.5354h-.1365ZM75.3313 7.35427c.0195-1.03001.039-1.90156.0585-2.75329h-3.9183c.0585 1.70347.0585 3.44656.0585 6.00172 0 2.5553-.0195 4.3182-.0585 6.0018h4.4836c-.078-1.1885-.0975-3.189-.0975-4.8925 0-2.69388 1.0917-3.46638 3.5674-3.46638 1.1502 0 1.9689.13865 2.6902.39615.0195-1.01019.2144-2.97117.3314-3.84271-.7408-.21789-1.5595-.35655-2.5537-.35655-2.1249-.0198-3.6844.85174-4.4056 2.93156l-.156-.0198ZM94.8501 10.5235c0 2.1591-1.5595 3.1693-4.0157 3.1693-2.4368 0-3.9963-.9508-3.9963-3.1693 0-2.21846 1.579-3.05039 3.9963-3.05039 2.4367 0 4.0157.89135 4.0157 3.05039Zm4.0743-.099c0-4.29832-3.353-6.21968-8.09-6.21968-4.7566 0-7.9926 1.92136-7.9926 6.21968 0 4.2785 3.0216 6.5762 7.9731 6.5762 4.9904 0 8.1095-2.2977 8.1095-6.5762Z"/><defs><linearGradient id="paint0_linear_386_2739" x1="5.46011" x2="16.8017" y1="25.9999" y2="20.6412" gradientUnits="userSpaceOnUse"><stop stop-color="#D83333"/><stop offset="1" stop-color="#F041FF"/></linearGradient></defs></svg>';
5
9
  let integrationData;
6
10
  var astro_default = {
@@ -20,6 +24,7 @@ var astro_default = {
20
24
  }
21
25
  });
22
26
  closeOnOutsideClick(eventTarget);
27
+ synchronizePlacementOnUpdate(eventTarget, canvas);
23
28
  function fetchIntegrationData() {
24
29
  fetch("https://astro.build/api/v1/dev-overlay/", {
25
30
  cache: "no-cache"
@@ -463,7 +463,7 @@ const a11y = [
463
463
  return false;
464
464
  if (!isInteractive(element))
465
465
  return false;
466
- if (!interactiveElements.includes(element.localName))
466
+ if (!interactiveElements.includes(element.localName) && !roleless_elements.includes(element.localName))
467
467
  return true;
468
468
  }
469
469
  },