astro 5.1.10 → 5.2.1

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 (65) hide show
  1. package/client.d.ts +14 -0
  2. package/dist/assets/endpoint/config.d.ts +2 -2
  3. package/dist/cli/add/index.js +51 -25
  4. package/dist/config/index.js +4 -4
  5. package/dist/container/index.js +6 -0
  6. package/dist/content/content-layer.js +3 -3
  7. package/dist/core/app/index.d.ts +2 -2
  8. package/dist/core/app/index.js +33 -0
  9. package/dist/core/app/pipeline.d.ts +2 -2
  10. package/dist/core/app/types.d.ts +9 -3
  11. package/dist/core/build/generate.js +8 -2
  12. package/dist/core/build/index.js +13 -8
  13. package/dist/core/build/page-data.d.ts +2 -2
  14. package/dist/core/build/pipeline.d.ts +3 -3
  15. package/dist/core/build/pipeline.js +4 -4
  16. package/dist/core/build/plugins/plugin-manifest.js +9 -3
  17. package/dist/core/build/types.d.ts +2 -2
  18. package/dist/core/config/schema.d.ts +17 -0
  19. package/dist/core/config/schema.js +4 -2
  20. package/dist/core/constants.js +1 -1
  21. package/dist/core/create-vite.d.ts +6 -6
  22. package/dist/core/create-vite.js +6 -4
  23. package/dist/core/dev/container.js +6 -5
  24. package/dist/core/dev/dev.js +1 -1
  25. package/dist/core/errors/errors-data.d.ts +22 -0
  26. package/dist/core/errors/errors-data.js +12 -0
  27. package/dist/core/messages.js +2 -2
  28. package/dist/core/preview/index.js +2 -2
  29. package/dist/core/redirects/render.d.ts +2 -0
  30. package/dist/core/redirects/render.js +24 -5
  31. package/dist/core/routing/astro-designed-error-pages.d.ts +2 -2
  32. package/dist/core/routing/index.d.ts +1 -1
  33. package/dist/core/routing/index.js +2 -2
  34. package/dist/core/routing/manifest/create.d.ts +3 -3
  35. package/dist/core/routing/manifest/create.js +12 -10
  36. package/dist/core/routing/match.d.ts +3 -3
  37. package/dist/core/server-islands/endpoint.d.ts +2 -2
  38. package/dist/core/sync/index.d.ts +5 -3
  39. package/dist/core/sync/index.js +13 -8
  40. package/dist/i18n/utils.d.ts +2 -0
  41. package/dist/i18n/utils.js +24 -0
  42. package/dist/manifest/virtual-module.d.ts +9 -0
  43. package/dist/manifest/virtual-module.js +111 -0
  44. package/dist/template/4xx.d.ts +1 -0
  45. package/dist/template/4xx.js +14 -1
  46. package/dist/types/astro.d.ts +1 -1
  47. package/dist/types/public/config.d.ts +36 -18
  48. package/dist/types/public/index.d.ts +1 -0
  49. package/dist/types/public/manifest.d.ts +23 -0
  50. package/dist/types/public/manifest.js +0 -0
  51. package/dist/vite-plugin-astro-server/base.js +3 -13
  52. package/dist/vite-plugin-astro-server/pipeline.d.ts +4 -4
  53. package/dist/vite-plugin-astro-server/pipeline.js +5 -5
  54. package/dist/vite-plugin-astro-server/plugin.d.ts +4 -4
  55. package/dist/vite-plugin-astro-server/plugin.js +21 -10
  56. package/dist/vite-plugin-astro-server/request.d.ts +3 -3
  57. package/dist/vite-plugin-astro-server/request.js +3 -3
  58. package/dist/vite-plugin-astro-server/route.d.ts +4 -4
  59. package/dist/vite-plugin-astro-server/route.js +7 -7
  60. package/dist/vite-plugin-astro-server/trailing-slash.d.ts +3 -0
  61. package/dist/vite-plugin-astro-server/trailing-slash.js +30 -0
  62. package/dist/vite-plugin-scanner/index.d.ts +3 -3
  63. package/dist/vite-plugin-scanner/index.js +3 -3
  64. package/package.json +4 -4
  65. package/templates/content/types.d.ts +25 -24
@@ -68,6 +68,7 @@ export declare const ASTRO_CONFIG_DEFAULTS: {
68
68
  contentIntellisense: false;
69
69
  responsiveImages: false;
70
70
  svg: false;
71
+ serializeConfig: false;
71
72
  };
