astro 3.4.4 → 3.5.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 (143) hide show
  1. package/client.d.ts +86 -0
  2. package/components/Code.astro +15 -2
  3. package/components/Picture.astro +2 -1
  4. package/components/ViewTransitions.astro +39 -38
  5. package/content-module.template.mjs +4 -14
  6. package/dist/@types/astro.d.ts +227 -5
  7. package/dist/assets/build/generate.d.ts +2 -1
  8. package/dist/assets/build/generate.js +16 -5
  9. package/dist/assets/consts.d.ts +1 -0
  10. package/dist/assets/consts.js +2 -0
  11. package/dist/assets/endpoint/generic.js +6 -2
  12. package/dist/assets/internal.js +9 -2
  13. package/dist/assets/services/service.d.ts +8 -3
  14. package/dist/assets/services/service.js +2 -1
  15. package/dist/assets/services/vendor/squoosh/image-pool.d.ts +1 -2
  16. package/dist/assets/types.d.ts +9 -5
  17. package/dist/assets/utils/emitAsset.js +5 -0
  18. package/dist/assets/utils/metadata.d.ts +1 -2
  19. package/dist/assets/utils/proxy.d.ts +1 -0
  20. package/dist/assets/utils/proxy.js +16 -0
  21. package/dist/assets/utils/queryParams.d.ts +1 -1
  22. package/dist/assets/utils/transformToPath.d.ts +1 -1
  23. package/dist/assets/utils/transformToPath.js +8 -3
  24. package/dist/assets/vite-plugin-assets.js +33 -12
  25. package/dist/cli/build/index.js +1 -1
  26. package/dist/cli/info/index.js +7 -3
  27. package/dist/content/consts.d.ts +1 -0
  28. package/dist/content/consts.js +2 -0
  29. package/dist/content/runtime-assets.d.ts +9 -1
  30. package/dist/content/runtime-assets.js +1 -1
  31. package/dist/content/runtime.d.ts +1 -0
  32. package/dist/content/runtime.js +8 -2
  33. package/dist/content/utils.d.ts +1 -0
  34. package/dist/content/utils.js +9 -0
  35. package/dist/content/vite-plugin-content-assets.js +49 -23
  36. package/dist/content/vite-plugin-content-imports.js +9 -3
  37. package/dist/content/vite-plugin-content-virtual-mod.d.ts +17 -12
  38. package/dist/content/vite-plugin-content-virtual-mod.js +136 -57
  39. package/dist/core/app/index.js +19 -4
  40. package/dist/core/app/types.d.ts +7 -1
  41. package/dist/core/build/buildPipeline.js +17 -4
  42. package/dist/core/build/common.js +2 -0
  43. package/dist/core/build/generate.js +64 -34
  44. package/dist/core/build/index.d.ts +0 -8
  45. package/dist/core/build/index.js +9 -2
  46. package/dist/core/build/internal.d.ts +11 -1
  47. package/dist/core/build/internal.js +23 -1
  48. package/dist/core/build/page-data.js +46 -18
  49. package/dist/core/build/plugin.d.ts +12 -10
  50. package/dist/core/build/plugin.js +14 -22
  51. package/dist/core/build/plugins/index.js +4 -0
  52. package/dist/core/build/plugins/plugin-alias-resolve.js +1 -1
  53. package/dist/core/build/plugins/plugin-analyzer.js +1 -1
  54. package/dist/core/build/plugins/plugin-chunks.d.ts +4 -0
  55. package/dist/core/build/plugins/plugin-chunks.js +31 -0
  56. package/dist/core/build/plugins/plugin-component-entry.js +1 -1
  57. package/dist/core/build/plugins/plugin-content.d.ts +4 -0
  58. package/dist/core/build/plugins/plugin-content.js +273 -0
  59. package/dist/core/build/plugins/plugin-css.js +9 -4
  60. package/dist/core/build/plugins/plugin-hoisted-scripts.js +1 -1
  61. package/dist/core/build/plugins/plugin-internals.js +1 -1
  62. package/dist/core/build/plugins/plugin-manifest.js +14 -5
  63. package/dist/core/build/plugins/plugin-middleware.d.ts +1 -3
  64. package/dist/core/build/plugins/plugin-middleware.js +5 -57
  65. package/dist/core/build/plugins/plugin-pages.js +3 -3
  66. package/dist/core/build/plugins/plugin-prerender.js +2 -5
  67. package/dist/core/build/plugins/plugin-renderers.js +1 -1
  68. package/dist/core/build/plugins/plugin-ssr.js +6 -5
  69. package/dist/core/build/plugins/util.d.ts +3 -3
  70. package/dist/core/build/static-build.d.ts +2 -1
  71. package/dist/core/build/static-build.js +52 -28
  72. package/dist/core/build/types.d.ts +1 -1
  73. package/dist/core/build/util.d.ts +7 -0
  74. package/dist/core/build/util.js +37 -1
  75. package/dist/core/compile/compile.js +1 -0
  76. package/dist/core/config/config.js +3 -0
  77. package/dist/core/config/schema.d.ts +208 -0
  78. package/dist/core/config/schema.js +55 -2
  79. package/dist/core/config/settings.js +1 -0
  80. package/dist/core/constants.js +1 -1
  81. package/dist/core/create-vite.js +9 -3
  82. package/dist/core/dev/dev.js +1 -1
  83. package/dist/core/endpoint/index.d.ts +4 -3
  84. package/dist/core/endpoint/index.js +29 -3
  85. package/dist/core/errors/errors-data.d.ts +11 -0
  86. package/dist/core/errors/errors-data.js +17 -0
  87. package/dist/core/logger/node.js +1 -0
  88. package/dist/core/messages.js +2 -2
  89. package/dist/core/middleware/index.d.ts +7 -3
  90. package/dist/core/middleware/index.js +3 -2
  91. package/dist/core/middleware/loadMiddleware.d.ts +1 -2
  92. package/dist/core/middleware/loadMiddleware.js +3 -4
  93. package/dist/core/middleware/sequence.d.ts +2 -2
  94. package/dist/core/middleware/sequence.js +3 -2
  95. package/dist/core/middleware/vite-plugin.d.ts +9 -0
  96. package/dist/core/middleware/vite-plugin.js +101 -0
  97. package/dist/core/pipeline.d.ts +1 -1
  98. package/dist/core/pipeline.js +6 -4
  99. package/dist/core/redirects/helpers.d.ts +1 -0
  100. package/dist/core/redirects/helpers.js +4 -0
  101. package/dist/core/render/context.d.ts +24 -1
  102. package/dist/core/render/context.js +96 -2
  103. package/dist/core/render/core.d.ts +2 -14
  104. package/dist/core/render/core.js +12 -52
  105. package/dist/core/render/index.d.ts +2 -3
  106. package/dist/core/render/index.js +3 -4
  107. package/dist/core/render/params-and-props.d.ts +1 -1
  108. package/dist/core/render/params-and-props.js +5 -2
  109. package/dist/core/render/result.d.ts +1 -0
  110. package/dist/core/render/result.js +23 -0
  111. package/dist/core/render/route-cache.d.ts +1 -1
  112. package/dist/core/render/route-cache.js +6 -2
  113. package/dist/core/routing/manifest/create.js +117 -4
  114. package/dist/core/sync/index.d.ts +2 -24
  115. package/dist/i18n/index.d.ts +54 -0
  116. package/dist/i18n/index.js +91 -0
  117. package/dist/i18n/middleware.d.ts +2 -0
  118. package/dist/i18n/middleware.js +62 -0
  119. package/dist/i18n/vite-plugin-i18n.d.ts +7 -0
  120. package/dist/i18n/vite-plugin-i18n.js +62 -0
  121. package/dist/integrations/astroFeaturesValidation.js +4 -1
  122. package/dist/integrations/index.js +12 -0
  123. package/dist/prefetch/index.d.ts +31 -0
  124. package/dist/prefetch/index.js +176 -0
  125. package/dist/prefetch/vite-plugin-prefetch.d.ts +5 -0
  126. package/dist/prefetch/vite-plugin-prefetch.js +43 -0
  127. package/dist/runtime/client/dev-overlay/plugins/audit.js +17 -9
  128. package/dist/runtime/server/index.d.ts +0 -2
  129. package/dist/runtime/server/render/component.js +3 -5
  130. package/dist/transitions/router.d.ts +1 -0
  131. package/dist/transitions/router.js +9 -4
  132. package/dist/transitions/vite-plugin-transitions.d.ts +4 -1
  133. package/dist/transitions/vite-plugin-transitions.js +7 -1
  134. package/dist/vite-plugin-astro-server/devPipeline.d.ts +1 -0
  135. package/dist/vite-plugin-astro-server/devPipeline.js +2 -0
  136. package/dist/vite-plugin-astro-server/plugin.js +11 -1
  137. package/dist/vite-plugin-astro-server/route.js +113 -51
  138. package/dist/vite-plugin-head/index.js +1 -1
  139. package/dist/vite-plugin-markdown/index.js +1 -0
  140. package/package.json +8 -6
  141. package/tsconfigs/base.json +1 -1
  142. package/dist/core/endpoint/dev/index.d.ts +0 -2
  143. package/dist/core/endpoint/dev/index.js +0 -17
