astro 5.3.1 → 5.4.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 (45) hide show
  1. package/components/Image.astro +1 -9
  2. package/components/Picture.astro +6 -11
  3. package/dist/assets/endpoint/generic.js +1 -1
  4. package/dist/assets/endpoint/node.js +1 -1
  5. package/dist/assets/internal.js +13 -0
  6. package/dist/assets/services/service.js +1 -1
  7. package/dist/assets/utils/imageAttributes.d.ts +1 -9
  8. package/dist/assets/utils/imageAttributes.js +2 -21
  9. package/dist/assets/utils/index.d.ts +1 -1
  10. package/dist/assets/utils/index.js +3 -3
  11. package/dist/assets/utils/remotePattern.d.ts +3 -13
  12. package/dist/assets/utils/remotePattern.js +8 -48
  13. package/dist/cli/dev/index.js +4 -0
  14. package/dist/cli/flags.js +2 -1
  15. package/dist/cli/preview/index.js +4 -0
  16. package/dist/config/entrypoint.d.ts +2 -0
  17. package/dist/config/entrypoint.js +5 -1
  18. package/dist/content/content-layer.js +3 -3
  19. package/dist/content/runtime.js +10 -5
  20. package/dist/core/app/index.js +1 -1
  21. package/dist/core/build/generate.js +1 -1
  22. package/dist/core/build/index.d.ts +10 -0
  23. package/dist/core/config/merge.d.ts +3 -1
  24. package/dist/core/config/merge.js +2 -2
  25. package/dist/core/config/schema.d.ts +18 -0
  26. package/dist/core/config/schema.js +6 -3
  27. package/dist/core/constants.js +1 -1
  28. package/dist/core/dev/container.js +2 -2
  29. package/dist/core/dev/dev.js +1 -1
  30. package/dist/core/index.d.ts +1 -7
  31. package/dist/core/index.js +6 -7
  32. package/dist/core/messages.js +2 -2
  33. package/dist/core/preview/static-preview-server.js +2 -1
  34. package/dist/core/routing/match.js +2 -3
  35. package/dist/core/session.d.ts +2 -2
  36. package/dist/integrations/hooks.js +2 -1
  37. package/dist/transitions/router.js +1 -1
  38. package/dist/types/public/config.d.ts +20 -1
  39. package/dist/types/public/extendables.d.ts +5 -0
  40. package/dist/types/public/index.d.ts +1 -1
  41. package/dist/vite-plugin-markdown/content-entry-type.js +8 -2
  42. package/dist/vite-plugin-markdown/images.d.ts +1 -1
  43. package/dist/vite-plugin-markdown/images.js +20 -3
  44. package/dist/vite-plugin-markdown/index.js +14 -6
  45. package/package.json +7 -7
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  import { type LocalImageProps, type RemoteImageProps, getImage, imageConfig } from 'astro:assets';
3
3
  import type { UnresolvedImageTransform } from '../dist/assets/types';
4
- import { applyResponsiveAttributes } from '../dist/assets/utils/imageAttributes.js';
5
4
  import { AstroError, AstroErrorData } from '../dist/core/errors/index.js';
6
5
  import type { HTMLAttributes } from '../types';
7
6
 
@@ -46,14 +45,7 @@ if (import.meta.env.DEV) {
46
45
  additionalAttributes['data-image-component'] = 'true';
47
46
  }
48
47
 
49
- const { class: className, ...attributes } = useResponsive
50
- ? applyResponsiveAttributes({
51
- layout,
52
- image,
53
- props,
54
- additionalAttributes,
55
- })
56
- : { ...additionalAttributes, ...image.attributes };
48
+ const { class: className, ...attributes } = { ...additionalAttributes, ...image.attributes };
57
49
  ---
58
50
 
59
51
  {/* Applying class outside of the spread prevents it from applying unnecessary astro-* classes */}
@@ -1,8 +1,7 @@
1
1
  ---
2
2
  import { type LocalImageProps, type RemoteImageProps, getImage, imageConfig } from 'astro:assets';
3
3
  import * as mime from 'mrmime';
4
- import { applyResponsiveAttributes } from '../dist/assets/utils/imageAttributes';
5
- import { isESMImportedImage, resolveSrc } from '../dist/assets/utils/imageKind';
4
+ import { isESMImportedImage, resolveSrc } from '../dist/assets/utils/imageKind.js';
6
5
  import { AstroError, AstroErrorData } from '../dist/core/errors/index.js';