72
73
  };
73
74
  export declare const AstroConfigSchema: z.ZodObject<{
@@ -747,10 +748,12 @@ export declare const AstroConfigSchema: z.ZodObject<{
747
748
  } | undefined, boolean | {
748
749
  mode?: "inline" | "sprite" | undefined;
749
750
  } | undefined>;
751
+ serializeConfig: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
750
752
  }, "strict", z.ZodTypeAny, {
751
753
  clientPrerender: boolean;
752
754
  contentIntellisense: boolean;
753
755
  responsiveImages: boolean;
756
+ serializeConfig: boolean;
754
757
  svg?: {
755
758
  mode?: "inline" | "sprite" | undefined;
756
759
  } | undefined;
@@ -774,6 +777,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
774
777
  svg?: boolean | {
775
778
  mode?: "inline" | "sprite" | undefined;
776
779
  } | undefined;
780
+ serializeConfig?: boolean | undefined;
777
781
  session?: {
778
782
  driver: string;
779
783
  cookie?: string | {
@@ -926,6 +930,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
926
930
  clientPrerender: boolean;
927
931
  contentIntellisense: boolean;
928
932
  responsiveImages: boolean;
933
+ serializeConfig: boolean;
929
934
  svg?: {
930
935
  mode?: "inline" | "sprite" | undefined;
931
936
  } | undefined;
@@ -1118,6 +1123,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
1118
1123
  svg?: boolean | {
1119
1124
  mode?: "inline" | "sprite" | undefined;
1120
1125
  } | undefined;
1126
+ serializeConfig?: boolean | undefined;
1121
1127
  session?: {
1122
1128
  driver: string;
1123
1129
  cookie?: string | {
@@ -1814,10 +1820,12 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
1814
1820
  } | undefined, boolean | {
1815
1821
  mode?: "inline" | "sprite" | undefined;
1816
1822
  } | undefined>;
1823
+ serializeConfig: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
1817
1824
  }, "strict", z.ZodTypeAny, {
1818
1825
  clientPrerender: boolean;
1819
1826
  contentIntellisense: boolean;
1820
1827
  responsiveImages: boolean;
1828
+ serializeConfig: boolean;
1821
1829
  svg?: {
1822
1830
  mode?: "inline" | "sprite" | undefined;
1823
1831
  } | undefined;
@@ -1841,6 +1849,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
1841
1849
  svg?: boolean | {
1842
1850
  mode?: "inline" | "sprite" | undefined;
1843
1851
  } | undefined;
1852
+ serializeConfig?: boolean | undefined;
1844
1853
  session?: {
1845
1854
  driver: string;
1846
1855
  cookie?: string | {
@@ -2071,6 +2080,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2071
2080
  clientPrerender: boolean;
2072
2081
  contentIntellisense: boolean;
2073
2082
  responsiveImages: boolean;
2083
+ serializeConfig: boolean;
2074
2084
  svg?: {
2075
2085
  mode?: "inline" | "sprite" | undefined;
2076
2086
  } | undefined;
@@ -2263,6 +2273,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2263
2273
  svg?: boolean | {
2264
2274
  mode?: "inline" | "sprite" | undefined;
2265
2275
  } | undefined;
2276
+ serializeConfig?: boolean | undefined;
2266
2277
  session?: {
2267
2278
  driver: string;
2268
2279
  cookie?: string | {
@@ -2412,6 +2423,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2412
2423
  clientPrerender: boolean;
2413
2424
  contentIntellisense: boolean;
2414
2425
  responsiveImages: boolean;
2426
+ serializeConfig: boolean;
2415
2427
  svg?: {
2416
2428
  mode?: "inline" | "sprite" | undefined;
2417
2429
  } | undefined;
@@ -2604,6 +2616,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2604
2616
  svg?: boolean | {
2605
2617
  mode?: "inline" | "sprite" | undefined;
2606
2618
  } | undefined;
2619
+ serializeConfig?: boolean | undefined;
2607
2620
  session?: {
2608
2621
  driver: string;
2609
2622
  cookie?: string | {
@@ -2753,6 +2766,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2753
2766
  clientPrerender: boolean;
2754
2767
  contentIntellisense: boolean;
2755
2768
  responsiveImages: boolean;
2769
+ serializeConfig: boolean;
2756
2770
  svg?: {
2757
2771
  mode?: "inline" | "sprite" | undefined;
2758
2772
  } | undefined;
@@ -2945,6 +2959,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2945
2959
  svg?: boolean | {
2946
2960
  mode?: "inline" | "sprite" | undefined;
2947
2961
  } | undefined;
2962
+ serializeConfig?: boolean | undefined;
2948
2963
  session?: {
2949
2964
  driver: string;
2950
2965
  cookie?: string | {
@@ -3094,6 +3109,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
3094
3109
  clientPrerender: boolean;
3095
3110
  contentIntellisense: boolean;
3096
3111
  responsiveImages: boolean;
3112
+ serializeConfig: boolean;
3097
3113
  svg?: {
3098
3114
  mode?: "inline" | "sprite" | undefined;
3099
3115
  } | undefined;
@@ -3286,6 +3302,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
3286
3302
  svg?: boolean | {
3287
3303
  mode?: "inline" | "sprite" | undefined;
3288
3304
  } | undefined;
3305
+ serializeConfig?: boolean | undefined;
3289
3306
  session?: {
3290
3307
  driver: string;
3291
3308
  cookie?: string | {
@@ -54,7 +54,8 @@ const ASTRO_CONFIG_DEFAULTS = {
54
54
  clientPrerender: false,
55
55
  contentIntellisense: false,
56
56
  responsiveImages: false,
57
- svg: false
57
+ svg: false,
58
+ serializeConfig: false
58
59
  }
59
60
  };
60
61
  const AstroConfigSchema = z.object({
@@ -373,7 +374,8 @@ const AstroConfigSchema = z.object({
373
374
  }
374
375
  }
375
376
  return svgConfig;
376
- })
377
+ }),
378
+ serializeConfig: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.serializeConfig)
377
379
  }).strict(
378
380
  `Invalid or outdated experimental feature.
379
381
  Check for incorrect spelling or outdated Astro version.
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "5.1.10";
1
+ const ASTRO_VERSION = "5.2.1";
2
2
  const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";
3
3
  const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite";
4
4
  const REWRITE_DIRECTIVE_HEADER_VALUE = "yes";
@@ -1,6 +1,6 @@
1
1
  import nodeFs from 'node:fs';
2
2
  import * as vite from 'vite';
3
- import type { AstroSettings, ManifestData } from '../types/astro.js';
3
+ import type { AstroSettings, RoutesList } from '../types/astro.js';
4
4
  import type { SSRManifest } from './app/types.js';
5
5
  import type { Logger } from './logger/core.js';
6
6
  type CreateViteOptions = {
@@ -9,15 +9,15 @@ type CreateViteOptions = {
9
9
  mode: string;
10
10
  fs?: typeof nodeFs;
11
11
  sync: boolean;
12
- manifest: ManifestData;
13
- ssrManifest?: SSRManifest;
12
+ routesList: RoutesList;
13
+ manifest: SSRManifest;
14
14
  } & ({
15
15
  command: 'dev';
16
- ssrManifest: SSRManifest;
16
+ manifest: SSRManifest;
17
17
  } | {
18
18
  command: 'build';
19
- ssrManifest?: SSRManifest;
19
+ manifest?: SSRManifest;
20
20
  });
21
21
  /** Return a base vite config as a common starting point for all Vite commands. */
22
- export declare function createVite(commandConfig: vite.InlineConfig, { settings, logger, mode, command, fs, sync, manifest, ssrManifest }: CreateViteOptions): Promise<vite.InlineConfig>;
22
+ export declare function createVite(commandConfig: vite.InlineConfig, { settings, logger, mode, command, fs, sync, routesList, manifest }: CreateViteOptions): Promise<vite.InlineConfig>;
23
23
  export {};
@@ -16,6 +16,7 @@ import { createEnvLoader } from "../env/env-loader.js";
16
16
  import { astroEnv } from "../env/vite-plugin-env.js";
17
17
  import { importMetaEnv } from "../env/vite-plugin-import-meta-env.js";
18
18
  import astroInternationalization from "../i18n/vite-plugin-i18n.js";
19
+ import astroVirtualManifestPlugin from "../manifest/virtual-module.js";
19
20
  import astroPrefetch from "../prefetch/vite-plugin-prefetch.js";
20
21
  import astroDevToolbar from "../toolbar/vite-plugin-dev-toolbar.js";
21
22
  import astroTransitions from "../transitions/vite-plugin-transitions.js";
@@ -58,7 +59,7 @@ const ONLY_DEV_EXTERNAL = [
58
59
  // Imported by `astro:transitions` -> packages/astro/src/runtime/server/transition.ts
59
60
  "cssesc"
60
61
  ];
61
- async function createVite(commandConfig, { settings, logger, mode, command, fs = nodeFs, sync, manifest, ssrManifest }) {
62
+ async function createVite(commandConfig, { settings, logger, mode, command, fs = nodeFs, sync, routesList, manifest }) {
62
63
  const astroPkgsConfig = await crawlFrameworkPkgs({
63
64
  root: fileURLToPath(settings.config.root),
64
65
  isBuild: command === "build",
@@ -101,14 +102,15 @@ async function createVite(commandConfig, { settings, logger, mode, command, fs =
101
102
  exclude: ["astro", "node-fetch"]
102
103
  },
103
104
  plugins: [
105
+ astroVirtualManifestPlugin({ settings, logger, manifest }),
104
106
  configAliasVitePlugin({ settings }),
105
107
  astroLoadFallbackPlugin({ fs, root: settings.config.root }),
106
108
  astroVitePlugin({ settings, logger }),
107
109
  astroScriptsPlugin({ settings }),
108
110
  // The server plugin is for dev only and having it run during the build causes
109
111
  // the build to run very slow as the filewatcher is triggered often.
110
- command === "dev" && vitePluginAstroServer({ settings, logger, fs, manifest, ssrManifest }),
111
- // ssrManifest is only required in dev mode, where it gets created before a Vite instance is created, and get passed to this function
112
+ command === "dev" && vitePluginAstroServer({ settings, logger, fs, routesList, manifest }),
113
+ // manifest is only required in dev mode, where it gets created before a Vite instance is created, and get passed to this function
112
114
  importMetaEnv({ envLoader }),
113
115
  astroEnv({ settings, sync, envLoader }),
114
116
  markdownVitePlugin({ settings, logger }),
@@ -117,7 +119,7 @@ async function createVite(commandConfig, { settings, logger, mode, command, fs =
117
119
  astroIntegrationsContainerPlugin({ settings, logger }),
118
120
  astroScriptsPageSSRPlugin({ settings }),
119
121
  astroHeadPlugin(),
120
- astroScannerPlugin({ settings, logger, manifest }),
122
+ astroScannerPlugin({ settings, logger, routesList }),
121
123
  astroContentVirtualModPlugin({ fs, settings }),
122
124
  astroContentImportPlugin({ fs, settings, logger }),
123
125
  astroContentAssetPropagationPlugin({ settings }),
@@ -9,7 +9,7 @@ import {
9
9
  import { createDevelopmentManifest } from "../../vite-plugin-astro-server/plugin.js";
10
10
  import { createVite } from "../create-vite.js";
11
11
  import { apply as applyPolyfill } from "../polyfill.js";
12
- import { createRouteManifest } from "../routing/index.js";
12
+ import { createRoutesList } from "../routing/index.js";
13
13
  import { syncInternal } from "../sync/index.js";
14
14
  import { warnMissingAdapter } from "./adapter-validation.js";
15
15
  async function createContainer({
@@ -34,8 +34,8 @@ async function createContainer({
34
34
  const isServerOpenBoolean = serverOpen && !isRestart;
35
35
  const open = isServerOpenURL ? serverOpen : isServerOpenBoolean ? base : false;
36
36
  const rendererClientEntries = settings.renderers.map((r) => r.clientEntrypoint).filter(Boolean);
37
- const manifest = await createRouteManifest({ settings, fsMod: fs }, logger, { dev: true });
38
- const devSSRManifest = createDevelopmentManifest(settings);
37
+ const routesList = await createRoutesList({ settings, fsMod: fs }, logger, { dev: true });
38
+ const manifest = createDevelopmentManifest(settings);
39
39
  await runHookConfigDone({ settings, logger, command: "dev" });
40
40
  warnMissingAdapter(logger, settings);
41
41
  const mode = inlineConfig?.mode ?? "development";
@@ -53,8 +53,8 @@ async function createContainer({
53
53
  command: "dev",
54
54
  fs,
55
55
  sync: false,
56
- manifest,
57
- ssrManifest: devSSRManifest
56
+ routesList,
57
+ manifest
58
58
  }
59
59
  );
60
60
  const viteServer = await vite.createServer(viteConfig);
@@ -67,6 +67,7 @@ async function createContainer({
67
67
  cleanup: true
68
68
  },
69
69
  force: inlineConfig?.force,
70
+ routesList,
70
71
  manifest,
71
72
  command: "dev",
72
73
  watcher: viteServer.watcher
@@ -22,7 +22,7 @@ async function dev(inlineConfig) {
22
22
  await telemetry.record([]);
23
23
  const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
24
24
  const logger = restart.container.logger;
25
- const currentVersion = "5.1.10";
25
+ const currentVersion = "5.2.1";
26
26
  const isPrerelease = currentVersion.includes("-");
27
27
  if (!isPrerelease) {
28
28
  try {
@@ -10,6 +10,16 @@ export interface ErrorData {
10
10
  * @kind heading
11
11
  * @name Astro Errors
12
12
  */
13
+ /**
14
+ * @docs
15
+ * @description
16
+ * Cannot use the module `astro:config` without enabling the experimental feature.
17
+ */
18
+ export declare const CantUseAstroConfigModuleError: {
19
+ name: string;
20
+ title: string;
21
+ message: (moduleName: any) => string;
22
+ };
13
23
  /**
14
24
  * @docs
15
25
  * @message
@@ -892,6 +902,18 @@ export declare const RedirectWithNoLocation: {
892
902
  name: string;
893
903
  title: string;
894
904
  };
905
+ /**
906
+ * @docs
907
+ * @see
908
+ * - [Astro.redirect](https://docs.astro.build/en/reference/api-reference/#redirect)
909
+ * @description
910
+ * An external redirect must start with http or https, and must be a valid URL.
911
+ */
912
+ export declare const UnsupportedExternalRedirect: {
913
+ name: string;
914
+ title: string;
915
+ message: string;
916
+ };
895
917
  /**
896
918
  * @docs
897
919
  * @see
@@ -1,3 +1,8 @@
1
+ const CantUseAstroConfigModuleError = {
2
+ name: "CantUseAstroConfigModuleError",
3
+ title: "Cannot use the `astro:config` module without enabling the experimental feature.",
4
+ message: (moduleName) => `Cannot import the module "${moduleName}" because the experimental feature is disabled. Enable \`experimental.serializeManifest\` in your \`astro.config.mjs\` `
5
+ };
1
6
  const UnknownCompilerError = {
2
7
  name: "UnknownCompilerError",
3
8
  title: "Unknown compiler error.",
@@ -314,6 +319,11 @@ const RedirectWithNoLocation = {
314
319
  name: "RedirectWithNoLocation",
315
320
  title: "A redirect must be given a location with the `Location` header."
316
321
  };
322
+ const UnsupportedExternalRedirect = {
323
+ name: "UnsupportedExternalRedirect",
324
+ title: "Unsupported or malformed URL.",
325
+ message: "An external redirect must start with http or https, and must be a valid URL."
326
+ };
317
327
  const InvalidDynamicRoute = {
318
328
  name: "InvalidDynamicRoute",
319
329
  title: "Invalid dynamic route.",
@@ -646,6 +656,7 @@ export {
646
656
  AstroResponseHeadersReassigned,
647
657
  CSSSyntaxError,
648
658
  CantRenderPage,
659
+ CantUseAstroConfigModuleError,
649
660
  ClientAddressNotAvailable,
650
661
  ConfigLegacyKey,
651
662
  ConfigNotFound,
@@ -736,6 +747,7 @@ export {
736
747
  UnknownMarkdownError,
737
748
  UnknownViteError,
738
749
  UnsupportedConfigTransformError,
750
+ UnsupportedExternalRedirect,
739
751
  UnsupportedImageConversion,
740
752
  UnsupportedImageFormat,
741
753
  i18nNoLocaleFoundInPath,
@@ -38,7 +38,7 @@ function serverStart({
38
38
  host,
39
39
  base
40
40
  }) {
41
- const version = "5.1.10";
41
+ const version = "5.2.1";
42
42
  const localPrefix = `${dim("\u2503")} Local `;
43
43
  const networkPrefix = `${dim("\u2503")} Network `;
44
44
  const emptyPrefix = " ".repeat(11);
@@ -276,7 +276,7 @@ function printHelp({
276
276
  message.push(
277
277
  linebreak(),
278
278
  ` ${bgGreen(black(` ${commandName} `))} ${green(
279
- `v${"5.1.10"}`
279
+ `v${"5.2.1"}`
280
280
  )} ${headline}`
281
281
  );
282
282
  }
@@ -9,7 +9,7 @@ import { resolveConfig } from "../config/config.js";
9
9
  import { createNodeLogger } from "../config/logging.js";
10
10
  import { createSettings } from "../config/settings.js";
11
11
  import { apply as applyPolyfills } from "../polyfill.js";
12
- import { createRouteManifest } from "../routing/index.js";
12
+ import { createRoutesList } from "../routing/index.js";
13
13
  import { ensureProcessNodeEnv } from "../util.js";
14
14
  import createStaticPreviewServer from "./static-preview-server.js";
15
15
  import { getResolvedHostForHttpServer } from "./util.js";
@@ -25,7 +25,7 @@ async function preview(inlineConfig) {
25
25
  command: "preview",
26
26
  logger
27
27
  });
28
- await createRouteManifest({ settings, cwd: inlineConfig.root }, logger);
28
+ await createRoutesList({ settings, cwd: inlineConfig.root }, logger);
29
29
  await runHookConfigDone({ settings, logger, command: "preview" });
30
30
  if (settings.buildOutput === "static") {
31
31
  if (!fs.existsSync(settings.config.outDir)) {
@@ -1,2 +1,4 @@
1
+ import type { RedirectConfig } from '../../types/public/index.js';
1
2
  import type { RenderContext } from '../render-context.js';
3
+ export declare function redirectIsExternal(redirect: RedirectConfig): boolean;
2
4
  export declare function renderRedirect(renderContext: RenderContext): Promise<Response>;
@@ -1,3 +1,10 @@
1
+ function redirectIsExternal(redirect) {
2
+ if (typeof redirect === "string") {
3
+ return redirect.startsWith("http://") || redirect.startsWith("https://");
4
+ } else {
5
+ return redirect.destination.startsWith("http://") || redirect.destination.startsWith("https://");
6
+ }
7
+ }
1
8
  async function renderRedirect(renderContext) {
2
9
  const {
3
10
  request: { method },
@@ -6,6 +13,13 @@ async function renderRedirect(renderContext) {
6
13
  const { redirect, redirectRoute } = routeData;
7
14
  const status = redirectRoute && typeof redirect === "object" ? redirect.status : method === "GET" ? 301 : 308;
8
15
  const headers = { location: encodeURI(redirectRouteGenerate(renderContext)) };
16
+ if (redirect && redirectIsExternal(redirect)) {
17
+ if (typeof redirect === "string") {
18
+ return Response.redirect(redirect, status);
19
+ } else {
20
+ return Response.redirect(redirect.destination, status);
21
+ }
22
+ }
9
23
  return new Response(null, { status, headers });
10
24
  }
11
25
  function redirectRouteGenerate(renderContext) {
@@ -16,17 +30,22 @@ function redirectRouteGenerate(renderContext) {
16
30
  if (typeof redirectRoute !== "undefined") {
17
31
  return redirectRoute?.generate(params) || redirectRoute?.pathname || "/";
18
32
  } 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).replace(`[...${param}]`, paramValue);
33
+ if (redirectIsExternal(redirect)) {
34
+ return redirect;
35
+ } else {
36
+ let target = redirect;
37
+ for (const param of Object.keys(params)) {
38
+ const paramValue = params[param];
39
+ target = target.replace(`[${param}]`, paramValue).replace(`[...${param}]`, paramValue);
40
+ }
41
+ return target;
23
42
  }
24
- return target;
25
43
  } else if (typeof redirect === "undefined") {
26
44
  return "/";
27
45
  }
28
46
  return redirect.destination;
29
47
  }
30
48
  export {
49
+ redirectIsExternal,
31
50
  renderRedirect
32
51
  };
@@ -1,6 +1,6 @@
1
- import type { ComponentInstance, ManifestData } from '../../types/astro.js';
1
+ import type { ComponentInstance, RoutesList } from '../../types/astro.js';
2
2
  import type { RouteData } from '../../types/public/internal.js';
3
3
  export declare const DEFAULT_404_ROUTE: RouteData;
4
4
  export declare const DEFAULT_500_ROUTE: RouteData;
5
- export declare function ensure404Route(manifest: ManifestData): ManifestData;
5
+ export declare function ensure404Route(manifest: RoutesList): RoutesList;
6
6
  export declare const default404Instance: ComponentInstance;
@@ -1,4 +1,4 @@
1
- export { createRouteManifest } from './manifest/create.js';
1
+ export { createRoutesList } from './manifest/create.js';
2
2
  export { deserializeRouteData, serializeRouteData } from './manifest/serialization.js';
3
3
  export { matchAllRoutes, matchRoute } from './match.js';
4
4
  export { validateDynamicRouteModule, validateGetStaticPathsResult } from './validation.js';
@@ -1,9 +1,9 @@
1
- import { createRouteManifest } from "./manifest/create.js";
1
+ import { createRoutesList } from "./manifest/create.js";
2
2
  import { deserializeRouteData, serializeRouteData } from "./manifest/serialization.js";
3
3
  import { matchAllRoutes, matchRoute } from "./match.js";
4
4
  import { validateDynamicRouteModule, validateGetStaticPathsResult } from "./validation.js";
5
5
  export {
6
- createRouteManifest,
6
+ createRoutesList,
7
7
  deserializeRouteData,
8
8
  matchAllRoutes,
9
9
  matchRoute,
@@ -1,4 +1,4 @@
1
- import type { AstroSettings, ManifestData } from '../../../types/astro.js';
1
+ import type { AstroSettings, RoutesList } from '../../../types/astro.js';
2
2
  import type { Logger } from '../../logger/core.js';
3
3
  import nodeFs from 'node:fs';
4
4
  import type { RoutePart } from '../../../types/public/internal.js';
@@ -12,9 +12,9 @@ export interface CreateRouteManifestParams {
12
12
  fsMod?: typeof nodeFs;
13
13
  }
14
14
  /** Create manifest of all static routes */
15
- export declare function createRouteManifest(params: CreateRouteManifestParams, logger: Logger, { dev }?: {
15
+ export declare function createRoutesList(params: CreateRouteManifestParams, logger: Logger, { dev }?: {
16
16
  dev?: boolean;
17
- }): Promise<ManifestData>;
17
+ }): Promise<RoutesList>;
18
18
  export declare function resolveInjectedRoute(entrypoint: string, root: URL, cwd?: string): {
19
19
  resolved: string;
20
20
  component: string;
@@ -9,7 +9,10 @@ import { toRoutingStrategy } from "../../../i18n/utils.js";
9
9
  import { runHookRoutesResolved } from "../../../integrations/hooks.js";
10
10
  import { getPrerenderDefault } from "../../../prerender/utils.js";
11
11
  import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from "../../constants.js";
12
- import { MissingIndexForInternationalization } from "../../errors/errors-data.js";
12
+ import {
13
+ MissingIndexForInternationalization,
14
+ UnsupportedExternalRedirect
15
+ } from "../../errors/errors-data.js";
13
16
  import { AstroError } from "../../errors/index.js";
14
17
  import { removeLeadingForwardSlash, slash } from "../../path.js";
15
18
  import { injectServerIslandRoute } from "../../server-islands/endpoint.js";
@@ -213,7 +216,7 @@ function createInjectedRoutes({ settings, cwd }) {
213
216
  }
214
217
  return routes;
215
218
  }
216
- function createRedirectRoutes({ settings }, routeMap, logger) {
219
+ function createRedirectRoutes({ settings }, routeMap) {
217
220
  const { config } = settings;
218
221
  const trailingSlash = config.trailingSlash;
219
222
  const routes = [];
@@ -233,11 +236,10 @@ function createRedirectRoutes({ settings }, routeMap, logger) {
233
236
  } else {
234
237
  destination = to.destination;
235
238
  }
236
- if (/^https?:\/\//.test(destination)) {
237
- logger.warn(
238
- "redirects",
239
- `Redirecting to an external URL is not officially supported: ${from} -> ${destination}`
240
- );
239
+ if (!destination.startsWith("/")) {
240
+ if (!/^https?:\/\//.test(destination) && !URL.canParse(destination)) {
241
+ throw new AstroError(UnsupportedExternalRedirect);
242
+ }
241
243
  }
242
244
  routes.push({
243
245
  type: "redirect",
@@ -298,7 +300,7 @@ function detectRouteCollision(a, b, _config, logger) {
298
300
  );
299
301
  logger.warn("router", "A collision will result in an hard error in following versions of Astro.");
300
302
  }
301
- async function createRouteManifest(params, logger, { dev = false } = {}) {
303
+ async function createRoutesList(params, logger, { dev = false } = {}) {
302
304
  const { settings } = params;
303
305
  const { config } = settings;
304
306
  const routeMap = /* @__PURE__ */ new Map();
@@ -310,7 +312,7 @@ async function createRouteManifest(params, logger, { dev = false } = {}) {
310
312
  for (const route of injectedRoutes) {
311
313
  routeMap.set(route.route, route);
312
314
  }
313
- const redirectRoutes = createRedirectRoutes(params, routeMap, logger);
315
+ const redirectRoutes = createRedirectRoutes(params, routeMap);
314
316
  const filteredFiledBasedRoutes = fileBasedRoutes.filter((fileBasedRoute) => {
315
317
  const isRedirect = redirectRoutes.findIndex((rd) => rd.route === fileBasedRoute.route);
316
318
  return isRedirect < 0;
@@ -511,7 +513,7 @@ function joinSegments(segments) {
511
513
  return `/${arr.join("/")}`.toLowerCase();
512
514
  }
513
515
  export {
514
- createRouteManifest,
516
+ createRoutesList,
515
517
  getParts,
516
518
  resolveInjectedRoute
517
519
  };
@@ -1,9 +1,9 @@
1
- import type { ManifestData } from '../../types/astro.js';
1
+ import type { RoutesList } from '../../types/astro.js';
2
2
  import type { RouteData } from '../../types/public/internal.js';
3
3
  /** Find matching route from pathname */
4
- export declare function matchRoute(pathname: string, manifest: ManifestData): RouteData | undefined;
4
+ export declare function matchRoute(pathname: string, manifest: RoutesList): RouteData | undefined;
5
5
  /** Finds all matching routes from pathname */
6
- export declare function matchAllRoutes(pathname: string, manifest: ManifestData): RouteData[];
6
+ export declare function matchAllRoutes(pathname: string, manifest: RoutesList): RouteData[];
7
7
  export declare function isRoute404(route: string): boolean;
8
8
  export declare function isRoute500(route: string): boolean;
9
9
  /**
@@ -1,9 +1,9 @@
1
- import type { ComponentInstance, ManifestData } from '../../types/astro.js';
1
+ import type { ComponentInstance, RoutesList } from '../../types/astro.js';
2
2
  import type { RouteData, SSRManifest } from '../../types/public/internal.js';
3
3
  export declare const SERVER_ISLAND_ROUTE = "/_server-islands/[name]";
4
4
  export declare const SERVER_ISLAND_COMPONENT = "_server-islands.astro";
5
5
  type ConfigFields = Pick<SSRManifest, 'base' | 'trailingSlash'>;
6
6
  export declare function getServerIslandRouteData(config: ConfigFields): RouteData;
7
- export declare function injectServerIslandRoute(config: ConfigFields, routeManifest: ManifestData): void;
7
+ export declare function injectServerIslandRoute(config: ConfigFields, routeManifest: RoutesList): void;
8
8
  export declare function createEndpoint(manifest: SSRManifest): ComponentInstance;
9
9
  export {};
@@ -1,7 +1,8 @@
1
1
  import fsMod from 'node:fs';
2
2
  import { type FSWatcher } from 'vite';
3
- import type { AstroSettings, ManifestData } from '../../types/astro.js';
3
+ import type { AstroSettings, RoutesList } from '../../types/astro.js';
4
4
  import type { AstroInlineConfig } from '../../types/public/config.js';
5
+ import type { SSRManifest } from '../app/types.js';
5
6
  import type { Logger } from '../logger/core.js';
6
7
  export type SyncOptions = {
7
8
  mode: string;
@@ -12,7 +13,8 @@ export type SyncOptions = {
12
13
  content?: boolean;
13
14
  cleanup?: boolean;
14
15
  };
15
- manifest: ManifestData;
16
+ routesList: RoutesList;
17
+ manifest: SSRManifest;
16
18
  command: 'build' | 'dev' | 'sync';
17
19
  watcher?: FSWatcher;
18
20
  };
@@ -35,4 +37,4 @@ export declare function clearContentLayerCache({ settings, logger, fs, isDev, }:
35
37
  *
36
38
  * @experimental The JavaScript API is experimental
37
39
  */
38
- export declare function syncInternal({ mode, logger, fs, settings, skip, force, manifest, command, watcher, }: SyncOptions): Promise<void>;
40
+ export declare function syncInternal({ mode, logger, fs, settings, skip, force, routesList, command, watcher, manifest, }: SyncOptions): Promise<void>;