@@ -8,3 +8,4 @@ export declare const VALID_INPUT_FORMATS: readonly ["jpeg", "jpg", "png", "tiff"
8
8
  export declare const VALID_SUPPORTED_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif", "svg", "avif"];
9
9
  export declare const DEFAULT_OUTPUT_FORMAT: "webp";
10
10
  export declare const VALID_OUTPUT_FORMATS: readonly ["avif", "png", "webp", "jpeg", "jpg", "svg"];
11
+ export declare const DEFAULT_HASH_PROPS: string[];
@@ -22,7 +22,9 @@ const VALID_SUPPORTED_FORMATS = [
22
22
  ];
23
23
  const DEFAULT_OUTPUT_FORMAT = "webp";
24
24
  const VALID_OUTPUT_FORMATS = ["avif", "png", "webp", "jpeg", "jpg", "svg"];
25
+ const DEFAULT_HASH_PROPS = ["src", "width", "height", "format", "quality"];
25
26
  export {
27
+ DEFAULT_HASH_PROPS,
26
28
  DEFAULT_OUTPUT_FORMAT,
27
29
  VALID_INPUT_FORMATS,
28
30
  VALID_OUTPUT_FORMATS,
@@ -9,7 +9,7 @@ async function loadRemoteImage(src) {
9
9
  if (!res.ok) {
10
10
  return void 0;
11
11
  }
12
- return Buffer.from(await res.arrayBuffer());
12
+ return await res.arrayBuffer();
13
13
  } catch (err) {
14
14
  return void 0;
15
15
  }
@@ -34,7 +34,11 @@ const GET = async ({ request }) => {
34
34
  if (!inputBuffer) {
35
35
  return new Response("Not Found", { status: 404 });
36
36
  }
37
- const { data, format } = await imageService.transform(inputBuffer, transform, imageConfig);
37
+ const { data, format } = await imageService.transform(
38
+ new Uint8Array(inputBuffer),
39
+ transform,
40
+ imageConfig
41
+ );
38
42
  return new Response(data, {
39
43
  status: 200,
40
44
  headers: {
@@ -1,5 +1,6 @@
1
1
  import { isRemotePath } from "@astrojs/internal-helpers/path";
2
2
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
3
+ import { DEFAULT_HASH_PROPS } from "./consts.js";
3
4
  import { isLocalService } from "./services/service.js";
4
5
  import { matchHostname, matchPattern } from "./utils/remotePattern.js";
5
6
  function injectImageEndpoint(settings, mode) {
@@ -55,6 +56,11 @@ async function getImage(options, imageConfig) {
55
56
  ...options,
56
57
  src: typeof options.src === "object" && "then" in options.src ? (await options.src).default ?? await options.src : options.src
57
58
  };
59
+ const clonedSrc = isESMImportedImage(resolvedOptions.src) ? (
60
+ // @ts-expect-error - clone is a private, hidden prop
61
+ resolvedOptions.src.clone ?? resolvedOptions.src
62
+ ) : resolvedOptions.src;
63
+ resolvedOptions.src = clonedSrc;
58
64
  const validatedOptions = service.validateOptions ? await service.validateOptions(resolvedOptions, imageConfig) : resolvedOptions;
59
65
  const srcSetTransforms = service.getSrcSet ? await service.getSrcSet(validatedOptions, imageConfig) : [];
60
66
  let imageURL = await service.getURL(validatedOptions, imageConfig);
@@ -67,10 +73,11 @@ async function getImage(options, imageConfig) {
67
73
  }))
68
74
  );
69
75
  if (isLocalService(service) && globalThis.astroAsset.addStaticImage && !(isRemoteImage(validatedOptions.src) && imageURL === validatedOptions.src)) {
70
- imageURL = globalThis.astroAsset.addStaticImage(validatedOptions);
76
+ const propsToHash = service.propertiesToHash ?? DEFAULT_HASH_PROPS;
77
+ imageURL = globalThis.astroAsset.addStaticImage(validatedOptions, propsToHash);
71
78
  srcSets = srcSetTransforms.map((srcSet) => ({
72
79
  transform: srcSet.transform,
73
- url: globalThis.astroAsset.addStaticImage(srcSet.transform),
80
+ url: globalThis.astroAsset.addStaticImage(srcSet.transform, propsToHash),
74
81
  descriptor: srcSet.descriptor,
75
82
  attributes: srcSet.attributes
76
83
  }));
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import type { AstroConfig } from '../../@types/astro.js';
3
2
  import type { ImageOutputFormat, ImageTransform, UnresolvedSrcSetValue } from '../types.js';
4
3
  export type ImageService = LocalImageService | ExternalImageService;
@@ -60,10 +59,16 @@ export interface LocalImageService<T extends Record<string, any> = Record<string
60
59
  * Performs the image transformations on the input image and returns both the binary data and
61
60
  * final image format of the optimized image.
62
61
  */
63
- transform: (inputBuffer: Buffer, transform: LocalImageTransform, imageConfig: ImageConfig<T>) => Promise<{
64
- data: Buffer;
62
+ transform: (inputBuffer: Uint8Array, transform: LocalImageTransform, imageConfig: ImageConfig<T>) => Promise<{
63
+ data: Uint8Array;
65
64
  format: ImageOutputFormat;
66
65
  }>;
66
+ /**
67
+ * A list of properties that should be used to generate the hash for the image.
68
+ *
69
+ * Generally, this should be all the properties that can change the result of the image. By default, this is `src`, `width`, `height`, `quality`, and `format`.
70
+ */
71
+ propertiesToHash?: string[];
67
72
  }
68
73
  export type BaseServiceTransform = {
69
74
  src: string;
@@ -1,6 +1,6 @@
1
1
  import { AstroError, AstroErrorData } from "../../core/errors/index.js";
2
2
  import { isRemotePath, joinPaths } from "../../core/path.js";
3
- import { DEFAULT_OUTPUT_FORMAT, VALID_SUPPORTED_FORMATS } from "../consts.js";
3
+ import { DEFAULT_HASH_PROPS, DEFAULT_OUTPUT_FORMAT, VALID_SUPPORTED_FORMATS } from "../consts.js";
4
4
  import { isESMImportedImage, isRemoteAllowed } from "../internal.js";
5
5
  function isLocalService(service) {
6
6
  if (!service) {
@@ -16,6 +16,7 @@ function parseQuality(quality) {
16
16
  return result;
17
17
  }
18
18
  const baseService = {
19
+ propertiesToHash: DEFAULT_HASH_PROPS,
19
20
  validateOptions(options) {
20
21
  if (!options.src || typeof options.src !== "string" && typeof options.src !== "object") {
21
22
  throw new AstroError({
@@ -1,4 +1,3 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import type { ImageOutputFormat } from '../../../types.js';
3
2
  import type { Operation } from './image.js';
4
- export declare function processBuffer(buffer: Buffer, operations: Operation[], encoding: ImageOutputFormat, quality?: number): Promise<Uint8Array>;
3
+ export declare function processBuffer(buffer: Uint8Array, operations: Operation[], encoding: ImageOutputFormat, quality?: number): Promise<Uint8Array>;
@@ -5,15 +5,19 @@ export type ImageQualityPreset = 'low' | 'mid' | 'high' | 'max' | (string & {});
5
5
  export type ImageQuality = ImageQualityPreset | number;
6
6
  export type ImageInputFormat = (typeof VALID_INPUT_FORMATS)[number];
7
7
  export type ImageOutputFormat = (typeof VALID_OUTPUT_FORMATS)[number] | (string & {});
8
- export type AssetsGlobalStaticImagesList = Map<string, Map<string, {
9
- finalPath: string;
10
- transform: ImageTransform;
11
- }>>;
8
+ export type AssetsGlobalStaticImagesList = Map<string, {
9
+ originalSrcPath: string;
10
+ transforms: Map<string, {
11
+ finalPath: string;
12
+ transform: ImageTransform;
13
+ }>;
14
+ }>;
12
15
  declare global {
13
16
  var astroAsset: {
14
17
  imageService?: ImageService;
15
- addStaticImage?: ((options: ImageTransform) => string) | undefined;
18
+ addStaticImage?: ((options: ImageTransform, hashProperties: string[]) => string) | undefined;
16
19
  staticImages?: AssetsGlobalStaticImagesList;
20
+ referencedImages?: Set<string>;
17
21
  };
18
22
  }
19
23
  /**
@@ -19,6 +19,11 @@ async function emitESMImage(id, watchMode, fileEmitter) {
19
19
  src: "",
20
20
  ...fileMetadata
21
21
  };
22
+ Object.defineProperty(emittedImage, "fsPath", {
23
+ enumerable: false,
24
+ writable: false,
25
+ value: url
26
+ });
22
27
  if (!watchMode) {
23
28
  const pathname = decodeURI(url.pathname);
24
29
  const filename = path.basename(pathname, path.extname(pathname) + `.${fileMetadata.format}`);
@@ -1,3 +1,2 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
1
  import type { ImageMetadata } from '../types.js';
3
- export declare function imageMetadata(data: Buffer, src?: string): Promise<Omit<ImageMetadata, 'src'>>;
2
+ export declare function imageMetadata(data: Uint8Array, src?: string): Promise<Omit<ImageMetadata, 'src' | 'fsPath'>>;
@@ -0,0 +1 @@
1
+ export declare function getProxyCode(options: Record<string, any>, isSSR: boolean): string;
@@ -0,0 +1,16 @@
1
+ function getProxyCode(options, isSSR) {
2
+ return `
3
+ new Proxy(${JSON.stringify(options)}, {
4
+ get(target, name, receiver) {
5
+ if (name === 'clone') {
6
+ return structuredClone(target);
7
+ }
8
+ ${!isSSR ? "globalThis.astroAsset.referencedImages.add(target.fsPath);" : ""}
9
+ return target[name];
10
+ }
11
+ })
12
+ `;
13
+ }
14
+ export {
15
+ getProxyCode
16
+ };
@@ -1,2 +1,2 @@
1
1
  import type { ImageMetadata } from '../types.js';
2
- export declare function getOrigQueryParams(params: URLSearchParams): Omit<ImageMetadata, 'src'> | undefined;
2
+ export declare function getOrigQueryParams(params: URLSearchParams): Pick<ImageMetadata, 'width' | 'height' | 'format'> | undefined;
@@ -1,3 +1,3 @@
1
1
  import type { ImageTransform } from '../types.js';
2
2
  export declare function propsToFilename(transform: ImageTransform, hash: string): string;
3
- export declare function hashTransform(transform: ImageTransform, imageService: string): string;
3
+ export declare function hashTransform(transform: ImageTransform, imageService: string, propertiesToHash: string[]): string;
@@ -12,9 +12,14 @@ function propsToFilename(transform, hash) {
12
12
  let outputExt = transform.format ? `.${transform.format}` : ext;
13
13
  return `/${filename}_${hash}${outputExt}`;
14
14
  }
15
- function hashTransform(transform, imageService) {
16
- const { alt, class: className, style, widths, densities, ...rest } = transform;
17
- const hashFields = { ...rest, imageService };
15
+ function hashTransform(transform, imageService, propertiesToHash) {
16
+ const hashFields = propertiesToHash.reduce(
17
+ (acc, prop) => {
18
+ acc[prop] = transform[prop];
19
+ return acc;
20
+ },
21
+ { imageService }
22
+ );
18
23
  return shorthash(deterministicString(hashFields));
19
24
  }
20
25
  export {
@@ -12,6 +12,7 @@ import { isServerLikeOutput } from "../prerender/utils.js";
12
12
  import { VALID_INPUT_FORMATS, VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from "./consts.js";
13
13
  import { isESMImportedImage } from "./internal.js";
14
14
  import { emitESMImage } from "./utils/emitAsset.js";
15
+ import { getProxyCode } from "./utils/proxy.js";
15
16
  import { hashTransform, propsToFilename } from "./utils/transformToPath.js";
16
17
  const resolvedVirtualModuleId = "\0" + VIRTUAL_MODULE_ID;
17
18
  const assetRegex = new RegExp(`\\.(${VALID_INPUT_FORMATS.join("|")})$`, "i");
@@ -20,7 +21,9 @@ function assets({
20
21
  mode
21
22
  }) {
22
23
  let resolvedConfig;
23
- globalThis.astroAsset = {};
24
+ globalThis.astroAsset = {
25
+ referencedImages: /* @__PURE__ */ new Set()
26
+ };
24
27
  return [
25
28
  // Expose the components and different utilities from `astro:assets` and handle serving images from `/_image` in dev
26
29
  {
@@ -29,7 +32,7 @@ function assets({
29
32
  extendManualChunks(outputOptions, {
30
33
  after(id) {
31
34
  if (id.includes("astro/dist/assets/services/")) {
32
- return `astro-assets-services`;
35
+ return `astro/assets-service`;
33
36
  }
34
37
  }
35
38
  });
@@ -64,15 +67,20 @@ function assets({
64
67
  if (mode != "build") {
65
68
  return;
66
69
  }
67
- globalThis.astroAsset.addStaticImage = (options) => {
70
+ globalThis.astroAsset.addStaticImage = (options, hashProperties) => {
68
71
  if (!globalThis.astroAsset.staticImages) {
69
72
  globalThis.astroAsset.staticImages = /* @__PURE__ */ new Map();
70
73
  }
71
- const originalImagePath = (isESMImportedImage(options.src) ? options.src.src : options.src).replace(settings.config.build.assetsPrefix || "", "");
72
- const hash = hashTransform(options, settings.config.image.service.entrypoint);
74
+ const finalOriginalImagePath = (isESMImportedImage(options.src) ? options.src.src : options.src).replace(settings.config.build.assetsPrefix || "", "");
75
+ const originalSrcPath = isESMImportedImage(options.src) ? options.src.fsPath : options.src;
76
+ const hash = hashTransform(
77
+ options,
78
+ settings.config.image.service.entrypoint,
79
+ hashProperties
80
+ );
73
81
  let finalFilePath;
74
- let transformsForPath = globalThis.astroAsset.staticImages.get(originalImagePath);
75
- let transformForHash = transformsForPath?.get(hash);
82
+ let transformsForPath = globalThis.astroAsset.staticImages.get(finalOriginalImagePath);
83
+ let transformForHash = transformsForPath?.transforms.get(hash);
76
84
  if (transformsForPath && transformForHash) {
77
85
  finalFilePath = transformForHash.finalPath;
78
86
  } else {
@@ -80,10 +88,16 @@ function assets({
80
88
  joinPaths(settings.config.build.assets, propsToFilename(options, hash))
81
89
  );
82
90
  if (!transformsForPath) {
83
- globalThis.astroAsset.staticImages.set(originalImagePath, /* @__PURE__ */ new Map());
84
- transformsForPath = globalThis.astroAsset.staticImages.get(originalImagePath);
91
+ globalThis.astroAsset.staticImages.set(finalOriginalImagePath, {
92
+ originalSrcPath,
93
+ transforms: /* @__PURE__ */ new Map()
94
+ });
95
+ transformsForPath = globalThis.astroAsset.staticImages.get(finalOriginalImagePath);
85
96
  }
86
- transformsForPath.set(hash, { finalPath: finalFilePath, transform: options });
97
+ transformsForPath.transforms.set(hash, {
98
+ finalPath: finalFilePath,
99
+ transform: options
100
+ });
87
101
  }
88
102
  if (settings.config.build.assetsPrefix) {
89
103
  return joinPaths(settings.config.build.assetsPrefix, finalFilePath);
@@ -122,7 +136,7 @@ function assets({
122
136
  configResolved(viteConfig) {
123
137
  resolvedConfig = viteConfig;
124
138
  },
125
- async load(id) {
139
+ async load(id, options) {
126
140
  if (id !== removeQueryString(id)) {
127
141
  return;
128
142
  }
@@ -134,7 +148,14 @@ function assets({
134
148
  message: AstroErrorData.ImageNotFound.message(id)
135
149
  });
136
150
  }
137
- return `export default ${JSON.stringify(meta)}`;
151
+ if (options?.ssr) {
152
+ return `export default ${getProxyCode(meta, isServerLikeOutput(settings.config))}`;
153
+ } else {
154
+ if (!globalThis.astroAsset.referencedImages)
155
+ globalThis.astroAsset.referencedImages = /* @__PURE__ */ new Set();
156
+ globalThis.astroAsset.referencedImages.add(meta.fsPath);
157
+ return `export default ${JSON.stringify(meta)}`;
158
+ }
138
159
  }
139
160
  }
140
161
  }
@@ -18,7 +18,7 @@ async function build({ flags }) {
18
18
  return;
19
19
  }
20
20
  const inlineConfig = flagsToAstroInlineConfig(flags);
21
- await _build(inlineConfig);
21
+ await _build(inlineConfig, { force: flags.force ?? false });
22
22
  }
23
23
  export {
24
24
  build
@@ -35,11 +35,15 @@ async function copyToClipboard(text) {
35
35
  } else if (system === "win32") {
36
36
  command = "clip";
37
37
  } else {
38
- const output = execSync("which xclip", { encoding: "utf8" });
39
- if (output[0] !== "/") {
38
+ try {
39
+ const output = execSync("which xclip", { encoding: "utf8" });
40
+ if (output[0] !== "/") {
41
+ return;
42
+ }
43
+ command = "xclip -sel clipboard -l 1";
44
+ } catch (e) {
40
45
  return;
41
46
  }
42
- command = "xclip -sel clipboard -l 1";
43
47
  }
44
48
  console.log();
45
49
  const { shouldCopy } = await prompts({
@@ -3,6 +3,7 @@ export declare const CONTENT_RENDER_FLAG = "astroRenderContent";
3
3
  export declare const CONTENT_FLAG = "astroContentCollectionEntry";
4
4
  export declare const DATA_FLAG = "astroDataCollectionEntry";
5
5
  export declare const VIRTUAL_MODULE_ID = "astro:content";
6
+ export declare const RESOLVED_VIRTUAL_MODULE_ID: string;
6
7
  export declare const LINKS_PLACEHOLDER = "@@ASTRO-LINKS@@";
7
8
  export declare const STYLES_PLACEHOLDER = "@@ASTRO-STYLES@@";
8
9
  export declare const SCRIPTS_PLACEHOLDER = "@@ASTRO-SCRIPTS@@";
@@ -3,6 +3,7 @@ const CONTENT_RENDER_FLAG = "astroRenderContent";
3
3
  const CONTENT_FLAG = "astroContentCollectionEntry";
4
4
  const DATA_FLAG = "astroDataCollectionEntry";
5
5
  const VIRTUAL_MODULE_ID = "astro:content";
6
+ const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
6
7
  const LINKS_PLACEHOLDER = "@@ASTRO-LINKS@@";
7
8
  const STYLES_PLACEHOLDER = "@@ASTRO-STYLES@@";
8
9
  const SCRIPTS_PLACEHOLDER = "@@ASTRO-SCRIPTS@@";
@@ -21,6 +22,7 @@ export {
21
22
  DATA_FLAG,
22
23
  LINKS_PLACEHOLDER,
23
24
  PROPAGATED_ASSET_FLAG,
25
+ RESOLVED_VIRTUAL_MODULE_ID,
24
26
  SCRIPTS_PLACEHOLDER,
25
27
  STYLES_PLACEHOLDER,
26
28
  VIRTUAL_MODULE_ID
@@ -1,3 +1,11 @@
1
1
  import type { PluginContext } from 'rollup';
2
2
  import { z } from 'zod';
3
- export declare function createImage(pluginContext: PluginContext, entryFilePath: string): () => z.ZodEffects<z.ZodString, import("../assets/types.js").ImageMetadata | z.ZodNever, string>;
3
+ export declare function createImage(pluginContext: PluginContext, entryFilePath: string): () => z.ZodEffects<z.ZodString, z.ZodNever | {
4
+ ASTRO_ASSET: boolean;
5
+ src: string;
6
+ width: number;
7
+ height: number;
8
+ format: "jpeg" | "jpg" | "png" | "tiff" | "webp" | "gif" | "svg" | "avif";
9
+ orientation?: number | undefined;
10
+ fsPath: string;
11
+ }, string>;
@@ -17,7 +17,7 @@ function createImage(pluginContext, entryFilePath) {
17
17
  });
18
18
  return z.never();
19
19
  }
20
- return metadata;
20
+ return { ...metadata, ASTRO_ASSET: true };
21
21
  });
22
22
  };
23
23
  }
@@ -5,6 +5,7 @@ type LazyImport = () => Promise<any>;
5
5
  type GlobResult = Record<string, LazyImport>;
6
6
  type CollectionToEntryMap = Record<string, GlobResult>;
7
7
  type GetEntryImport = (collection: string, lookupId: string) => Promise<LazyImport>;
8
+ export declare function defineCollection(config: any): any;
8
9
  export declare function createCollectionToGlobResultMap({ globResult, contentDir, }: {
9
10
  globResult: GlobResult;
10
11
  contentDir: string;
@@ -10,6 +10,11 @@ import {
10
10
  renderUniqueStylesheet,
11
11
  unescapeHTML
12
12
  } from "../runtime/server/index.js";
13
+ function defineCollection(config) {
14
+ if (!config.type)
15
+ config.type = "content";
16
+ return config;
17
+ }
13
18
  function createCollectionToGlobResultMap({
14
19
  globResult,
15
20
  contentDir
@@ -48,7 +53,7 @@ function createGetCollection({
48
53
  type === "content" ? contentCollectionToEntryMap[collection] : dataCollectionToEntryMap[collection]
49
54
  );
50
55
  let entries = [];
51
- if (import.meta.env.PROD && cacheEntriesByCollection.has(collection)) {
56
+ if (!import.meta.env?.DEV && cacheEntriesByCollection.has(collection)) {
52
57
  entries = [...cacheEntriesByCollection.get(collection)];
53
58
  } else {
54
59
  entries = await Promise.all(
@@ -291,5 +296,6 @@ export {
291
296
  createGetEntries,
292
297
  createGetEntry,
293
298
  createGetEntryBySlug,
294
- createReference
299
+ createReference,
300
+ defineCollection
295
301
  };
@@ -126,6 +126,7 @@ export declare function parseFrontmatter(fileContents: string): matter.GrayMatte
126
126
  * subscribe to changes during dev server updates.
127
127
  */
128
128
  export declare const globalContentConfigObserver: ContentObservable;
129
+ export declare function hasAnyContentFlag(viteId: string): boolean;
129
130
  export declare function hasContentFlag(viteId: string, flag: (typeof CONTENT_FLAGS)[number]): boolean;
130
131
  export declare function loadContentConfig({ fs, settings, viteServer, }: {
131
132
  fs: typeof fsMod;
@@ -219,6 +219,14 @@ function parseFrontmatter(fileContents) {
219
219
  }
220
220
  }
221
221
  const globalContentConfigObserver = contentObservable({ status: "init" });
222
+ function hasAnyContentFlag(viteId) {
223
+ const flags = new URLSearchParams(viteId.split("?")[1] ?? "");
224
+ const flag = Array.from(flags.keys()).at(0);
225
+ if (typeof flag !== "string") {
226
+ return false;
227
+ }
228
+ return CONTENT_FLAGS.includes(flag);
229
+ }
222
230
  function hasContentFlag(viteId, flag) {
223
231
  const flags = new URLSearchParams(viteId.split("?")[1] ?? "");
224
232
  return flags.has(flag);
@@ -349,6 +357,7 @@ export {
349
357
  getEntryType,
350
358
  getExtGlob,
351
359
  globalContentConfigObserver,
360
+ hasAnyContentFlag,
352
361
  hasContentFlag,
353
362
  hasUnderscoreBelowContentDirectoryPath,
354
363
  loadContentConfig,
@@ -85,14 +85,14 @@ function astroContentAssetPropagationPlugin({
85
85
  function astroConfigBuildPlugin(options, internals) {
86
86
  let ssrPluginContext = void 0;
87
87
  return {
88
- build: "ssr",
88
+ targets: ["server"],
89
89
  hooks: {
90
- "build:before": ({ build }) => {
90
+ "build:before": ({ target }) => {
91
91
  return {
92
92
  vitePlugin: {
93
93
  name: "astro:content-build-plugin",
94
94
  generateBundle() {
95
- if (build === "ssr") {
95
+ if (target === "server") {
96
96
  ssrPluginContext = this;
97
97
  }
98
98
  }
@@ -113,26 +113,46 @@ function astroConfigBuildPlugin(options, internals) {
113
113
  let entryStyles = /* @__PURE__ */ new Set();
114
114
  let entryLinks = /* @__PURE__ */ new Set();
115
115
  let entryScripts = /* @__PURE__ */ new Set();
116
- for (const id of Object.keys(chunk.modules)) {
117
- for (const [pageInfo] of walkParentInfos(id, ssrPluginContext)) {
118
- if (moduleIsTopLevelPage(pageInfo)) {
119
- const pageViteID = pageInfo.id;
120
- const pageData = getPageDataByViteID(internals, pageViteID);
121
- if (!pageData)
122
- continue;
123
- const _entryCss = pageData.propagatedStyles?.get(id);
124
- const _entryScripts = pageData.propagatedScripts?.get(id);
125
- if (_entryCss) {
126
- for (const value of _entryCss) {
127
- if (value.type === "inline")
128
- entryStyles.add(value.content);
129
- if (value.type === "external")
130
- entryLinks.add(value.src);
131
- }
116
+ if (options.settings.config.experimental.contentCollectionCache) {
117
+ for (const id of chunk.moduleIds) {
118
+ const _entryCss = internals.propagatedStylesMap.get(id);
119
+ const _entryScripts = internals.propagatedScriptsMap.get(id);
120
+ if (_entryCss) {
121
+ for (const value of _entryCss) {
122
+ if (value.type === "inline")
123
+ entryStyles.add(value.content);
124
+ if (value.type === "external")
125
+ entryLinks.add(value.src);
126
+ }
127
+ }
128
+ if (_entryScripts) {
129
+ for (const value of _entryScripts) {
130
+ entryScripts.add(value);
132
131
  }
133
- if (_entryScripts) {
134
- for (const value of _entryScripts) {
135
- entryScripts.add(value);
132
+ }
133
+ }
134
+ } else {
135
+ for (const id of Object.keys(chunk.modules)) {
136
+ for (const [pageInfo] of walkParentInfos(id, ssrPluginContext)) {
137
+ if (moduleIsTopLevelPage(pageInfo)) {
138
+ const pageViteID = pageInfo.id;
139
+ const pageData = getPageDataByViteID(internals, pageViteID);
140
+ if (!pageData)
141
+ continue;
142
+ const _entryCss = internals.propagatedStylesMap?.get(id);
143
+ const _entryScripts = pageData.propagatedScripts?.get(id);
144
+ if (_entryCss) {
145
+ for (const value of _entryCss) {
146
+ if (value.type === "inline")
147
+ entryStyles.add(value.content);
148
+ if (value.type === "external")
149
+ entryLinks.add(value.src);
150
+ }
151
+ }
152
+ if (_entryScripts) {
153
+ for (const value of _entryScripts) {
154
+ entryScripts.add(value);
155
+ }
136
156
  }
137
157
  }
138
158
  }
@@ -144,12 +164,16 @@ function astroConfigBuildPlugin(options, internals) {
144
164
  JSON.stringify(STYLES_PLACEHOLDER),
145
165
  JSON.stringify(Array.from(entryStyles))
146
166
  );
167
+ } else {
168
+ newCode = newCode.replace(JSON.stringify(STYLES_PLACEHOLDER), "[]");
147
169
  }
148
170
  if (entryLinks.size) {
149
171
  newCode = newCode.replace(
150
172
  JSON.stringify(LINKS_PLACEHOLDER),
151
173
  JSON.stringify(Array.from(entryLinks).map(prependBase))
152
174
  );
175
+ } else {
176
+ newCode = newCode.replace(JSON.stringify(LINKS_PLACEHOLDER), "[]");
153
177
  }
154
178
  if (entryScripts.size) {
155
179
  const entryFileNames = /* @__PURE__ */ new Set();
@@ -176,8 +200,10 @@ function astroConfigBuildPlugin(options, internals) {
176
200
  }))
177
201
  )
178
202
  );
203
+ } else {
204
+ newCode = newCode.replace(JSON.stringify(SCRIPTS_PLACEHOLDER), "[]");
179
205
  }
180
- mutate(chunk, "server", newCode);
206
+ mutate(chunk, ["server"], newCode);
181
207
  }
182
208
  }
183
209
  }
@@ -1,8 +1,10 @@
1
1
  import * as devalue from "devalue";
2
2
  import { extname } from "node:path";
3
3
  import { pathToFileURL } from "node:url";
4
+ import { getProxyCode } from "../assets/utils/proxy.js";
4
5
  import { AstroError } from "../core/errors/errors.js";
5
6
  import { AstroErrorData } from "../core/errors/index.js";
7
+ import { isServerLikeOutput } from "../prerender/utils.js";
6
8
  import { escapeViteEnvReferences } from "../vite-plugin-utils/index.js";
7
9
  import { CONTENT_FLAG, DATA_FLAG } from "./consts.js";
8
10
  import {
@@ -60,7 +62,7 @@ function astroContentImportPlugin({
60
62
  const code = escapeViteEnvReferences(`
61
63
  export const id = ${JSON.stringify(id)};
62
64
  export const collection = ${JSON.stringify(collection)};
63
- export const data = ${stringifyEntryData(data)};
65
+ export const data = ${stringifyEntryData(data, isServerLikeOutput(settings.config))};
64
66
  export const _internal = {
65
67
  type: 'data',
66
68
  filePath: ${JSON.stringify(_internal.filePath)},
@@ -83,7 +85,7 @@ export const _internal = {
83
85
  export const collection = ${JSON.stringify(collection)};
84
86
  export const slug = ${JSON.stringify(slug)};
85
87
  export const body = ${JSON.stringify(body)};
86
- export const data = ${stringifyEntryData(data)};
88
+ export const data = ${stringifyEntryData(data, isServerLikeOutput(settings.config))};
87
89
  export const _internal = {
88
90
  type: 'content',
89
91
  filePath: ${JSON.stringify(_internal.filePath)},
@@ -259,12 +261,16 @@ async function getContentConfigFromGlobal() {
259
261
  }
260
262
  return contentConfig;
261
263
  }
262
- function stringifyEntryData(data) {
264
+ function stringifyEntryData(data, isSSR) {
263
265
  try {
264
266
  return devalue.uneval(data, (value) => {
265
267
  if (value instanceof URL) {
266
268
  return `new URL(${JSON.stringify(value.href)})`;
267
269
  }
270
+ if (typeof value === "object" && "ASTRO_ASSET" in value) {
271
+ const { ASTRO_ASSET, ...asset } = value;
272
+ return getProxyCode(asset, isSSR);
273
+ }
268
274
  });
269
275
  } catch (e) {
270
276
  if (e instanceof Error) {