astro 5.0.1 → 5.0.3

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 (38) hide show
  1. package/components/Image.astro +2 -2
  2. package/components/Picture.astro +2 -2
  3. package/dist/assets/utils/resolveImports.js +1 -1
  4. package/dist/cli/info/index.d.ts +2 -0
  5. package/dist/cli/info/index.js +71 -26
  6. package/dist/container/index.js +2 -1
  7. package/dist/content/content-layer.js +3 -3
  8. package/dist/content/vite-plugin-content-virtual-mod.js +2 -4
  9. package/dist/core/app/index.d.ts +1 -0
  10. package/dist/core/app/index.js +23 -16
  11. package/dist/core/build/generate.js +4 -2
  12. package/dist/core/build/index.js +2 -2
  13. package/dist/core/build/plugins/plugin-renderers.js +1 -1
  14. package/dist/core/build/plugins/plugin-ssr.js +1 -1
  15. package/dist/core/build/static-build.d.ts +2 -1
  16. package/dist/core/build/static-build.js +13 -15
  17. package/dist/core/config/schema.d.ts +18 -20
  18. package/dist/core/config/schema.js +14 -8
  19. package/dist/core/config/validate.js +2 -1
  20. package/dist/core/constants.js +1 -1
  21. package/dist/core/dev/container.js +2 -1
  22. package/dist/core/dev/dev.js +2 -2
  23. package/dist/core/errors/errors-data.d.ts +15 -15
  24. package/dist/core/errors/errors-data.js +8 -8
  25. package/dist/core/errors/zod-error-map.js +46 -26
  26. package/dist/core/messages.js +6 -4
  27. package/dist/core/render-context.d.ts +3 -2
  28. package/dist/core/render-context.js +14 -8
  29. package/dist/core/request.d.ts +2 -1
  30. package/dist/core/request.js +3 -6
  31. package/dist/core/sync/index.d.ts +1 -0
  32. package/dist/core/sync/index.js +3 -0
  33. package/dist/i18n/index.js +2 -2
  34. package/dist/runtime/server/render/component.js +0 -6
  35. package/dist/types/public/config.d.ts +3 -3
  36. package/dist/vite-plugin-astro-server/route.js +6 -4
  37. package/package.json +1 -1
  38. package/templates/content/types.d.ts +3 -1
@@ -47,7 +47,7 @@ if (import.meta.env.DEV) {
47
47
  additionalAttributes['data-image-component'] = 'true';
48
48
  }
49
49
 