7
6
  import type {
8
7
  GetImageResult,
@@ -101,18 +100,14 @@ if (fallbackImage.srcSet.values.length > 0) {
101
100
  imgAdditionalAttributes.srcset = fallbackImage.srcSet.attribute;
102
101
  }
103
102
 
104
- const { class: className, ...attributes } = useResponsive
105
- ? applyResponsiveAttributes({
106
- layout,
107
- image: fallbackImage,
108
- props,
109
- additionalAttributes: imgAdditionalAttributes,
110
- })
111
- : { ...imgAdditionalAttributes, ...fallbackImage.attributes };
112
-
113
103
  if (import.meta.env.DEV) {
114
104
  imgAdditionalAttributes['data-image-component'] = 'true';
115
105
  }
106
+
107
+ const { class: className, ...attributes } = {
108
+ ...imgAdditionalAttributes,
109
+ ...fallbackImage.attributes,
110
+ };
116
111
  ---
117
112
 
118
113
  <picture {...pictureAttributes}>
@@ -1,9 +1,9 @@
1
1
  import { imageConfig } from "astro:assets";
2
2
  import { isRemotePath } from "@astrojs/internal-helpers/path";
3
+ import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
3
4
  import * as mime from "mrmime";
4
5
  import { getConfiguredImageService } from "../internal.js";
5
6
  import { etag } from "../utils/etag.js";
6
- import { isRemoteAllowed } from "../utils/remotePattern.js";
7
7
  async function loadRemoteImage(src, headers) {
8
8
  try {
9
9
  const res = await fetch(src, {
@@ -4,10 +4,10 @@ import { isAbsolute } from "node:path";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
5
5
  import { assetsDir, imageConfig, outDir } from "astro:assets";
6
6
  import { isRemotePath, removeQueryString } from "@astrojs/internal-helpers/path";
7
+ import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
7
8
  import * as mime from "mrmime";
8
9
  import { getConfiguredImageService } from "../internal.js";
9
10
  import { etag } from "../utils/etag.js";
10
- import { isRemoteAllowed } from "../utils/remotePattern.js";
11
11
  function replaceFileSystemReferences(src) {
12
12
  return os.platform().includes("win32") ? src.replace(/^\/@fs\//, "") : src.replace(/^\/@fs/, "");
13
13
  }
@@ -11,6 +11,7 @@ import { isLocalService } from "./services/service.js";
11
11
  import {
12
12
  isImageMetadata
13
13
  } from "./types.js";
14
+ import { addCSSVarsToStyle, cssFitValues } from "./utils/imageAttributes.js";
14
15
  import { isESMImportedImage, isRemoteImage, resolveSrc } from "./utils/imageKind.js";
15
16
  import { inferRemoteSize } from "./utils/remoteProbe.js";
16
17
  async function getConfiguredImageService() {
@@ -108,6 +109,18 @@ async function getImage(options, imageConfig) {
108
109
  }
109
110
  delete resolvedOptions.priority;
110
111
  delete resolvedOptions.densities;
112
+ if (layout !== "none") {
113
+ resolvedOptions.style = addCSSVarsToStyle(
114
+ {
115
+ w: String(resolvedOptions.width),
116
+ h: String(resolvedOptions.height),
117
+ fit: cssFitValues.includes(resolvedOptions.fit ?? "") && resolvedOptions.fit,
118
+ pos: resolvedOptions.position
119
+ },
120
+ resolvedOptions.style
121
+ );
122
+ resolvedOptions["data-astro-image"] = layout;
123
+ }
111
124
  }
112
125
  const validatedOptions = service.validateOptions ? await service.validateOptions(resolvedOptions, imageConfig) : resolvedOptions;
113
126
  const srcSetTransforms = service.getSrcSet ? await service.getSrcSet(validatedOptions, imageConfig) : [];
@@ -1,8 +1,8 @@
1
+ import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
1
2
  import { AstroError, AstroErrorData } from "../../core/errors/index.js";
2
3
  import { isRemotePath, joinPaths } from "../../core/path.js";
3
4
  import { DEFAULT_HASH_PROPS, DEFAULT_OUTPUT_FORMAT, VALID_SUPPORTED_FORMATS } from "../consts.js";
4
5
  import { isESMImportedImage, isRemoteImage } from "../utils/imageKind.js";
5
- import { isRemoteAllowed } from "../utils/remotePattern.js";
6
6
  function isLocalService(service) {
7
7
  if (!service) {
8
8
  return false;
@@ -1,10 +1,2 @@
1
- import type { GetImageResult, ImageLayout, LocalImageProps, RemoteImageProps } from '../types.js';
1
+ export declare const cssFitValues: string[];
2
2
  export declare function addCSSVarsToStyle(vars: Record<string, string | false | undefined>, styles?: string | Record<string, any>): string;
3
- export declare function applyResponsiveAttributes<T extends LocalImageProps<unknown> | RemoteImageProps<unknown>>({ layout, image, props, additionalAttributes, }: {
4
- layout: Exclude<ImageLayout, 'none'>;
5
- image: GetImageResult;
6
- additionalAttributes: Record<string, any>;
7
- props: T;
8
- }): {
9
- [x: string]: any;
10
- };
@@ -1,4 +1,5 @@
1
1
  import { toStyleString } from "../../runtime/server/render/util.js";
2
+ const cssFitValues = ["fill", "contain", "cover", "scale-down"];
2
3
  function addCSSVarsToStyle(vars, styles) {
3
4
  const cssVars = Object.entries(vars).filter(([_, value]) => value !== void 0 && value !== false).map(([key, value]) => `--${key}: ${value};`).join(" ");
4
5
  if (!styles) {
@@ -7,27 +8,7 @@ function addCSSVarsToStyle(vars, styles) {
7
8
  const style = typeof styles === "string" ? styles : toStyleString(styles);
8
9
  return `${cssVars} ${style}`;
9
10
  }
10
- const cssFitValues = ["fill", "contain", "cover", "scale-down"];
11
- function applyResponsiveAttributes({
12
- layout,
13
- image,
14
- props,
15
- additionalAttributes
16
- }) {
17
- const attributes = { ...additionalAttributes, ...image.attributes };
18
- attributes.style = addCSSVarsToStyle(
19
- {
20
- w: image.attributes.width ?? props.width ?? image.options.width,
21
- h: image.attributes.height ?? props.height ?? image.options.height,
22
- fit: cssFitValues.includes(props.fit ?? "") && props.fit,
23
- pos: props.position
24
- },
25
- attributes.style
26
- );
27
- attributes["data-astro-image"] = layout;
28
- return attributes;
29
- }
30
11
  export {
31
12
  addCSSVarsToStyle,
32
- applyResponsiveAttributes
13
+ cssFitValues
33
14
  };
@@ -2,7 +2,7 @@ export { emitESMImage } from './node/emitAsset.js';
2
2
  export { isESMImportedImage, isRemoteImage } from './imageKind.js';
3
3
  export { imageMetadata } from './metadata.js';
4
4
  export { getOrigQueryParams } from './queryParams.js';
5
- export { isRemoteAllowed, matchHostname, matchPathname, matchPattern, matchPort, matchProtocol, type RemotePattern, } from './remotePattern.js';
6
5
  export { hashTransform, propsToFilename } from './transformToPath.js';
7
6
  export { inferRemoteSize } from './remoteProbe.js';
8
7
  export { makeSvgComponent } from './svg.js';
8
+ export { isRemoteAllowed, matchHostname, matchPathname, matchPattern, matchPort, matchProtocol, type RemotePattern, } from './remotePattern.js';
@@ -2,6 +2,9 @@ import { emitESMImage } from "./node/emitAsset.js";
2
2
  import { isESMImportedImage, isRemoteImage } from "./imageKind.js";
3
3
  import { imageMetadata } from "./metadata.js";
4
4
  import { getOrigQueryParams } from "./queryParams.js";
5
+ import { hashTransform, propsToFilename } from "./transformToPath.js";
6
+ import { inferRemoteSize } from "./remoteProbe.js";
7
+ import { makeSvgComponent } from "./svg.js";
5
8
  import {
6
9
  isRemoteAllowed,
7
10
  matchHostname,
@@ -10,9 +13,6 @@ import {
10
13
  matchPort,
11
14
  matchProtocol
12
15
  } from "./remotePattern.js";
13
- import { hashTransform, propsToFilename } from "./transformToPath.js";
14
- import { inferRemoteSize } from "./remoteProbe.js";
15
- import { makeSvgComponent } from "./svg.js";
16
16
  export {
17
17
  emitESMImage,
18
18
  getOrigQueryParams,
@@ -1,13 +1,3 @@
1
- import type { AstroConfig } from '../../types/public/config.js';
2
- export type RemotePattern = {
3
- hostname?: string;
4
- pathname?: string;
5
- protocol?: string;
6
- port?: string;
7
- };
8
- export declare function matchPattern(url: URL, remotePattern: RemotePattern): boolean;
9
- export declare function matchPort(url: URL, port?: string): boolean;
10
- export declare function matchProtocol(url: URL, protocol?: string): boolean;
11
- export declare function matchHostname(url: URL, hostname?: string, allowWildcard?: boolean): boolean;
12
- export declare function matchPathname(url: URL, pathname?: string, allowWildcard?: boolean): boolean;
13
- export declare function isRemoteAllowed(src: string, { domains, remotePatterns, }: Partial<Pick<AstroConfig['image'], 'domains' | 'remotePatterns'>>): boolean;
1
+ import { type RemotePattern, isRemoteAllowed, matchHostname, matchPathname, matchPattern, matchPort, matchProtocol } from '@astrojs/internal-helpers/remote';
2
+ export { isRemoteAllowed, matchHostname, matchPort, matchPathname, matchProtocol, matchPattern };
3
+ export type { RemotePattern };
@@ -1,51 +1,11 @@
1
- import { isRemotePath } from "@astrojs/internal-helpers/path";
2
- function matchPattern(url, remotePattern) {
3
- return matchProtocol(url, remotePattern.protocol) && matchHostname(url, remotePattern.hostname, true) && matchPort(url, remotePattern.port) && matchPathname(url, remotePattern.pathname, true);
4
- }
5
- function matchPort(url, port) {
6
- return !port || port === url.port;
7
- }
8
- function matchProtocol(url, protocol) {
9
- return !protocol || protocol === url.protocol.slice(0, -1);
10
- }
11
- function matchHostname(url, hostname, allowWildcard) {
12
- if (!hostname) {
13
- return true;
14
- } else if (!allowWildcard || !hostname.startsWith("*")) {
15
- return hostname === url.hostname;
16
- } else if (hostname.startsWith("**.")) {
17
- const slicedHostname = hostname.slice(2);
18
- return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname);
19
- } else if (hostname.startsWith("*.")) {
20
- const slicedHostname = hostname.slice(1);
21
- const additionalSubdomains = url.hostname.replace(slicedHostname, "").split(".").filter(Boolean);
22
- return additionalSubdomains.length === 1;
23
- }
24
- return false;
25
- }
26
- function matchPathname(url, pathname, allowWildcard) {
27
- if (!pathname) {
28
- return true;
29
- } else if (!allowWildcard || !pathname.endsWith("*")) {
30
- return pathname === url.pathname;
31
- } else if (pathname.endsWith("/**")) {
32
- const slicedPathname = pathname.slice(0, -2);
33
- return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname);
34
- } else if (pathname.endsWith("/*")) {
35
- const slicedPathname = pathname.slice(0, -1);
36
- const additionalPathChunks = url.pathname.replace(slicedPathname, "").split("/").filter(Boolean);
37
- return additionalPathChunks.length === 1;
38
- }
39
- return false;
40
- }
41
- function isRemoteAllowed(src, {
42
- domains = [],
43
- remotePatterns = []
44
- }) {
45
- if (!isRemotePath(src)) return false;
46
- const url = new URL(src);
47
- return domains.some((domain) => matchHostname(url, domain)) || remotePatterns.some((remotePattern) => matchPattern(url, remotePattern));
48
- }
1
+ import {
2
+ isRemoteAllowed,
3
+ matchHostname,
4
+ matchPathname,
5
+ matchPattern,
6
+ matchPort,
7
+ matchProtocol
8
+ } from "@astrojs/internal-helpers/remote";
49
9
  export {
50
10
  isRemoteAllowed,
51
11
  matchHostname,
@@ -15,6 +15,10 @@ async function dev({ flags }) {
15
15
  ["--host <custom-address>", `Expose on a network IP address at <custom-address>`],
16
16
  ["--open", "Automatically open the app in the browser on server start"],
17
17
  ["--force", "Clear the content layer cache, forcing a full rebuild."],
18
+ [
19
+ "--allowed-hosts",
20
+ "Specify a comma-separated list of allowed hosts or allow any hostname."
21
+ ],
18
22
  ["--help (-h)", "See all available flags."]
19
23
  ]
20
24
  },
package/dist/cli/flags.js CHANGED
@@ -15,7 +15,8 @@ function flagsToAstroInlineConfig(flags) {
15
15
  server: {
16
16
  port: typeof flags.port === "number" ? flags.port : void 0,
17
17
  host: typeof flags.host === "string" || typeof flags.host === "boolean" ? flags.host : void 0,
18
- open: typeof flags.open === "string" || typeof flags.open === "boolean" ? flags.open : void 0
18
+ open: typeof flags.open === "string" || typeof flags.open === "boolean" ? flags.open : void 0,
19
+ allowedHosts: typeof flags.allowedHosts === "string" ? flags.allowedHosts.split(",") : typeof flags.allowedHosts === "boolean" && flags.allowedHosts === true ? flags.allowedHosts : []
19
20
  }
20
21
  };
21
22
  }
@@ -13,6 +13,10 @@ async function preview({ flags }) {
13
13
  ["--host", `Listen on all addresses, including LAN and public addresses.`],
14
14
  ["--host <custom-address>", `Expose on a network IP address at <custom-address>`],
15
15
  ["--open", "Automatically open the app in the browser on server start"],
16
+ [
17
+ "--allowed-hosts",
18
+ "Specify a comma-separated list of allowed hosts or allow any hostname."
19
+ ],
16
20
  ["--help (-h)", "See all available flags."]
17
21
  ]
18
22
  },
@@ -2,6 +2,8 @@ import type { SharpImageServiceConfig } from '../assets/services/sharp.js';
2
2
  import type { ImageServiceConfig } from '../types/public/index.js';
3
3
  export { defineConfig, getViteConfig } from './index.js';
4
4
  export { envField } from '../env/config.js';
5
+ export { mergeConfig } from '../core/config/merge.js';
6
+ export { validateConfig } from '../core/config/validate.js';
5
7
  /**
6
8
  * Return the configuration needed to use the Sharp-based image service
7
9
  */
@@ -1,5 +1,7 @@
1
1
  import { defineConfig, getViteConfig } from "./index.js";
2
2
  import { envField } from "../env/config.js";
3
+ import { mergeConfig } from "../core/config/merge.js";
4
+ import { validateConfig } from "../core/config/validate.js";
3
5
  function sharpImageService(config = {}) {
4
6
  return {
5
7
  entrypoint: "astro/assets/services/sharp",
@@ -16,6 +18,8 @@ export {
16
18
  defineConfig,
17
19
  envField,
18
20
  getViteConfig,
21
+ mergeConfig,
19
22
  passthroughImageService,
20
- sharpImageService
23
+ sharpImageService,
24
+ validateConfig
21
25
  };
@@ -153,7 +153,7 @@ ${contentConfig.error.message}`);
153
153
  logger.info("Content config changed");
154
154
  shouldClear = true;
155
155
  }
156
- if (previousAstroVersion && previousAstroVersion !== "5.3.1") {
156
+ if (previousAstroVersion && previousAstroVersion !== "5.4.1") {
157
157
  logger.info("Astro version changed");
158
158
  shouldClear = true;
159
159
  }
@@ -161,8 +161,8 @@ ${contentConfig.error.message}`);
161
161
  logger.info("Clearing content store");
162
162
  this.#store.clearAll();
163
163
  }
164
- if ("5.3.1") {
165
- await this.#store.metaStore().set("astro-version", "5.3.1");
164
+ if ("5.4.1") {
165
+ await this.#store.metaStore().set("astro-version", "5.4.1");
166
166
  }
167
167
  if (currentConfigDigest) {
168
168
  await this.#store.metaStore().set("content-config-digest", currentConfigDigest);
@@ -298,12 +298,17 @@ async function updateImageReferencesInBody(html, fileName) {
298
298
  for (const [_full, imagePath] of html.matchAll(CONTENT_LAYER_IMAGE_REGEX)) {
299
299
  try {
300
300
  const decodedImagePath = JSON.parse(imagePath.replaceAll("&#x22;", '"'));
301
- const id = imageSrcToImportId(decodedImagePath.src, fileName);
302
- const imported = imageAssetMap.get(id);
303
- if (!id || imageObjects.has(id) || !imported) {
304
- continue;
301
+ let image;
302
+ if (URL.canParse(decodedImagePath.src)) {
303
+ image = await getImage(decodedImagePath);
304
+ } else {
305
+ const id = imageSrcToImportId(decodedImagePath.src, fileName);
306
+ const imported = imageAssetMap.get(id);
307
+ if (!id || imageObjects.has(id) || !imported) {
308
+ continue;
309
+ }
310
+ image = await getImage({ ...decodedImagePath, src: imported });
305
311
  }
306
- const image = await getImage({ ...decodedImagePath, src: imported });
307
312
  imageObjects.set(imagePath, image);
308
313
  } catch {
309
314
  throw new Error(`Failed to parse image reference: ${imagePath}`);
@@ -115,7 +115,7 @@ class App {
115
115
  if (!pathname) {
116
116
  pathname = prependForwardSlash(this.removeBase(url.pathname));
117
117
  }
118
- let routeData = matchRoute(pathname, this.#manifestData);
118
+ let routeData = matchRoute(decodeURI(pathname), this.#manifestData);
119
119
  if (!routeData || routeData.prerender) return void 0;
120
120
  return routeData;
121
121
  }
@@ -208,7 +208,7 @@ async function getPathsForRoute(route, mod, pipeline, builtPaths) {
208
208
  if (!builtPaths.has(removeTrailingForwardSlash(staticPath))) {
209
209
  return true;
210
210
  }
211
- const matchedRoute = matchRoute(staticPath, options.routesList);
211
+ const matchedRoute = matchRoute(decodeURI(staticPath), options.routesList);
212
212
  return matchedRoute === route;
213
213
  });
214
214
  for (const staticPath of paths) {
@@ -7,6 +7,16 @@ export interface BuildOptions {
7
7
  * @default false
8
8
  */
9
9
  devOutput?: boolean;
10
+ /**
11
+ * Teardown the compiler WASM instance after build. This can improve performance when
12
+ * building once, but may cause a performance hit if building multiple times in a row.
13
+ *
14
+ * When building multiple projects in the same execution (e.g. during tests), disabling
15
+ * this option can greatly improve performance at the cost of some extra memory usage.
16
+ *
17
+ * @default true
18
+ */
19
+ teardownCompiler?: boolean;
10
20
  }
11
21
  /**
12
22
  * Builds your site for deployment. By default, this will generate static files and place them in a dist/ directory.
@@ -1 +1,3 @@
1
- export declare function mergeConfig(defaults: Record<string, any>, overrides: Record<string, any>, isRoot?: boolean): Record<string, any>;
1
+ import type { DeepPartial } from '../../type-utils.js';
2
+ import type { AstroConfig, AstroInlineConfig } from '../../types/public/index.js';
3
+ export declare function mergeConfig<C extends AstroConfig | AstroInlineConfig>(defaults: C, overrides: DeepPartial<C>): C;
@@ -47,8 +47,8 @@ function mergeConfigRecursively(defaults, overrides, rootPath) {
47
47
  }
48
48
  return merged;
49
49
  }
50
- function mergeConfig(defaults, overrides, isRoot = true) {
51
- return mergeConfigRecursively(defaults, overrides, isRoot ? "" : ".");
50
+ function mergeConfig(defaults, overrides) {
51
+ return mergeConfigRecursively(defaults, overrides, "");
52
52
  }
53
53
  export {
54
54
  mergeConfig
@@ -48,6 +48,7 @@ export declare const ASTRO_CONFIG_DEFAULTS: {
48
48
  host: false;
49
49
  port: number;
50
50
  open: false;
51
+ allowedHosts: never[];
51
52
  };
52
53
  integrations: never[];
53
54
  markdown: Required<import("@astrojs/markdown-remark").AstroMarkdownOptions>;
@@ -164,19 +165,23 @@ export declare const AstroConfigSchema: z.ZodObject<{
164
165
  host: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodBoolean]>>>;
165
166
  port: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
166
167
  headers: z.ZodOptional<z.ZodType<OutgoingHttpHeaders, z.ZodTypeDef, OutgoingHttpHeaders>>;
168
+ allowedHosts: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodLiteral<true>]>>>;
167
169
  }, "strip", z.ZodTypeAny, {
168
170
  host: string | boolean;
169
171
  port: number;
172
+ allowedHosts: true | string[];
170
173
  open: string | boolean;
171
174
  headers?: OutgoingHttpHeaders | undefined;
172
175
  }, {
173
176
  headers?: OutgoingHttpHeaders | undefined;
174
177
  host?: string | boolean | undefined;
175
178
  port?: number | undefined;
179
+ allowedHosts?: true | string[] | undefined;
176
180
  open?: string | boolean | undefined;
177
181
  }>>, {
178
182
  host: string | boolean;
179
183
  port: number;
184
+ allowedHosts: true | string[];
180
185
  open: string | boolean;
181
186
  headers?: OutgoingHttpHeaders | undefined;
182
187
  }, unknown>;
@@ -783,6 +788,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
783
788
  server: {
784
789
  host: string | boolean;
785
790
  port: number;
791
+ allowedHosts: true | string[];
786
792
  open: string | boolean;
787
793
  headers?: OutgoingHttpHeaders | undefined;
788
794
  };
@@ -1215,19 +1221,23 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
1215
1221
  host: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodBoolean]>>>;
1216
1222
  port: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
1217
1223
  headers: z.ZodOptional<z.ZodType<OutgoingHttpHeaders, z.ZodTypeDef, OutgoingHttpHeaders>>;
1224
+ allowedHosts: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodLiteral<true>]>>>;
1218
1225
  }, "strip", z.ZodTypeAny, {
1219
1226
  host: string | boolean;
1220
1227
  port: number;
1228
+ allowedHosts: true | string[];
1221
1229
  open: string | boolean;
1222
1230
  headers?: OutgoingHttpHeaders | undefined;
1223
1231
  }, {
1224
1232
  headers?: OutgoingHttpHeaders | undefined;
1225
1233
  host?: string | boolean | undefined;
1226
1234
  port?: number | undefined;
1235
+ allowedHosts?: true | string[] | undefined;
1227
1236
  open?: string | boolean | undefined;
1228
1237
  }>>, {
1229
1238
  host: string | boolean;
1230
1239
  port: number;
1240
+ allowedHosts: true | string[];
1231
1241
  open: string | boolean;
1232
1242
  headers?: OutgoingHttpHeaders | undefined;
1233
1243
  }, unknown>;
@@ -1887,9 +1897,11 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
1887
1897
  port: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
1888
1898
  headers: z.ZodOptional<z.ZodType<OutgoingHttpHeaders, z.ZodTypeDef, OutgoingHttpHeaders>>;
1889
1899
  streaming: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
1900
+ allowedHosts: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodLiteral<true>]>>>;
1890
1901
  }, "strip", z.ZodTypeAny, {
1891
1902
  host: string | boolean;
1892
1903
  port: number;
1904
+ allowedHosts: true | string[];
1893
1905
  open: string | boolean;
1894
1906
  streaming: boolean;
1895
1907
  headers?: OutgoingHttpHeaders | undefined;
@@ -1897,11 +1909,13 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
1897
1909
  headers?: OutgoingHttpHeaders | undefined;
1898
1910
  host?: string | boolean | undefined;
1899
1911
  port?: number | undefined;
1912
+ allowedHosts?: true | string[] | undefined;
1900
1913
  open?: string | boolean | undefined;
1901
1914
  streaming?: boolean | undefined;
1902
1915
  }>>>, {
1903
1916
  host: string | boolean;
1904
1917
  port: number;
1918
+ allowedHosts: true | string[];
1905
1919
  open: string | boolean;
1906
1920
  streaming: boolean;
1907
1921
  headers?: OutgoingHttpHeaders | undefined;
@@ -1911,6 +1925,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
1911
1925
  server: {
1912
1926
  host: string | boolean;
1913
1927
  port: number;
1928
+ allowedHosts: true | string[];
1914
1929
  open: string | boolean;
1915
1930
  streaming: boolean;
1916
1931
  headers?: OutgoingHttpHeaders | undefined;
@@ -2256,6 +2271,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2256
2271
  server: {
2257
2272
  host: string | boolean;
2258
2273
  port: number;
2274
+ allowedHosts: true | string[];
2259
2275
  open: string | boolean;
2260
2276
  streaming: boolean;
2261
2277
  headers?: OutgoingHttpHeaders | undefined;
@@ -2601,6 +2617,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2601
2617
  server: {
2602
2618
  host: string | boolean;
2603
2619
  port: number;
2620
+ allowedHosts: true | string[];
2604
2621
  open: string | boolean;
2605
2622
  streaming: boolean;
2606
2623
  headers?: OutgoingHttpHeaders | undefined;
@@ -2946,6 +2963,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2946
2963
  server: {
2947
2964
  host: string | boolean;
2948
2965
  port: number;
2966
+ allowedHosts: true | string[];
2949
2967
  open: string | boolean;
2950
2968
  streaming: boolean;
2951
2969
  headers?: OutgoingHttpHeaders | undefined;
@@ -34,7 +34,8 @@ const ASTRO_CONFIG_DEFAULTS = {
34
34
  server: {
35
35
  host: false,
36
36
  port: 4321,
37
- open: false
37
+ open: false,
38
+ allowedHosts: []
38
39
  },
39
40
  integrations: [],
40
41
  markdown: markdownConfigDefaults,
@@ -112,7 +113,8 @@ const AstroConfigSchema = z.object({
112
113
  open: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.open),
113
114
  host: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.host),
114
115
  port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
115
- headers: z.custom().optional()
116
+ headers: z.custom().optional(),
117
+ allowedHosts: z.union([z.array(z.string()), z.literal(true)]).optional().default(ASTRO_CONFIG_DEFAULTS.server.allowedHosts)
116
118
  }).default({})
117
119
  ),
118
120
  redirects: z.record(
@@ -447,7 +449,8 @@ function createRelativeSchema(cmd, fileProtocolRoot) {
447
449
  host: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.host),
448
450
  port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
449
451
  headers: z.custom().optional(),
450
- streaming: z.boolean().optional().default(true)
452
+ streaming: z.boolean().optional().default(true),
453
+ allowedHosts: z.union([z.array(z.string()), z.literal(true)]).optional().default(ASTRO_CONFIG_DEFAULTS.server.allowedHosts)
451
454
  }).optional().default({})
452
455
  )
453
456
  }).transform((config) => {
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "5.3.1";
1
+ const ASTRO_VERSION = "5.4.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";
@@ -28,7 +28,7 @@ async function createContainer({
28
28
  });
29
29
  const {
30
30
  base,
31
- server: { host, headers, open: serverOpen }
31
+ server: { host, headers, open: serverOpen, allowedHosts }
32
32
  } = settings.config;
33
33
  const isServerOpenURL = typeof serverOpen == "string" && !isRestart;
34
34
  const isServerOpenBoolean = serverOpen && !isRestart;
@@ -41,7 +41,7 @@ async function createContainer({
41
41
  const mode = inlineConfig?.mode ?? "development";
42
42
  const viteConfig = await createVite(
43
43
  {
44
- server: { host, headers, open },
44
+ server: { host, headers, open, allowedHosts },
45
45
  optimizeDeps: {
46
46
  include: rendererClientEntries
47
47
  }
@@ -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.3.1";
25
+ const currentVersion = "5.4.1";
26
26
  const isPrerelease = currentVersion.includes("-");
27
27
  if (!isPrerelease) {
28
28
  try {
@@ -1,13 +1,7 @@
1
1
  import type { AstroInlineConfig } from '../types/public/config.js';
2
+ export { default as build } from './build/index.js';
2
3
  export { default as dev } from './dev/index.js';
3
4
  export { default as preview } from './preview/index.js';
4
- /**
5
- * Builds your site for deployment. By default, this will generate static files and place them in a dist/ directory.
6
- * If SSR is enabled, this will generate the necessary server files to serve your site.
7
- *
8
- * @experimental The JavaScript API is experimental
9
- */
10
- export declare const build: (inlineConfig: AstroInlineConfig) => Promise<void>;
11
5
  /**
12
6
  * Generates TypeScript types for all Astro modules. This sets up a `src/env.d.ts` file for type inferencing,
13
7
  * and defines the `astro:content` module for the Content Collections API.
@@ -1,12 +1,11 @@
1
- import { default as _build } from "./build/index.js";
2
1
  import { default as _sync } from "./sync/index.js";
3
- import { default as default2 } from "./dev/index.js";
4
- import { default as default3 } from "./preview/index.js";
5
- const build = (inlineConfig) => _build(inlineConfig);
2
+ import { default as default2 } from "./build/index.js";
3
+ import { default as default3 } from "./dev/index.js";
4
+ import { default as default4 } from "./preview/index.js";
6
5
  const sync = (inlineConfig) => _sync(inlineConfig);
7
6
  export {
8
- build,
9
- default2 as dev,
10
- default3 as preview,
7
+ default2 as build,
8
+ default3 as dev,
9
+ default4 as preview,
11
10
  sync
12
11
  };
@@ -38,7 +38,7 @@ function serverStart({
38
38
  host,
39
39
  base
40
40
  }) {
41
- const version = "5.3.1";
41
+ const version = "5.4.1";
42
42
  const localPrefix = `${dim("\u2503")} Local `;
43
43
  const networkPrefix = `${dim("\u2503")} Network `;
44
44
  const emptyPrefix = " ".repeat(11);
@@ -281,7 +281,7 @@ function printHelp({
281
281
  message.push(
282
282
  linebreak(),
283
283
  ` ${bgGreen(black(` ${commandName} `))} ${green(
284
- `v${"5.3.1"}`
284
+ `v${"5.4.1"}`
285
285
  )} ${headline}`
286
286
  );
287
287
  }
@@ -19,7 +19,8 @@ async function createStaticPreviewServer(settings, logger) {
19
19
  host: settings.config.server.host,
20
20
  port: settings.config.server.port,
21
21
  headers: settings.config.server.headers,
22
- open: settings.config.server.open
22
+ open: settings.config.server.open,
23
+ allowedHosts: settings.config.server.allowedHosts
23
24
  },
24
25
  plugins: [vitePluginAstroPreview(settings)]
25
26
  });
@@ -1,13 +1,12 @@
1
1
  import { redirectIsExternal } from "../redirects/render.js";
2
2
  import { SERVER_ISLAND_BASE_PREFIX, SERVER_ISLAND_COMPONENT } from "../server-islands/endpoint.js";
3
3
  function matchRoute(pathname, manifest) {
4
- const decodedPathname = decodeURI(pathname);
5
4
  return manifest.routes.find((route) => {
6
- return route.pattern.test(decodedPathname) || route.fallbackRoutes.some((fallbackRoute) => fallbackRoute.pattern.test(decodedPathname));
5
+ return route.pattern.test(pathname) || route.fallbackRoutes.some((fallbackRoute) => fallbackRoute.pattern.test(pathname));
7
6
  });
8
7
  }
9
8
  function matchAllRoutes(pathname, manifest) {
10
- return manifest.routes.filter((route) => route.pattern.test(decodeURI(pathname)));
9
+ return manifest.routes.filter((route) => route.pattern.test(pathname));
11
10
  }
12
11
  const ROUTE404_RE = /^\/404\/?$/;
13
12
  const ROUTE500_RE = /^\/500\/?$/;
@@ -8,7 +8,7 @@ export declare class AstroSession<TDriver extends SessionDriverName = any> {
8
8
  /**
9
9
  * Gets a session value. Returns `undefined` if the session or value does not exist.
10
10
  */
11
- get<T = any>(key: string): Promise<T | undefined>;
11
+ get<T = void, K extends string = string>(key: K): Promise<(T extends void ? (K extends keyof App.SessionData ? App.SessionData[K] : any) : T) | undefined>;
12
12
  /**
13
13
  * Checks if a session value exists.
14
14
  */
@@ -32,7 +32,7 @@ export declare class AstroSession<TDriver extends SessionDriverName = any> {
32
32
  /**
33
33
  * Sets a session value. The session is created if it does not exist.
34
34
  */
35
- set<T = any>(key: string, value: T, { ttl }?: {
35
+ set<T = void, K extends string = string>(key: K, value: T extends void ? K extends keyof App.SessionData ? App.SessionData[K] : any : NoInfer<T>, { ttl }?: {
36
36
  ttl?: number;
37
37
  }): void;
38
38
  /**
@@ -1,6 +1,7 @@
1
1
  import fsMod from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { bold } from "kleur/colors";
4
+ import { mergeConfig as mergeViteConfig } from "vite";
4
5
  import astroIntegrationActionsRouteHandler from "../actions/integration.js";
5
6
  import { isActionsFilePresent } from "../actions/utils.js";
6
7
  import { CONTENT_LAYER_TYPE } from "../content/consts.js";
@@ -377,7 +378,7 @@ async function runHookBuildSetup({
377
378
  pages,
378
379
  target,
379
380
  updateConfig: (newConfig) => {
380
- updatedConfig = mergeConfig(updatedConfig, newConfig);
381
+ updatedConfig = mergeViteConfig(updatedConfig, newConfig);
381
382
  return { ...updatedConfig };
382
383
  },
383
384
  logger: getLogger(integration, logger)
@@ -252,7 +252,7 @@ async function transition(direction, from, to, options, historyState) {
252
252
  if (preparationEvent.formData) {
253
253
  init.method = "POST";
254
254
  const form = preparationEvent.sourceElement instanceof HTMLFormElement ? preparationEvent.sourceElement : preparationEvent.sourceElement instanceof HTMLElement && "form" in preparationEvent.sourceElement ? preparationEvent.sourceElement.form : preparationEvent.sourceElement?.closest("form");
255
- init.body = form?.attributes.getNamedItem("enctype")?.value === "application/x-www-form-urlencoded" ? new URLSearchParams(preparationEvent.formData) : preparationEvent.formData;
255
+ init.body = from !== void 0 && Reflect.get(HTMLFormElement.prototype, "attributes", form).getNamedItem("enctype")?.value === "application/x-www-form-urlencoded" ? new URLSearchParams(preparationEvent.formData) : preparationEvent.formData;
256
256
  }
257
257
  const response = await fetchHTML(href, init);
258
258
  if (response === null) {
@@ -1,9 +1,9 @@
1
1
  import type { OutgoingHttpHeaders } from 'node:http';
2
+ import type { RemotePattern } from '@astrojs/internal-helpers/remote';
2
3
  import type { RehypePlugins, RemarkPlugins, RemarkRehype, ShikiConfig } from '@astrojs/markdown-remark';
3
4
  import type { BuiltinDriverName, BuiltinDriverOptions, Driver, Storage } from 'unstorage';
4
5
  import type { UserConfig as OriginalViteUserConfig, SSROptions as ViteSSROptions } from 'vite';
5
6
  import type { ImageFit, ImageLayout } from '../../assets/types.js';
6
- import type { RemotePattern } from '../../assets/utils/remotePattern.js';
7
7
  import type { SvgRenderMode } from '../../assets/utils/svg.js';
8
8
  import type { AssetsPrefix } from '../../core/app/types.js';
9
9
  import type { AstroConfigType } from '../../core/config/schema.js';
@@ -54,6 +54,25 @@ export type ServerConfig = {
54
54
  * If the given port is already in use, Astro will automatically try the next available port.
55
55
  */
56
56
  port?: number;
57
+ /**
58
+ * @name server.allowedHosts
59
+ * @type {string[] | true}
60
+ * @default `[]`
61
+ * @version 5.4.0
62
+ * @description
63
+ *
64
+ * A list of hostnames that Astro is allowed to respond to. When the value is set to `true`, any
65
+ * hostname is allowed.
66
+ *
67
+ * ```js
68
+ * {
69
+ * server: {
70
+ * allowedHosts: ['staging.example.com', 'qa.example.com']
71
+ * }
72
+ * }
73
+ * ```
74
+ */
75
+ allowedHosts?: string[] | true;
57
76
  /**
58
77
  * @name server.headers
59
78
  * @typeraw {OutgoingHttpHeaders}
@@ -7,6 +7,11 @@ declare global {
7
7
  */
8
8
  interface Locals {
9
9
  }
10
+ /**
11
+ * Optionally type the data stored in the session
12
+ */
13
+ interface SessionData {
14
+ }
10
15
  }
11
16
  namespace Astro {
12
17
  interface IntegrationHooks extends BaseIntegrationHooks {
@@ -12,10 +12,10 @@ export type * from './common.js';
12
12
  export type * from './manifest.js';
13
13
  export type { AstroIntegrationLogger } from '../../core/logger/core.js';
14
14
  export type { ToolbarServerHelpers } from '../../runtime/client/dev-toolbar/helpers.js';
15
+ export type { RemotePattern } from '@astrojs/internal-helpers/remote';
15
16
  export type { MarkdownHeading, RehypePlugins, RemarkPlugins, ShikiConfig, } from '@astrojs/markdown-remark';
16
17
  export type { ExternalImageService, ImageService, LocalImageService, } from '../../assets/services/service.js';
17
18
  export type { GetImageResult, ImageInputFormat, ImageMetadata, ImageOutputFormat, ImageQuality, ImageQualityPreset, ImageTransform, UnresolvedImageTransform, } from '../../assets/types.js';
18
- export type { RemotePattern } from '../../assets/utils/remotePattern.js';
19
19
  export type { AssetsPrefix, SSRManifest } from '../../core/app/types.js';
20
20
  export type { AstroCookieGetOptions, AstroCookieSetOptions, AstroCookies, } from '../../core/cookies/index.js';
21
21
  export type { ContainerRenderer } from '../../container/index.js';
@@ -15,7 +15,10 @@ const markdownContentEntryType = {
15
15
  // We need to handle propagation for Markdown because they support layouts which will bring in styles.
16
16
  handlePropagation: true,
17
17
  async getRenderFunction(config) {
18
- const processor = await createMarkdownProcessor(config.markdown);
18
+ const processor = await createMarkdownProcessor({
19
+ image: config.image,
20
+ ...config.markdown
21
+ });
19
22
  return async function renderToString(entry) {
20
23
  const result = await processor.render(entry.body ?? "", {
21
24
  frontmatter: entry.data,
@@ -24,7 +27,10 @@ const markdownContentEntryType = {
24
27
  });
25
28
  return {
26
29
  html: result.code,
27
- metadata: result.metadata
30
+ metadata: {
31
+ ...result.metadata,
32
+ imagePaths: result.metadata.localImagePaths.concat(result.metadata.remoteImagePaths)
33
+ }
28
34
  };
29
35
  };
30
36
  }
@@ -2,4 +2,4 @@ export type MarkdownImagePath = {
2
2
  raw: string;
3
3
  safeName: string;
4
4
  };
5
- export declare function getMarkdownCodeForImages(imagePaths: MarkdownImagePath[], html: string): string;
5
+ export declare function getMarkdownCodeForImages(localImagePaths: MarkdownImagePath[], remoteImagePaths: string[], html: string): string;
@@ -1,11 +1,11 @@
1
- function getMarkdownCodeForImages(imagePaths, html) {
1
+ function getMarkdownCodeForImages(localImagePaths, remoteImagePaths, html) {
2
2
  return `
3
3
  import { getImage } from "astro:assets";
4
- ${imagePaths.map((entry) => `import Astro__${entry.safeName} from ${JSON.stringify(entry.raw)};`).join("\n")}
4
+ ${localImagePaths.map((entry) => `import Astro__${entry.safeName} from ${JSON.stringify(entry.raw)};`).join("\n")}
5
5
 
6
6
  const images = async function(html) {
7
7
  const imageSources = {};
8
- ${imagePaths.map((entry) => {
8
+ ${localImagePaths.map((entry) => {
9
9
  const rawUrl = JSON.stringify(entry.raw);
10
10
  return `{
11
11
  const regex = new RegExp('__ASTRO_IMAGE_="([^"]*' + ${rawUrl.replace(
@@ -22,6 +22,23 @@ function getMarkdownCodeForImages(imagePaths, html) {
22
22
  occurrenceCounter++;
23
23
  }
24
24
  }`;
25
+ }).join("\n")}
26
+ ${remoteImagePaths.map((raw) => {
27
+ const rawUrl = JSON.stringify(raw);
28
+ return `{
29
+ const regex = new RegExp('__ASTRO_IMAGE_="([^"]*' + ${rawUrl.replace(
30
+ /[.*+?^${}()|[\]\\]/g,
31
+ "\\\\$&"
32
+ )} + '[^"]*)"', 'g');
33
+ let match;
34
+ let occurrenceCounter = 0;
35
+ while ((match = regex.exec(html)) !== null) {
36
+ const matchKey = ${rawUrl} + '_' + occurrenceCounter;
37
+ const props = JSON.parse(match[1].replace(/&#x22;/g, '"'));
38
+ imageSources[matchKey] = await getImage(props);
39
+ occurrenceCounter++;
40
+ }
41
+ }`;
25
42
  }).join("\n")}
26
43
  return imageSources;
27
44
  };
@@ -44,7 +44,10 @@ function markdown({ settings, logger }) {
44
44
  const raw = safeParseFrontmatter(rawFile, id);
45
45
  const fileURL = pathToFileURL(fileId);
46
46
  if (!processor) {
47
- processor = createMarkdownProcessor(settings.config.markdown);
47
+ processor = createMarkdownProcessor({
48
+ image: settings.config.image,
49
+ ...settings.config.markdown
50
+ });
48
51
  }
49
52
  const renderResult = await (await processor).render(raw.content, {
50
53
  // @ts-expect-error passing internal prop
@@ -55,12 +58,17 @@ function markdown({ settings, logger }) {
55
58
  throw new AstroError(AstroErrorData.InvalidFrontmatterInjectionError);
56
59
  }
57
60
  let html = renderResult.code;
58
- const { headings, imagePaths: rawImagePaths, frontmatter } = renderResult.metadata;
61
+ const {
62
+ headings,
63
+ localImagePaths: rawLocalImagePaths,
64
+ remoteImagePaths,
65
+ frontmatter
66
+ } = renderResult.metadata;
59
67
  const isMarkdownPage = isPage(fileURL, settings);
60
68
  const charset = isMarkdownPage ? '<meta charset="utf-8">' : "";
61
- const imagePaths = [];
62
- for (const imagePath of rawImagePaths) {
63
- imagePaths.push({
69
+ const localImagePaths = [];
70
+ for (const imagePath of rawLocalImagePaths) {
71
+ localImagePaths.push({
64
72
  raw: imagePath,
65
73
  safeName: shorthash(imagePath)
66
74
  });
@@ -80,7 +88,7 @@ function markdown({ settings, logger }) {
80
88
  ${layout ? `import Layout from ${JSON.stringify(layout)};` : ""}
81
89
 
82
90
  ${// Only include the code relevant to `astro:assets` if there's images in the file
83
- imagePaths.length > 0 ? getMarkdownCodeForImages(imagePaths, html) : `const html = () => ${JSON.stringify(html)};`}
91
+ localImagePaths.length > 0 || remoteImagePaths.length > 0 ? getMarkdownCodeForImages(localImagePaths, remoteImagePaths, html) : `const html = () => ${JSON.stringify(html)};`}
84
92
 
85
93
  export const frontmatter = ${JSON.stringify(frontmatter)};
86
94
  export const file = ${JSON.stringify(fileId)};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "5.3.1",
3
+ "version": "5.4.1",
4
4
  "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
5
5
  "type": "module",
6
6
  "author": "withastro",
@@ -103,7 +103,7 @@
103
103
  "vendor"
104
104
  ],
105
105
  "dependencies": {
106
- "@astrojs/compiler": "^2.10.3",
106
+ "@astrojs/compiler": "^2.10.4",
107
107
  "@oslojs/encoding": "^1.1.0",
108
108
  "@rollup/pluginutils": "^5.1.4",
109
109
  "@types/cookie": "^0.6.0",
@@ -123,7 +123,7 @@
123
123
  "dlv": "^1.1.3",
124
124
  "dset": "^3.1.4",
125
125
  "es-module-lexer": "^1.6.0",
126
- "esbuild": "^0.24.2",
126
+ "esbuild": "^0.25.0",
127
127
  "estree-walker": "^3.0.3",
128
128
  "flattie": "^1.1.1",
129
129
  "github-slugger": "^2.0.0",
@@ -150,7 +150,7 @@
150
150
  "unist-util-visit": "^5.0.0",
151
151
  "unstorage": "^1.14.4",
152
152
  "vfile": "^6.0.3",
153
- "vite": "^6.0.11",
153
+ "vite": "^6.2.0",
154
154
  "vitefu": "^1.0.5",
155
155
  "which-pm": "^3.0.1",
156
156
  "xxhash-wasm": "^1.1.0",
@@ -159,9 +159,9 @@
159
159
  "zod": "^3.24.1",
160
160
  "zod-to-json-schema": "^3.24.1",
161
161
  "zod-to-ts": "^1.2.0",
162
- "@astrojs/internal-helpers": "0.5.1",
163
- "@astrojs/markdown-remark": "6.1.0",
164
- "@astrojs/telemetry": "3.2.0"
162
+ "@astrojs/internal-helpers": "0.6.0",
163
+ "@astrojs/telemetry": "3.2.0",
164
+ "@astrojs/markdown-remark": "6.2.0"
165
165
  },
166
166
  "optionalDependencies": {
167
167
  "sharp": "^0.33.3"