astro 2.1.9 → 2.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 (72) hide show
  1. package/client-base.d.ts +55 -5
  2. package/config.d.ts +2 -1
  3. package/dist/@types/astro.d.ts +25 -2
  4. package/dist/assets/image-endpoint.js +2 -2
  5. package/dist/assets/index.d.ts +1 -1
  6. package/dist/assets/index.js +3 -2
  7. package/dist/assets/internal.d.ts +2 -8
  8. package/dist/assets/services/service.d.ts +2 -2
  9. package/dist/assets/services/vendor/squoosh/image-pool.d.ts +2 -2
  10. package/dist/assets/services/vendor/squoosh/image.d.ts +2 -2
  11. package/dist/assets/types.d.ts +15 -9
  12. package/dist/assets/utils/emitAsset.d.ts +2 -1
  13. package/dist/assets/utils/emitAsset.js +4 -1
  14. package/dist/assets/vite-plugin-assets.js +11 -9
  15. package/dist/content/runtime-assets.d.ts +3 -7
  16. package/dist/content/runtime-assets.js +13 -20
  17. package/dist/content/template/virtual-mod.d.mts +1 -0
  18. package/dist/content/utils.d.ts +2 -6
  19. package/dist/content/utils.js +16 -56
  20. package/dist/content/vite-plugin-content-assets.js +13 -4
  21. package/dist/content/vite-plugin-content-imports.js +3 -4
  22. package/dist/content/vite-plugin-content-virtual-mod.js +1 -4
  23. package/dist/core/app/index.js +2 -0
  24. package/dist/core/build/add-rollup-input.d.ts +2 -2
  25. package/dist/core/build/generate.js +22 -6
  26. package/dist/core/build/internal.d.ts +3 -3
  27. package/dist/core/build/plugins/plugin-css.js +0 -29
  28. package/dist/core/build/plugins/plugin-internals.js +0 -7
  29. package/dist/core/build/plugins/plugin-ssr.js +12 -7
  30. package/dist/core/build/static-build.js +7 -3
  31. package/dist/core/config/schema.d.ts +12 -0
  32. package/dist/core/config/schema.js +2 -0
  33. package/dist/core/constants.js +1 -1
  34. package/dist/core/cookies/cookies.js +7 -0
  35. package/dist/core/create-vite.js +13 -0
  36. package/dist/core/dev/container.js +0 -5
  37. package/dist/core/dev/dev.js +1 -1
  38. package/dist/core/errors/errors-data.d.ts +11 -1
  39. package/dist/core/errors/errors-data.js +11 -1
  40. package/dist/core/messages.js +2 -2
  41. package/dist/core/render/dev/index.js +1 -1
  42. package/dist/core/render/dev/scripts.d.ts +1 -1
  43. package/dist/core/render/dev/scripts.js +7 -6
  44. package/dist/core/render/result.js +14 -3
  45. package/dist/core/render/ssr-element.d.ts +7 -6
  46. package/dist/core/render/ssr-element.js +28 -20
  47. package/dist/core/sync/index.js +9 -2
  48. package/dist/core/util.d.ts +1 -1
  49. package/dist/core/util.js +2 -2
  50. package/dist/runtime/server/index.d.ts +1 -1
  51. package/dist/runtime/server/index.js +2 -0
  52. package/dist/runtime/server/render/common.d.ts +1 -1
  53. package/dist/runtime/server/render/component.js +3 -3
  54. package/dist/runtime/server/render/dom.js +2 -2
  55. package/dist/runtime/server/render/index.d.ts +1 -1
  56. package/dist/runtime/server/render/index.js +2 -1
  57. package/dist/runtime/server/render/page.js +3 -2
  58. package/dist/runtime/server/render/slot.d.ts +2 -1
  59. package/dist/runtime/server/render/slot.js +21 -17
  60. package/dist/vite-plugin-astro-server/response.d.ts +1 -1
  61. package/dist/vite-plugin-astro-server/response.js +2 -1
  62. package/dist/vite-plugin-astro-server/route.js +1 -1
  63. package/dist/vite-plugin-env/index.js +9 -0
  64. package/dist/vite-plugin-integrations-container/index.d.ts +8 -0
  65. package/dist/vite-plugin-integrations-container/index.js +15 -0
  66. package/dist/vite-plugin-markdown/index.js +9 -12
  67. package/dist/vite-plugin-scanner/scan.js +17 -2
  68. package/package.json +4 -4
  69. package/src/content/template/types.d.ts +25 -10
  70. package/src/content/template/virtual-mod.mjs +7 -0
  71. package/dist/content/template/virtual-mod-assets.d.mts +0 -1
  72. package/src/content/template/virtual-mod-assets.mjs +0 -7