50
- const attributes = useResponsive
50
+ const { class: className, ...attributes } = useResponsive
51
51
  ? applyResponsiveAttributes({
52
52
  layout,
53
53
  image,
@@ -58,4 +58,4 @@ const attributes = useResponsive
58
58
  ---
59
59
 
60
60
  {/* Applying class outside of the spread prevents it from applying unnecessary astro-* classes */}
61
- <img src={image.src} {...attributes} class={attributes.class} />
61
+ <img src={image.src} {...attributes} class={className} />
@@ -102,7 +102,7 @@ if (fallbackImage.srcSet.values.length > 0) {
102
102
  imgAdditionalAttributes.srcset = fallbackImage.srcSet.attribute;
103
103
  }
104
104
 
105
- const attributes = useResponsive
105
+ const { class: className, ...attributes } = useResponsive
106
106
  ? applyResponsiveAttributes({
107
107
  layout,
108
108
  image: fallbackImage,
@@ -133,5 +133,5 @@ if (import.meta.env.DEV) {
133
133
  })
134
134
  }
135
135
  {/* Applying class outside of the spread prevents it from applying unnecessary astro-* classes */}
136
- <img src={fallbackImage.src} {...attributes} class={attributes.class} />
136
+ <img src={fallbackImage.src} {...attributes} class={className} />
137
137
  </picture>
@@ -7,7 +7,7 @@ function imageSrcToImportId(imageSrc, filePath) {
7
7
  if (isRemotePath(imageSrc)) {
8
8
  return;
9
9
  }
10
- const ext = imageSrc.split(".").at(-1);
10
+ const ext = imageSrc.split(".").at(-1)?.toLowerCase();
11
11
  if (!ext || !VALID_INPUT_FORMATS.includes(ext)) {
12
12
  return;
13
13
  }
@@ -8,4 +8,6 @@ export declare function getInfoOutput({ userConfig, print, }: {
8
8
  print: boolean;
9
9
  }): Promise<string>;
10
10
  export declare function printInfo({ flags }: InfoOptions): Promise<void>;
11
+ export declare function copyToClipboard(text: string, force?: boolean): Promise<void>;
12
+ export declare function readFromClipboard(): string;
11
13
  export {};
@@ -1,4 +1,4 @@
1
- import { execSync } from "node:child_process";
1
+ import { spawnSync } from "node:child_process";
2
2
  import { arch, platform } from "node:os";
3
3
  import * as colors from "kleur/colors";
4
4
  import prompts from "prompts";
@@ -33,48 +33,55 @@ async function printInfo({ flags }) {
33
33
  applyPolyfill();
34
34
  const { userConfig } = await resolveConfig(flagsToAstroInlineConfig(flags), "info");
35
35
  const output = await getInfoOutput({ userConfig, print: true });
36
- await copyToClipboard(output);
36
+ await copyToClipboard(output, flags.copy);
37
37
  }
38
- async function copyToClipboard(text) {
38
+ async function copyToClipboard(text, force) {
39
39
  text = text.trim();
40
40
  const system = platform();
41
41
  let command = "";
42
+ let args = [];
42
43
  if (system === "darwin") {
43
44
  command = "pbcopy";
44
45
  } else if (system === "win32") {
45
46
  command = "clip";
46
47
  } else {
47
48
  const unixCommands = [
48
- ["xclip", "-sel clipboard -l 1"],
49
- ["wl-copy", '"$0"']
49
+ ["xclip", ["-sel", "clipboard", "-l", "1"]],
50
+ ["wl-copy", []]
50
51
  ];
51
- for (const [unixCommand, args] of unixCommands) {
52
+ for (const [unixCommand, unixArgs] of unixCommands) {
52
53
  try {
53
- const output = execSync(`which ${unixCommand}`, { encoding: "utf8", stdio: "pipe" });
54
- if (output[0] !== "/") {
55
- continue;
54
+ const output = spawnSync("which", [unixCommand], { encoding: "utf8" });
55
+ if (output.stdout.trim()) {
56
+ command = unixCommand;
57
+ args = unixArgs;
58
+ break;
56
59
  }
57
- command = `${unixCommand} ${args}`;
58
60
  } catch {
59
61
  continue;
60
62
  }
61
63
  }
62
- if (!command) return;
63
64
  }
64
- console.log();
65
- const { shouldCopy } = await prompts({
66
- type: "confirm",
67
- name: "shouldCopy",
68
- message: "Copy to clipboard?",
69
- initial: true
70
- });
71
- if (!shouldCopy) return;
72
- try {
73
- execSync(command.replaceAll("$0", text), {
74
- stdio: "ignore",
75
- input: text,
76
- encoding: "utf8"
65
+ if (!command) {
66
+ console.error(colors.red("\nClipboard command not found!"));
67
+ console.info("Please manually copy the text above.");
68
+ return;
69
+ }
70
+ if (!force) {
71
+ const { shouldCopy } = await prompts({
72
+ type: "confirm",
73
+ name: "shouldCopy",
74
+ message: "Copy to clipboard?",
75
+ initial: true
77
76
  });
77
+ if (!shouldCopy) return;
78
+ }
79
+ try {
80
+ const result = spawnSync(command, args, { input: text });
81
+ if (result.error) {
82
+ throw result.error;
83
+ }
84
+ console.info(colors.green("Copied to clipboard!"));
78
85
  } catch {
79
86
  console.error(
80
87
  colors.red(`
@@ -82,6 +89,42 @@ Sorry, something went wrong!`) + ` Please copy the text above manually.`
82
89
  );
83
90
  }
84
91
  }
92
+ function readFromClipboard() {
93
+ const system = platform();
94
+ let command = "";
95
+ let args = [];
96
+ if (system === "darwin") {
97
+ command = "pbpaste";
98
+ } else if (system === "win32") {
99
+ command = "powershell";
100
+ args = ["-command", "Get-Clipboard"];
101
+ } else {
102
+ const unixCommands = [
103
+ ["xclip", ["-sel", "clipboard", "-o"]],
104
+ ["wl-paste", []]
105
+ ];
106
+ for (const [unixCommand, unixArgs] of unixCommands) {
107
+ try {
108
+ const output = spawnSync("which", [unixCommand], { encoding: "utf8" });
109
+ if (output.stdout.trim()) {
110
+ command = unixCommand;
111
+ args = unixArgs;
112
+ break;
113
+ }
114
+ } catch {
115
+ continue;
116
+ }
117
+ }
118
+ }
119
+ if (!command) {
120
+ throw new Error("Clipboard read command not found!");
121
+ }
122
+ const result = spawnSync(command, args, { encoding: "utf8" });
123
+ if (result.error) {
124
+ throw result.error;
125
+ }
126
+ return result.stdout.trim();
127
+ }
85
128
  const PLATFORM_TO_OS = {
86
129
  darwin: "macOS",
87
130
  win32: "Windows",
@@ -115,11 +158,13 @@ ${" ".repeat(MAX_PADDING)}${colors.green(entry)}`;
115
158
  }
116
159
  plaintext += "\n";
117
160
  if (print) {
118
- console.log(richtext);
161
+ console.info(richtext);
119
162
  }
120
163
  return plaintext;
121
164
  }
122
165
  export {
166
+ copyToClipboard,
123
167
  getInfoOutput,
124
- printInfo
168
+ printInfo,
169
+ readFromClipboard
125
170
  };
@@ -267,7 +267,8 @@ class experimental_AstroContainer {
267
267
  request,
268
268
  pathname: url.pathname,
269
269
  locals: options?.locals ?? {},
270
- partial: options?.partial ?? true
270
+ partial: options?.partial ?? true,
271
+ clientAddress: ""
271
272
  });
272
273
  if (options.params) {
273
274
  renderContext.params = options.params;
@@ -114,7 +114,7 @@ class ContentLayer {
114
114
  logger.info("Content config changed");
115
115
  shouldClear = true;
116
116
  }
117
- if (previousAstroVersion !== "5.0.1") {
117
+ if (previousAstroVersion !== "5.0.3") {
118
118
  logger.info("Astro version changed");
119
119
  shouldClear = true;
120
120
  }
@@ -122,8 +122,8 @@ class ContentLayer {
122
122
  logger.info("Clearing content store");
123
123
  this.#store.clearAll();
124
124
  }
125
- if ("5.0.1") {
126
- await this.#store.metaStore().set("astro-version", "5.0.1");
125
+ if ("5.0.3") {
126
+ await this.#store.metaStore().set("astro-version", "5.0.3");
127
127
  }
128
128
  if (currentConfigDigest) {
129
129
  await this.#store.metaStore().set("config-digest", currentConfigDigest);
@@ -40,14 +40,12 @@ function astroContentVirtualModPlugin({
40
40
  settings,
41
41
  fs
42
42
  }) {
43
- let IS_DEV = false;
44
43
  let dataStoreFile;
45
44
  return {
46
45
  name: "astro-content-virtual-mod-plugin",
47
46
  enforce: "pre",
48
- configResolved(config) {
49
- IS_DEV = !config.isProduction;
50
- dataStoreFile = getDataStoreFile(settings, IS_DEV);
47
+ config(_, env) {
48
+ dataStoreFile = getDataStoreFile(settings, env.command === "serve");
51
49
  },
52
50
  async resolveId(id) {
53
51
  if (id === VIRTUAL_MODULE_ID) {
@@ -44,6 +44,7 @@ export interface RenderErrorOptions {
44
44
  * Allows passing an error to 500.astro. It will be available through `Astro.props.error`.
45
45
  */
46
46
  error?: unknown;
47
+ clientAddress: string | undefined;
47
48
  }
48
49
  export declare class App {
49
50
  #private;
@@ -156,7 +156,7 @@ class App {
156
156
  let clientAddress;
157
157
  let addCookieHeader;
158
158
  addCookieHeader = renderOptions?.addCookieHeader;
159
- clientAddress = renderOptions?.clientAddress;
159
+ clientAddress = renderOptions?.clientAddress ?? Reflect.get(request, clientAddressSymbol);
160
160
  routeData = renderOptions?.routeData;
161
161
  locals = renderOptions?.locals;
162
162
  if (routeData) {
@@ -171,13 +171,10 @@ class App {
171
171
  if (typeof locals !== "object") {
172
172
  const error = new AstroError(AstroErrorData.LocalsNotAnObject);
173
173
  this.#logger.error(null, error.stack);
174
- return this.#renderError(request, { status: 500, error });
174
+ return this.#renderError(request, { status: 500, error, clientAddress });
175
175
  }
176
176
  Reflect.set(request, clientLocalsSymbol, locals);
177
177
  }
178
- if (clientAddress) {
179
- Reflect.set(request, clientAddressSymbol, clientAddress);
180
- }
181
178
  if (!routeData) {
182
179
  routeData = this.match(request);
183
180
  this.#logger.debug("router", "Astro matched the following route for " + request.url);
@@ -186,7 +183,7 @@ class App {
186
183
  if (!routeData) {
187
184
  this.#logger.debug("router", "Astro hasn't found routes that match " + request.url);
188
185
  this.#logger.debug("router", "Here's the available routes:\n", this.#manifestData);
189
- return this.#renderError(request, { locals, status: 404 });
186
+ return this.#renderError(request, { locals, status: 404, clientAddress });
190
187
  }
191
188
  const pathname = this.#getPathnameFromRequest(request);
192
189
  const defaultStatus = this.#getDefaultStatusCode(routeData, pathname);
@@ -199,12 +196,13 @@ class App {
199
196
  pathname,
200
197
  request,
201
198
  routeData,
202
- status: defaultStatus
199
+ status: defaultStatus,
200
+ clientAddress
203
201
  });
204
202
  response = await renderContext.render(await mod.page());
205
203
  } catch (err) {
206
204
  this.#logger.error(null, err.stack || err.message || String(err));
207
- return this.#renderError(request, { locals, status: 500, error: err });
205
+ return this.#renderError(request, { locals, status: 500, error: err, clientAddress });
208
206
  }
209
207
  if (REROUTABLE_STATUS_CODES.includes(response.status) && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") {
210
208
  return this.#renderError(request, {
@@ -213,7 +211,8 @@ class App {
213
211
  status: response.status,
214
212
  // We don't have an error to report here. Passing null means we pass nothing intentionally
215
213
  // while undefined means there's no error
216
- error: response.status === 500 ? null : void 0
214
+ error: response.status === 500 ? null : void 0,
215
+ clientAddress
217
216
  });
218
217
  }
219
218
  if (response.headers.has(REROUTE_DIRECTIVE_HEADER)) {
@@ -251,7 +250,8 @@ class App {
251
250
  status,
252
251
  response: originalResponse,
253
252
  skipMiddleware = false,
254
- error
253
+ error,
254
+ clientAddress
255
255
  }) {
256
256
  const errorRoutePath = `/${status}${this.#manifest.trailingSlash === "always" ? "/" : ""}`;
257
257
  const errorRouteData = matchRoute(errorRoutePath, this.#manifestData);
@@ -279,7 +279,8 @@ class App {
279
279
  request,
280
280
  routeData: errorRouteData,
281
281
  status,
282
- props: { error }
282
+ props: { error },
283
+ clientAddress
283
284
  });
284
285
  const response2 = await renderContext.render(await mod.page());
285
286
  return this.#mergeResponses(response2, originalResponse);
@@ -289,7 +290,8 @@ class App {
289
290
  locals,
290
291
  status,
291
292
  response: originalResponse,
292
- skipMiddleware: true
293
+ skipMiddleware: true,
294
+ clientAddress
293
295
  });
294
296
  }
295
297
  }
@@ -314,6 +316,14 @@ class App {
314
316
  originalResponse.headers.delete("Content-type");
315
317
  } catch {
316
318
  }
319
+ const mergedHeaders = new Map([
320
+ ...Array.from(newResponse.headers),
321
+ ...Array.from(originalResponse.headers)
322
+ ]);
323
+ const newHeaders = new Headers();
324
+ for (const [name, value] of mergedHeaders) {
325
+ newHeaders.set(name, value);
326
+ }
317
327
  return new Response(newResponse.body, {
318
328
  status,
319
329
  statusText: status === 200 ? newResponse.statusText : originalResponse.statusText,
@@ -322,10 +332,7 @@ class App {
322
332
  // If users see something weird, it's because they are setting some headers they should not.
323
333
  //
324
334
  // Although, we don't want it to replace the content-type, because the error page must return `text/html`
325
- headers: new Headers([
326
- ...Array.from(newResponse.headers),
327
- ...Array.from(originalResponse.headers)
328
- ])
335
+ headers: newHeaders
329
336
  });
330
337
  }
331
338
  #getDefaultStatusCode(routeData, pathname) {
@@ -295,13 +295,15 @@ async function generatePath(pathname, pipeline, gopts, route) {
295
295
  url,
296
296
  headers: new Headers(),
297
297
  logger,
298
- isPrerendered: true
298
+ isPrerendered: true,
299
+ routePattern: route.component
299
300
  });
300
301
  const renderContext = await RenderContext.create({
301
302
  pipeline,
302
303
  pathname,
303
304
  request,
304
- routeData: route
305
+ routeData: route,
306
+ clientAddress: void 0
305
307
  });
306
308
  let body;
307
309
  let response;
@@ -144,12 +144,12 @@ class AstroBuilder {
144
144
  viteConfig,
145
145
  key: keyPromise
146
146
  };
147
- const { internals, ssrOutputChunkNames, contentFileNames } = await viteBuild(opts);
147
+ const { internals, ssrOutputChunkNames, ssrOutputAssetNames, contentFileNames } = await viteBuild(opts);
148
148
  const hasServerIslands = this.settings.serverIslandNameMap.size > 0;
149
149
  if (hasServerIslands && this.settings.buildOutput !== "server") {
150
150
  throw new AstroError(AstroErrorData.NoAdapterInstalledServerIslands);
151
151
  }
152
- await staticBuild(opts, internals, ssrOutputChunkNames, contentFileNames);
152
+ await staticBuild(opts, internals, ssrOutputChunkNames, ssrOutputAssetNames, contentFileNames);
153
153
  this.timer.assetsStart = performance.now();
154
154
  Object.keys(assets).map((k) => {
155
155
  if (!assets[k]) return;
@@ -21,7 +21,7 @@ function vitePluginRenderers(opts) {
21
21
  let rendererItems = "";
22
22
  for (const renderer of opts.settings.renderers) {
23
23
  const variable = `_renderer${i}`;
24
- imports.push(`import ${variable} from '${renderer.serverEntrypoint}';`);
24
+ imports.push(`import ${variable} from ${JSON.stringify(renderer.serverEntrypoint)};`);
25
25
  rendererItems += `Object.assign(${JSON.stringify(renderer)}, { ssr: ${variable} }),`;
26
26
  i++;
27
27
  }
@@ -21,7 +21,7 @@ function vitePluginAdapter(adapter) {
21
21
  },
22
22
  async load(id) {
23
23
  if (id === RESOLVED_ADAPTER_VIRTUAL_MODULE_ID) {
24
- return `export * from '${adapter.serverEntrypoint}';`;
24
+ return `export * from ${JSON.stringify(adapter.serverEntrypoint)};`;
25
25
  }
26
26
  }
27
27
  };
@@ -4,9 +4,10 @@ import type { StaticBuildOptions } from './types.js';
4
4
  export declare function viteBuild(opts: StaticBuildOptions): Promise<{
5
5
  internals: BuildInternals;
6
6
  ssrOutputChunkNames: string[];
7
+ ssrOutputAssetNames: string[];
7
8
  contentFileNames: undefined;
8
9
  }>;
9
- export declare function staticBuild(opts: StaticBuildOptions, internals: BuildInternals, ssrOutputChunkNames: string[], contentFileNames?: string[]): Promise<void>;
10
+ export declare function staticBuild(opts: StaticBuildOptions, internals: BuildInternals, ssrOutputChunkNames: string[], ssrOutputAssetNames: string[], contentFileNames?: string[]): Promise<void>;
10
11
  export declare function copyFiles(fromFolder: URL, toFolder: URL, includeDotfiles?: boolean): Promise<void[] | undefined>;
11
12
  /**
12
13
  * This function takes the virtual module name of any page entrypoint and
@@ -69,16 +69,20 @@ async function viteBuild(opts) {
69
69
  teardown();
70
70
  }
71
71
  const ssrOutputChunkNames = [];
72
+ const ssrOutputAssetNames = [];
72
73
  for (const output of ssrOutputs) {
73
74
  for (const chunk of output.output) {
74
75
  if (chunk.type === "chunk") {
75
76
  ssrOutputChunkNames.push(chunk.fileName);
76
77
  }
78
+ if (chunk.type === "asset") {
79
+ ssrOutputAssetNames.push(chunk.fileName);
80
+ }
77
81
  }
78
82
  }
79
- return { internals, ssrOutputChunkNames, contentFileNames };
83
+ return { internals, ssrOutputChunkNames, ssrOutputAssetNames, contentFileNames };
80
84
  }
81
- async function staticBuild(opts, internals, ssrOutputChunkNames, contentFileNames) {
85
+ async function staticBuild(opts, internals, ssrOutputChunkNames, ssrOutputAssetNames, contentFileNames) {
82
86
  const { settings } = opts;
83
87
  if (settings.buildOutput === "static") {
84
88
  settings.timer.start("Static generate");
@@ -89,7 +93,7 @@ async function staticBuild(opts, internals, ssrOutputChunkNames, contentFileName
89
93
  settings.timer.start("Server generate");
90
94
  await generatePages(opts, internals);
91
95
  await cleanStaticOutput(opts, internals);
92
- await ssrMoveAssets(opts);
96
+ await ssrMoveAssets(opts, ssrOutputAssetNames);
93
97
  settings.timer.end("Server generate");
94
98
  }
95
99
  }
@@ -305,27 +309,21 @@ async function copyFiles(fromFolder, toFolder, includeDotfiles = false) {
305
309
  })
306
310
  );
307
311
  }
308
- async function ssrMoveAssets(opts) {
312
+ async function ssrMoveAssets(opts, ssrOutputAssetNames) {
309
313
  opts.logger.info("build", "Rearranging server assets...");
310
314
  const serverRoot = opts.settings.buildOutput === "static" ? opts.settings.config.build.client : opts.settings.config.build.server;
311
315
  const clientRoot = opts.settings.config.build.client;
312
- const assets = opts.settings.config.build.assets;
313
- const serverAssets = new URL(`./${assets}/`, appendForwardSlash(serverRoot.toString()));
314
- const clientAssets = new URL(`./${assets}/`, appendForwardSlash(clientRoot.toString()));
315
- const files = await glob(`**/*`, {
316
- cwd: fileURLToPath(serverAssets)
317
- });
318
- if (files.length > 0) {
316
+ if (ssrOutputAssetNames.length > 0) {
319
317
  await Promise.all(
320
- files.map(async function moveAsset(filename) {
321
- const currentUrl = new URL(filename, appendForwardSlash(serverAssets.toString()));
322
- const clientUrl = new URL(filename, appendForwardSlash(clientAssets.toString()));
318
+ ssrOutputAssetNames.map(async function moveAsset(filename) {
319
+ const currentUrl = new URL(filename, appendForwardSlash(serverRoot.toString()));
320
+ const clientUrl = new URL(filename, appendForwardSlash(clientRoot.toString()));
323
321
  const dir = new URL(path.parse(clientUrl.href).dir);
324
322
  if (!fs.existsSync(dir)) await fs.promises.mkdir(dir, { recursive: true });
325
323
  return fs.promises.rename(currentUrl, clientUrl);
326
324
  })
327
325
  );
328
- removeEmptyDirs(fileURLToPath(serverAssets));
326
+ removeEmptyDirs(fileURLToPath(serverRoot));
329
327
  }
330
328
  }
331
329
  function makeAstroPageEntryPointFileName(prefix, facadeModuleId, routes) {
@@ -67,9 +67,7 @@ export declare const ASTRO_CONFIG_DEFAULTS: {
67
67
  clientPrerender: false;
68
68
  contentIntellisense: false;
69
69
  responsiveImages: false;
70
- svg: {
71
- mode: "inline";
72
- };
70
+ svg: false;
73
71
  };
74
72
  };
75
73
  export declare const AstroConfigSchema: z.ZodObject<{
@@ -664,14 +662,14 @@ export declare const AstroConfigSchema: z.ZodObject<{
664
662
  clientPrerender: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
665
663
  contentIntellisense: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
666
664
  responsiveImages: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
667
- svg: z.ZodEffects<z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodObject<{
668
- mode: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"inline">, z.ZodLiteral<"sprite">]>>>;
665
+ svg: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodOptional<z.ZodObject<{
666
+ mode: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"inline">, z.ZodLiteral<"sprite">]>>;
669
667
  }, "strip", z.ZodTypeAny, {
670
- mode: "inline" | "sprite";
668
+ mode?: "inline" | "sprite" | undefined;
671
669
  }, {
672
670
  mode?: "inline" | "sprite" | undefined;
673
- }>]>>, {
674
- mode: "inline" | "sprite";
671
+ }>>]>>>, {
672
+ mode?: "inline" | "sprite" | undefined;
675
673
  } | undefined, boolean | {
676
674
  mode?: "inline" | "sprite" | undefined;
677
675
  } | undefined>;
@@ -680,7 +678,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
680
678
  contentIntellisense: boolean;
681
679
  responsiveImages: boolean;
682
680
  svg?: {
683
- mode: "inline" | "sprite";
681
+ mode?: "inline" | "sprite" | undefined;
684
682
  } | undefined;
685
683
  }, {
686
684
  clientPrerender?: boolean | undefined;
@@ -829,7 +827,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
829
827
  contentIntellisense: boolean;
830
828
  responsiveImages: boolean;
831
829
  svg?: {
832
- mode: "inline" | "sprite";
830
+ mode?: "inline" | "sprite" | undefined;
833
831
  } | undefined;
834
832
  };
835
833
  legacy: {
@@ -1605,14 +1603,14 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
1605
1603
  clientPrerender: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
1606
1604
  contentIntellisense: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
1607
1605
  responsiveImages: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
1608
- svg: z.ZodEffects<z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodObject<{
1609
- mode: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"inline">, z.ZodLiteral<"sprite">]>>>;
1606
+ svg: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodOptional<z.ZodObject<{
1607
+ mode: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"inline">, z.ZodLiteral<"sprite">]>>;
1610
1608
  }, "strip", z.ZodTypeAny, {
1611
- mode: "inline" | "sprite";
1609
+ mode?: "inline" | "sprite" | undefined;
1612
1610
  }, {
1613
1611
  mode?: "inline" | "sprite" | undefined;
1614
- }>]>>, {
1615
- mode: "inline" | "sprite";
1612
+ }>>]>>>, {
1613
+ mode?: "inline" | "sprite" | undefined;
1616
1614
  } | undefined, boolean | {
1617
1615
  mode?: "inline" | "sprite" | undefined;
1618
1616
  } | undefined>;
@@ -1621,7 +1619,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
1621
1619
  contentIntellisense: boolean;
1622
1620
  responsiveImages: boolean;
1623
1621
  svg?: {
1624
- mode: "inline" | "sprite";
1622
+ mode?: "inline" | "sprite" | undefined;
1625
1623
  } | undefined;
1626
1624
  }, {
1627
1625
  clientPrerender?: boolean | undefined;
@@ -1848,7 +1846,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
1848
1846
  contentIntellisense: boolean;
1849
1847
  responsiveImages: boolean;
1850
1848
  svg?: {
1851
- mode: "inline" | "sprite";
1849
+ mode?: "inline" | "sprite" | undefined;
1852
1850
  } | undefined;
1853
1851
  };
1854
1852
  legacy: {
@@ -2163,7 +2161,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2163
2161
  contentIntellisense: boolean;
2164
2162
  responsiveImages: boolean;
2165
2163
  svg?: {
2166
- mode: "inline" | "sprite";
2164
+ mode?: "inline" | "sprite" | undefined;
2167
2165
  } | undefined;
2168
2166
  };
2169
2167
  legacy: {
@@ -2478,7 +2476,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2478
2476
  contentIntellisense: boolean;
2479
2477
  responsiveImages: boolean;
2480
2478
  svg?: {
2481
- mode: "inline" | "sprite";
2479
+ mode?: "inline" | "sprite" | undefined;
2482
2480
  } | undefined;
2483
2481
  };
2484
2482
  legacy: {
@@ -2793,7 +2791,7 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
2793
2791
  contentIntellisense: boolean;
2794
2792
  responsiveImages: boolean;
2795
2793
  svg?: {
2796
- mode: "inline" | "sprite";
2794
+ mode?: "inline" | "sprite" | undefined;
2797
2795
  } | undefined;
2798
2796
  };
2799
2797
  legacy: {
@@ -54,9 +54,7 @@ const ASTRO_CONFIG_DEFAULTS = {
54
54
  clientPrerender: false,
55
55
  contentIntellisense: false,
56
56
  responsiveImages: false,
57
- svg: {
58
- mode: "inline"
59
- }
57
+ svg: false
60
58
  }
61
59
  };
62
60
  const AstroConfigSchema = z.object({
@@ -339,18 +337,26 @@ const AstroConfigSchema = z.object({
339
337
  svg: z.union([
340
338
  z.boolean(),
341
339
  z.object({
342
- mode: z.union([z.literal("inline"), z.literal("sprite")]).optional().default(ASTRO_CONFIG_DEFAULTS.experimental.svg.mode)
343
- })
344
- ]).optional().transform((svgConfig) => {
340
+ mode: z.union([z.literal("inline"), z.literal("sprite")]).optional()
341
+ }).optional()
342
+ ]).optional().default(ASTRO_CONFIG_DEFAULTS.experimental.svg).transform((svgConfig) => {
345
343
  if (typeof svgConfig === "boolean") {
346
- return svgConfig ? ASTRO_CONFIG_DEFAULTS.experimental.svg : void 0;
344
+ return svgConfig ? {
345
+ mode: "inline"
346
+ } : void 0;
347
+ } else {
348
+ if (!svgConfig.mode) {
349
+ return {
350
+ mode: "inline"
351
+ };
352
+ }
347
353
  }
348
354
  return svgConfig;
349
355
  })
350
356
  }).strict(
351
357
  `Invalid or outdated experimental feature.
352
358
  Check for incorrect spelling or outdated Astro version.
353
- See https://docs.astro.build/en/reference/configuration-reference/#experimental-flags for a list of all current experiments.`
359
+ See https://docs.astro.build/en/reference/experimental-flags/ for a list of all current experiments.`
354
360
  ).default({}),
355
361
  legacy: z.object({
356
362
  collections: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.legacy.collections)
@@ -1,7 +1,8 @@
1
+ import { errorMap } from "../errors/index.js";
1
2
  import { createRelativeSchema } from "./schema.js";
2
3
  async function validateConfig(userConfig, root, cmd) {
3
4
  const AstroConfigRelativeSchema = createRelativeSchema(cmd, root);
4
- return await AstroConfigRelativeSchema.parseAsync(userConfig);
5
+ return await AstroConfigRelativeSchema.parseAsync(userConfig, { errorMap });
5
6
  }
6
7
  export {
7
8
  validateConfig