package/client-base.d.ts CHANGED
@@ -178,6 +178,10 @@ declare module '*.module.pcss' {
178
178
  const classes: CSSModuleClasses;
179
179
  export default classes;
180
180
  }
181
+ declare module '*.module.sss' {
182
+ const classes: CSSModuleClasses;
183
+ export default classes;
184
+ }
181
185
 
182
186
  // CSS
183
187
  declare module '*.css' {
@@ -208,9 +212,31 @@ declare module '*.pcss' {
208
212
  const css: string;
209
213
  export default css;
210
214
  }
215
+ declare module '*.sss' {
216
+ const css: string;
217
+ export default css;
218
+ }
211
219
 
212
220
  // Built-in asset types
213
- // see `src/constants.ts`
221
+ // see `src/node/constants.ts`
222
+
223
+ // images
224
+ declare module '*.jfif' {
225
+ const src: string;
226
+ export default src;
227
+ }
228
+ declare module '*.pjpeg' {
229
+ const src: string;
230
+ export default src;
231
+ }
232
+ declare module '*.pjp' {
233
+ const src: string;
234
+ export default src;
235
+ }
236
+ declare module '*.ico' {
237
+ const src: string;
238
+ export default src;
239
+ }
214
240
 
215
241
  // media
216
242
  declare module '*.mp4' {
@@ -242,6 +268,11 @@ declare module '*.aac' {
242
268
  export default src;
243
269
  }
244
270
 
271
+ declare module '*.opus' {
272
+ const src: string;
273
+ export default src;
274
+ }
275
+
245
276
  // fonts
246
277
  declare module '*.woff' {
247
278
  const src: string;
@@ -265,10 +296,6 @@ declare module '*.otf' {
265
296
  }
266
297
 
267
298
  // other
268
- declare module '*.wasm' {
269
- const initWasm: (options: WebAssembly.Imports) => Promise<WebAssembly.Exports>;
270
- export default initWasm;
271
- }
272
299
  declare module '*.webmanifest' {
273
300
  const src: string;
274
301
  export default src;
@@ -282,6 +309,12 @@ declare module '*.txt' {
282
309
  export default src;
283
310
  }
284
311
 
312
+ // wasm?init
313
+ declare module '*.wasm?init' {
314
+ const initWasm: (options: WebAssembly.Imports) => Promise<WebAssembly.Instance>;
315
+ export default initWasm;
316
+ }
317
+
285
318
  // web worker
286
319
  declare module '*?worker' {
287
320
  const workerConstructor: {
@@ -297,6 +330,11 @@ declare module '*?worker&inline' {
297
330
  export default workerConstructor;
298
331
  }
299
332
 
333
+ declare module '*?worker&url' {
334
+ const src: string;
335
+ export default src;
336
+ }
337
+
300
338
  declare module '*?sharedworker' {
301
339
  const sharedWorkerConstructor: {
302
340
  new (): SharedWorker;
@@ -304,6 +342,18 @@ declare module '*?sharedworker' {
304
342
  export default sharedWorkerConstructor;
305
343
  }
306
344
 
345
+ declare module '*?sharedworker&inline' {
346
+ const sharedWorkerConstructor: {
347
+ new (): SharedWorker;
348
+ };
349
+ export default sharedWorkerConstructor;
350
+ }
351
+
352
+ declare module '*?sharedworker&url' {
353
+ const src: string;
354
+ export default src;
355
+ }
356
+
307
357
  declare module '*?raw' {
308
358
  const src: string;
309
359
  export default src;
package/config.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  type ViteUserConfig = import('vite').UserConfig;
2
+ type ViteUserConfigFn = import('vite').UserConfigFn;
2
3
  type AstroUserConfig = import('./dist/@types/astro.js').AstroUserConfig;
3
4
 
4
5
  /**
@@ -10,4 +11,4 @@ export function defineConfig(config: AstroUserConfig): AstroUserConfig;
10
11
  /**
11
12
  * Use Astro to generate a fully resolved Vite config
12
13
  */
13
- export function getViteConfig(config: ViteUserConfig): ViteUserConfig;
14
+ export function getViteConfig(config: ViteUserConfig): ViteUserConfigFn;
@@ -18,8 +18,8 @@ import type { LogOptions } from '../core/logger/core';
18
18
  import type { AstroComponentFactory, AstroComponentInstance } from '../runtime/server';
19
19
  import type { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../core/constants.js';
20
20
  export type { MarkdownHeading, MarkdownMetadata, MarkdownRenderingResult, RehypePlugins, RemarkPlugins, ShikiConfig, } from '@astrojs/markdown-remark';
21
- export type { ExternalImageService, LocalImageService } from '../assets/services/service';
22
- export type { ImageMetadata, ImageTransform } from '../assets/types';
21
+ export type { ExternalImageService, ImageService, LocalImageService, } from '../assets/services/service';
22
+ export type { GetImageResult, ImageInputFormat, ImageMetadata, ImageOutputFormat, ImageQuality, ImageQualityPreset, ImageTransform, } from '../assets/types';
23
23
  export type { SSRManifest } from '../core/app/types';
24
24
  export type { AstroCookies } from '../core/cookies';
25
25
  export interface AstroBuiltinProps {
@@ -568,6 +568,29 @@ export interface AstroUserConfig {
568
568
  * ```
569
569
  */
570
570
  assets?: string;
571
+ /**
572
+ * @docs
573
+ * @name build.assetsPrefix
574
+ * @type {string}
575
+ * @default `undefined`
576
+ * @version 2.2.0
577
+ * @description
578
+ * Specifies the prefix for Astro-generated asset links. This can be used if assets are served from a different domain than the current site.
579
+ *
580
+ * For example, if this is set to `https://cdn.example.com`, assets will be fetched from `https://cdn.example.com/_astro/...` (regardless of the `base` option).
581
+ * You would need to upload the files in `./dist/_astro/` to `https://cdn.example.com/_astro/` to serve the assets.
582
+ * The process varies depending on how the third-party domain is hosted.
583
+ * To rename the `_astro` path, specify a new directory in `build.assets`.
584
+ *
585
+ * ```js
586
+ * {
587
+ * build: {
588
+ * assetsPrefix: 'https://cdn.example.com'
589
+ * }
590
+ * }
591
+ * ```
592
+ */
593
+ assetsPrefix?: string;
571
594
  /**
572
595
  * @docs
573
596
  * @name build.serverEntry
@@ -1,4 +1,4 @@
1
- import mime from "mime";
1
+ import mime from "mime/lite.js";
2
2
  import { isRemotePath } from "../core/path.js";
3
3
  import { getConfiguredImageService } from "./internal.js";
4
4
  import { isLocalService } from "./services/service.js";
@@ -35,7 +35,7 @@ const get = async ({ request }) => {
35
35
  return new Response(data, {
36
36
  status: 200,
37
37
  headers: {
38
- "Content-Type": mime.getType(format) || "",
38
+ "Content-Type": mime.getType(format) ?? `image/${format}`,
39
39
  "Cache-Control": "public, max-age=31536000",
40
40
  ETag: etag(data.toString()),
41
41
  Date: (/* @__PURE__ */ new Date()).toUTCString()
@@ -1,5 +1,5 @@
1
1
  export { getConfiguredImageService, getImage } from './internal.js';
2
- export { baseService } from './services/service.js';
2
+ export { baseService, isLocalService } from './services/service.js';
3
3
  export { type LocalImageProps, type RemoteImageProps } from './types.js';
4
4
  export { emitESMImage } from './utils/emitAsset.js';
5
5
  export { imageMetadata } from './utils/metadata.js';
@@ -1,5 +1,5 @@
1
1
  import { getConfiguredImageService, getImage } from "./internal.js";
2
- import { baseService } from "./services/service.js";
2
+ import { baseService, isLocalService } from "./services/service.js";
3
3
  import {} from "./types.js";
4
4
  import { emitESMImage } from "./utils/emitAsset.js";
5
5
  import { imageMetadata } from "./utils/metadata.js";
@@ -8,5 +8,6 @@ export {
8
8
  emitESMImage,
9
9
  getConfiguredImageService,
10
10
  getImage,
11
- imageMetadata
11
+ imageMetadata,
12
+ isLocalService
12
13
  };
@@ -1,14 +1,8 @@
1
1
  import type { StaticBuildOptions } from '../core/build/types.js';
2
2
  import { type ImageService } from './services/service.js';
3
- import type { ImageMetadata, ImageTransform } from './types.js';
3
+ import type { GetImageResult, ImageMetadata, ImageTransform } from './types.js';
4
4
  export declare function isESMImportedImage(src: ImageMetadata | string): src is ImageMetadata;
5
5
  export declare function getConfiguredImageService(): Promise<ImageService>;
6
- interface GetImageResult {
7
- rawOptions: ImageTransform;
8
- options: ImageTransform;
9
- src: string;
10
- attributes: Record<string, any>;
11
- }
12
6
  /**
13
7
  * Get an optimized image and the necessary attributes to render it.
14
8
  *
@@ -18,7 +12,7 @@ interface GetImageResult {
18
12
  * import { getImage } from 'astro:assets';
19
13
  * import originalImage from '../assets/image.png';
20
14
  *
21
- * const optimizedImage = await getImage({src: originalImage, width: 1280 })
15
+ * const optimizedImage = await getImage({src: originalImage, width: 1280 });
22
16
  * ---
23
17
  * <img src={optimizedImage.src} {...optimizedImage.attributes} />
24
18
  * ```
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import type { ImageTransform, OutputFormat } from '../types.js';
2
+ import type { ImageOutputFormat, ImageTransform } from '../types.js';
3
3
  export type ImageService = LocalImageService | ExternalImageService;
4
4
  export declare function isLocalService(service: ImageService | undefined): service is LocalImageService;
5
5
  export declare function parseQuality(quality: string): string | number;
@@ -48,7 +48,7 @@ export interface LocalImageService extends SharedServiceProps {
48
48
  */
49
49
  transform: (inputBuffer: Buffer, transform: LocalImageTransform) => Promise<{
50
50
  data: Buffer;
51
- format: OutputFormat;
51
+ format: ImageOutputFormat;
52
52
  }>;
53
53
  }
54
54
  export type BaseServiceTransform = {
@@ -1,4 +1,4 @@
1
1
  /// <reference types="node" />
2
- import type { OutputFormat } from '../../../types.js';
2
+ import type { ImageOutputFormat } from '../../../types.js';
3
3
  import type { Operation } from './image.js';
4
- export declare function processBuffer(buffer: Buffer, operations: Operation[], encoding: OutputFormat, quality?: number): Promise<Uint8Array>;
4
+ export declare function processBuffer(buffer: Buffer, operations: Operation[], encoding: ImageOutputFormat, quality?: number): Promise<Uint8Array>;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import type { OutputFormat } from '../../../types.js';
2
+ import type { ImageOutputFormat } from '../../../types.js';
3
3
  type RotateOperation = {
4
4
  type: 'rotate';
5
5
  numRotations: number;
@@ -10,5 +10,5 @@ type ResizeOperation = {
10
10
  height?: number;
11
11
  };
12
12
  export type Operation = RotateOperation | ResizeOperation;
13
- export declare function processBuffer(buffer: Buffer, operations: Operation[], encoding: OutputFormat, quality?: number): Promise<Uint8Array>;
13
+ export declare function processBuffer(buffer: Buffer, operations: Operation[], encoding: ImageOutputFormat, quality?: number): Promise<Uint8Array>;
14
14
  export {};
@@ -2,8 +2,8 @@ import type { VALID_INPUT_FORMATS, VALID_OUTPUT_FORMATS } from './consts.js';
2
2
  import type { ImageService } from './services/service.js';
3
3
  export type ImageQualityPreset = 'low' | 'mid' | 'high' | 'max' | (string & {});
4
4
  export type ImageQuality = ImageQualityPreset | number;
5
- export type InputFormat = (typeof VALID_INPUT_FORMATS)[number] | 'svg';
6
- export type OutputFormat = (typeof VALID_OUTPUT_FORMATS)[number] | (string & {});
5
+ export type ImageInputFormat = (typeof VALID_INPUT_FORMATS)[number] | 'svg';
6
+ export type ImageOutputFormat = (typeof VALID_OUTPUT_FORMATS)[number] | (string & {});
7
7
  declare global {
8
8
  var astroAsset: {
9
9
  imageService?: ImageService;
@@ -21,19 +21,25 @@ export interface ImageMetadata {
21
21
  src: string;
22
22
  width: number;
23
23
  height: number;
24
- format: InputFormat;
24
+ format: ImageInputFormat;
25
25
  }
26
26
  /**
27
27
  * Options accepted by the image transformation service.
28
28
  */
29
29
  export type ImageTransform = {
30
30
  src: ImageMetadata | string;
31
- width?: number;
32
- height?: number;
33
- quality?: ImageQuality;
34
- format?: OutputFormat;
31
+ width?: number | undefined;
32
+ height?: number | undefined;
33
+ quality?: ImageQuality | undefined;
34
+ format?: ImageOutputFormat | undefined;
35
35
  [key: string]: any;
36
36
  };
37
+ export interface GetImageResult {
38
+ rawOptions: ImageTransform;
39
+ options: ImageTransform;
40
+ src: string;
41
+ attributes: Record<string, any>;
42
+ }
37
43
  type WithRequired<T, K extends keyof T> = T & {
38
44
  [P in K]-?: T[P];
39
45
  };
@@ -91,11 +97,11 @@ export type LocalImageProps<T> = ImageSharedProps<T> & {
91
97
  * <Image src={...} format="avif" alt="..." />
92
98
  * ```
93
99
  */
94
- format?: OutputFormat;
100
+ format?: ImageOutputFormat;
95
101
  /**
96
102
  * Desired quality for the image. Value can either be a preset such as `low` or `high`, or a numeric value from 0 to 100.
97
103
  *
98
- * The perceptual quality of the output image is loader-specific.
104
+ * The perceptual quality of the output image is service-specific.
99
105
  * For instance, a certain service might decide that `high` results in a very beautiful image, but another could choose for it to be at best passable.
100
106
  *
101
107
  * **Example**:
@@ -1,3 +1,4 @@
1
1
  import type { AstroSettings } from '../../@types/astro';
2
- export declare function emitESMImage(id: string, watchMode: boolean, fileEmitter: any, settings: Pick<AstroSettings, 'config'>): Promise<import("./metadata.js").Metadata | undefined>;
2
+ import { type Metadata } from './metadata.js';
3
+ export declare function emitESMImage(id: string | undefined, watchMode: boolean, fileEmitter: any, settings: Pick<AstroSettings, 'config'>): Promise<Metadata | undefined>;
3
4
  export declare function emoji(char: string, fallback: string): string;
@@ -4,10 +4,13 @@ import { fileURLToPath, pathToFileURL } from "node:url";
4
4
  import slash from "slash";
5
5
  import { imageMetadata } from "./metadata.js";
6
6
  async function emitESMImage(id, watchMode, fileEmitter, settings) {
7
+ if (!id) {
8
+ return void 0;
9
+ }
7
10
  const url = pathToFileURL(id);
8
11
  const meta = await imageMetadata(url);
9
12
  if (!meta) {
10
- return;
13
+ return void 0;
11
14
  }
12
15
  if (!watchMode) {
13
16
  const pathname = decodeURI(url.pathname);
@@ -1,12 +1,12 @@
1
1
  import { bold } from "kleur/colors";
2
2
  import MagicString from "magic-string";
3
- import mime from "mime";
3
+ import mime from "mime/lite.js";
4
4
  import fs from "node:fs/promises";
5
5
  import { Readable } from "node:stream";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { normalizePath } from "vite";
8
8
  import { error } from "../core/logger/core.js";
9
- import { joinPaths, prependForwardSlash } from "../core/path.js";
9
+ import { appendForwardSlash, joinPaths, prependForwardSlash } from "../core/path.js";
10
10
  import { VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from "./consts.js";
11
11
  import { isESMImportedImage } from "./internal.js";
12
12
  import { isLocalService } from "./services/service.js";
@@ -69,7 +69,7 @@ function assets({
69
69
  load(id) {
70
70
  if (id === resolvedVirtualModuleId) {
71
71
  return `
72
- export { getImage, getConfiguredImageService } from "astro/assets";
72
+ export { getImage, getConfiguredImageService, isLocalService } from "astro/assets";
73
73
  export { default as Image } from "astro/components/Image.astro";
74
74
  `;
75
75
  }
@@ -107,10 +107,7 @@ function assets({
107
107
  data = result.data;
108
108
  format = result.format;
109
109
  }
110
- res.setHeader(
111
- "Content-Type",
112
- mime.getType(fileURLToPath(filePathURL)) || `image/${format}`
113
- );
110
+ res.setHeader("Content-Type", mime.getType(format) ?? `image/${format}`);
114
111
  res.setHeader("Cache-Control", "max-age=360000");
115
112
  const stream = Readable.from(data);
116
113
  return stream.pipe(res);
@@ -139,7 +136,11 @@ function assets({
139
136
  );
140
137
  globalThis.astroAsset.staticImages.set(hash, { path: filePath, options });
141
138
  }
142
- return prependForwardSlash(joinPaths(settings.config.base, filePath));
139
+ if (settings.config.build.assetsPrefix) {
140
+ return joinPaths(settings.config.build.assetsPrefix, filePath);
141
+ } else {
142
+ return prependForwardSlash(joinPaths(settings.config.base, filePath));
143
+ }
143
144
  };
144
145
  },
145
146
  async buildEnd() {
@@ -160,7 +161,8 @@ function assets({
160
161
  s = s || (s = new MagicString(code));
161
162
  const [full, hash, postfix = ""] = match;
162
163
  const file = this.getFileName(hash);
163
- const outputFilepath = normalizePath(resolvedConfig.base + file + postfix);
164
+ const prefix = settings.config.build.assetsPrefix ? appendForwardSlash(settings.config.build.assetsPrefix) : resolvedConfig.base;
165
+ const outputFilepath = prefix + normalizePath(file + postfix);
164
166
  s.overwrite(match.index, match.index + full.length, outputFilepath);
165
167
  }
166
168
  if (s) {
@@ -1,8 +1,4 @@
1
+ import type { PluginContext } from 'rollup';
1
2
  import { z } from 'zod';
2
- import { type Metadata } from '../assets/utils/metadata.js';
3
- export declare function createImage(options: {
4
- assetsDir: string;
5
- relAssetsDir: string;
6
- }): () => z.ZodEffects<z.ZodString, Metadata & {
7
- __astro_asset: true;
8
- }, string>;
3
+ import type { AstroSettings } from '../@types/astro.js';
4
+ export declare function createImage(settings: AstroSettings, pluginContext: PluginContext, entryFilePath: string): () => z.ZodEffects<z.ZodString, import("../assets/utils/metadata.js").Metadata, string>;
@@ -1,16 +1,17 @@
1
- import { pathToFileURL } from "url";
2
1
  import { z } from "zod";
3
- import {
4
- imageMetadata as internalGetImageMetadata
5
- } from "../assets/utils/metadata.js";
6
- function createImage(options) {
2
+ import { emitESMImage } from "../assets/index.js";
3
+ function createImage(settings, pluginContext, entryFilePath) {
7
4
  return () => {
8
- if (options.assetsDir === "undefined") {
9
- throw new Error("Enable `experimental.assets` in your Astro config to use image()");
10
- }
11
- return z.string({ description: "__image" }).transform(async (imagePath, ctx) => {
12
- const imageMetadata = await getImageMetadata(pathToFileURL(imagePath));
13
- if (!imageMetadata) {
5
+ return z.string().transform(async (imagePath, ctx) => {
6
+ var _a;
7
+ const resolvedFilePath = (_a = await pluginContext.resolve(imagePath, entryFilePath)) == null ? void 0 : _a.id;
8
+ const metadata = await emitESMImage(
9
+ resolvedFilePath,
10
+ pluginContext.meta.watchMode,
11
+ pluginContext.emitFile,
12
+ settings
13
+ );
14
+ if (!metadata) {
14
15
  ctx.addIssue({
15
16
  code: "custom",
16
17
  message: `Image ${imagePath} does not exist. Is the path correct?`,
@@ -18,18 +19,10 @@ function createImage(options) {
18
19
  });
19
20
  return z.NEVER;
20
21
  }
21
- return imageMetadata;
22
+ return metadata;
22
23
  });
23
24
  };
24
25
  }
25
- async function getImageMetadata(imagePath) {
26
- const meta = await internalGetImageMetadata(imagePath);
27
- if (!meta) {
28
- return void 0;
29
- }
30
- delete meta.orientation;
31
- return { ...meta, __astro_asset: true };
32
- }
33
26
  export {
34
27
  createImage
35
28
  };
@@ -1,3 +1,4 @@
1
1
  export function defineCollection(config: any): any;
2
+ export function image(): never;
2
3
  export const getCollection: any;
3
4
  export const getEntryBySlug: any;
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import matter from 'gray-matter';
3
3
  import fsMod from 'node:fs';
4
- import type { EmitFile, PluginContext } from 'rollup';
4
+ import type { PluginContext } from 'rollup';
5
5
  import { type ViteDevServer } from 'vite';
6
6
  import { z } from 'zod';
7
7
  import type { AstroConfig, AstroSettings } from '../@types/astro.js';
@@ -47,17 +47,13 @@ export type EntryInfo = {
47
47
  export declare const msg: {
48
48
  collectionConfigMissing: (collection: string) => string;
49
49
  };
50
- /**
51
- * Mutate (arf) the entryData to reroute assets to their final paths
52
- */
53
- export declare function patchAssets(frontmatterEntry: Record<string, any>, watchMode: boolean, fileEmitter: EmitFile, astroSettings: AstroSettings): Promise<void>;
54
50
  export declare function getEntrySlug({ id, collection, slug, unvalidatedSlug, }: EntryInfo & {
55
51
  unvalidatedSlug?: unknown;
56
52
  }): string;
57
53
  export declare function getEntryData(entry: EntryInfo & {
58
54
  unvalidatedData: Record<string, unknown>;
59
55
  _internal: EntryInternal;
60
- }, collectionConfig: CollectionConfig, resolver: (idToResolve: string) => ReturnType<PluginContext['resolve']>): Promise<{
56
+ }, collectionConfig: CollectionConfig, pluginContext: PluginContext, settings: AstroSettings): Promise<{
61
57
  [x: string]: unknown;
62
58
  }>;
63
59
  export declare function getContentEntryExts(settings: Pick<AstroSettings, 'contentEntryTypes'>): string[];
@@ -5,10 +5,10 @@ import path from "node:path";
5
5
  import { fileURLToPath, pathToFileURL } from "node:url";
6
6
  import { normalizePath } from "vite";
7
7
  import { z } from "zod";
8
- import { emitESMImage } from "../assets/utils/emitAsset.js";
9
8
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
10
9
  import { CONTENT_TYPES_FILE } from "./consts.js";
11
10
  import { errorMap } from "./error-map.js";
11
+ import { createImage } from "./runtime-assets.js";
12
12
  const collectionConfigParser = z.object({
13
13
  schema: z.any().optional()
14
14
  });
@@ -25,22 +25,6 @@ const contentConfigParser = z.object({
25
25
  const msg = {
26
26
  collectionConfigMissing: (collection) => `${collection} does not have a config. We suggest adding one for type safety!`
27
27
  };
28
- async function patchAssets(frontmatterEntry, watchMode, fileEmitter, astroSettings) {
29
- for (const key of Object.keys(frontmatterEntry)) {
30
- if (typeof frontmatterEntry[key] === "object" && frontmatterEntry[key] !== null) {
31
- if (frontmatterEntry[key]["__astro_asset"]) {
32
- frontmatterEntry[key] = await emitESMImage(
33
- frontmatterEntry[key].src,
34
- watchMode,
35
- fileEmitter,
36
- astroSettings
37
- );
38
- } else {
39
- await patchAssets(frontmatterEntry[key], watchMode, fileEmitter, astroSettings);
40
- }
41
- }
42
- }
43
- }
44
28
  function getEntrySlug({
45
29
  id,
46
30
  collection,
@@ -56,50 +40,27 @@ function getEntrySlug({
56
40
  });
57
41
  }
58
42
  }
59
- async function getEntryData(entry, collectionConfig, resolver) {
43
+ async function getEntryData(entry, collectionConfig, pluginContext, settings) {
60
44
  let { slug, ...data } = entry.unvalidatedData;
61
- if (collectionConfig.schema) {
62
- if (typeof collectionConfig.schema === "object" && !("safeParseAsync" in collectionConfig.schema)) {
63
- throw new AstroError({
64
- title: "Invalid content collection config",
65
- message: `New: Content collection schemas must be Zod objects. Update your collection config to use \`schema: z.object({...})\` instead of \`schema: {...}\`.`,
66
- hint: "See https://docs.astro.build/en/reference/api-reference/#definecollection for an example.",
67
- code: 99999
68
- });
45
+ let schema = collectionConfig.schema;
46
+ if (typeof schema === "function") {
47
+ if (!settings.config.experimental.assets) {
48
+ throw new Error(
49
+ "The function shape for schema can only be used when `experimental.assets` is enabled."
50
+ );
69
51
  }
70
- if (typeof collectionConfig.schema === "object" && "shape" in collectionConfig.schema && collectionConfig.schema.shape.slug) {
52
+ schema = schema({
53
+ image: createImage(settings, pluginContext, entry._internal.filePath)
54
+ });
55
+ }
56
+ if (schema) {
57
+ if (typeof schema === "object" && "shape" in schema && schema.shape.slug) {
71
58
  throw new AstroError({
72
59
  ...AstroErrorData.ContentSchemaContainsSlugError,
73
60
  message: AstroErrorData.ContentSchemaContainsSlugError.message(entry.collection)
74
61
  });
75
62
  }
76
- async function preprocessAssetPaths(object) {
77
- if (typeof object !== "object" || object === null)
78
- return;
79
- for (let [schemaName, schema] of Object.entries(object)) {
80
- if (schema._def.description === "__image") {
81
- object[schemaName] = z.preprocess(
82
- async (value) => {
83
- var _a;
84
- if (!value || typeof value !== "string")
85
- return value;
86
- return ((_a = await resolver(value)) == null ? void 0 : _a.id) ?? path.join(path.dirname(entry._internal.filePath), value);
87
- },
88
- schema,
89
- { description: "__image" }
90
- );
91
- } else if ("shape" in schema) {
92
- await preprocessAssetPaths(schema.shape);
93
- } else if ("unwrap" in schema) {
94
- const unwrapped = schema.unwrap().shape;
95
- if (unwrapped) {
96
- await preprocessAssetPaths(unwrapped);
97
- }
98
- }
99
- }
100
- }
101
- await preprocessAssetPaths(collectionConfig.schema.shape);
102
- const parsed = await collectionConfig.schema.safeParseAsync(entry.unvalidatedData, {
63
+ const parsed = await schema.safeParseAsync(entry.unvalidatedData, {
103
64
  errorMap
104
65
  });
105
66
  if (parsed.success) {
@@ -288,6 +249,5 @@ export {
288
249
  globalContentConfigObserver,
289
250
  loadContentConfig,
290
251
  msg,
291
- parseFrontmatter,
292
- patchAssets
252
+ parseFrontmatter
293
253
  };
@@ -1,9 +1,8 @@
1
- import npath from "node:path";
2
1
  import { pathToFileURL } from "url";
3
2
  import { moduleIsTopLevelPage, walkParentInfos } from "../core/build/graph.js";
4
3
  import { getPageDataByViteID } from "../core/build/internal.js";
5
4
  import { createViteLoader } from "../core/module-loader/vite.js";
6
- import { prependForwardSlash } from "../core/path.js";
5
+ import { joinPaths, prependForwardSlash } from "../core/path.js";
7
6
  import { getStylesForURL } from "../core/render/dev/css.js";
8
7
  import { getScriptsForURL } from "../core/render/dev/scripts.js";
9
8
  import {
@@ -59,7 +58,11 @@ function astroContentAssetPropagationPlugin({
59
58
  devModuleLoader,
60
59
  "development"
61
60
  );
62
- const hoistedScripts = await getScriptsForURL(pathToFileURL(basePath), devModuleLoader);
61
+ const hoistedScripts = await getScriptsForURL(
62
+ pathToFileURL(basePath),
63
+ settings.config.root,
64
+ devModuleLoader
65
+ );
63
66
  return {
64
67
  code: code.replace(JSON.stringify(LINKS_PLACEHOLDER), JSON.stringify([...urls])).replace(JSON.stringify(STYLES_PLACEHOLDER), JSON.stringify([...stylesMap.values()])).replace(JSON.stringify(SCRIPTS_PLACEHOLDER), JSON.stringify([...hoistedScripts]))
65
68
  };
@@ -87,7 +90,13 @@ function astroConfigBuildPlugin(options, internals) {
87
90
  "build:post": ({ ssrOutputs, clientOutputs, mutate }) => {
88
91
  var _a, _b;
89
92
  const outputs = ssrOutputs.flatMap((o) => o.output);
90
- const prependBase = (src) => prependForwardSlash(npath.posix.join(options.settings.config.base, src));
93
+ const prependBase = (src) => {
94
+ if (options.settings.config.build.assetsPrefix) {
95
+ return joinPaths(options.settings.config.build.assetsPrefix, src);
96
+ } else {
97
+ return prependForwardSlash(joinPaths(options.settings.config.base, src));
98
+ }
99
+ };
91
100
  for (const chunk of outputs) {
92
101
  if (chunk.type === "chunk" && (chunk.code.includes(LINKS_PLACEHOLDER) || chunk.code.includes(SCRIPTS_PLACEHOLDER))) {
93
102
  let entryCSS = /* @__PURE__ */ new Set();