astro 5.5.5 → 5.6.0

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 (43) hide show
  1. package/client.d.ts +1 -16
  2. package/dist/actions/runtime/utils.d.ts +8 -2
  3. package/dist/assets/runtime.js +5 -29
  4. package/dist/assets/utils/svg.d.ts +1 -4
  5. package/dist/assets/utils/svg.js +2 -2
  6. package/dist/assets/vite-plugin-assets.js +1 -3
  7. package/dist/cli/add/index.js +1 -1
  8. package/dist/container/index.js +1 -1
  9. package/dist/content/content-layer.js +3 -3
  10. package/dist/core/app/index.d.ts +15 -0
  11. package/dist/core/app/index.js +27 -7
  12. package/dist/core/build/index.js +2 -2
  13. package/dist/core/config/index.d.ts +1 -1
  14. package/dist/core/config/schemas/base.d.ts +1110 -0
  15. package/dist/core/config/{schema.js → schemas/base.js} +8 -254
  16. package/dist/core/config/schemas/index.d.ts +3 -0
  17. package/dist/core/config/schemas/index.js +9 -0
  18. package/dist/core/config/schemas/refined.d.ts +3 -0
  19. package/dist/core/config/schemas/refined.js +148 -0
  20. package/dist/core/config/schemas/relative.d.ts +1462 -0
  21. package/dist/core/config/schemas/relative.js +93 -0
  22. package/dist/core/config/validate.d.ts +6 -0
  23. package/dist/core/config/validate.js +9 -3
  24. package/dist/core/constants.js +1 -1
  25. package/dist/core/dev/dev.js +1 -1
  26. package/dist/core/errors/errors-data.d.ts +1 -1
  27. package/dist/core/errors/errors-data.js +1 -1
  28. package/dist/core/messages.js +2 -2
  29. package/dist/core/render-context.js +5 -2
  30. package/dist/core/session.d.ts +8 -0
  31. package/dist/core/session.js +13 -0
  32. package/dist/events/session.js +1 -1
  33. package/dist/i18n/index.d.ts +1 -0
  34. package/dist/i18n/index.js +12 -0
  35. package/dist/i18n/utils.js +7 -11
  36. package/dist/integrations/hooks.d.ts +4 -4
  37. package/dist/integrations/hooks.js +273 -280
  38. package/dist/prefetch/index.d.ts +8 -0
  39. package/dist/prefetch/index.js +6 -4
  40. package/dist/types/public/config.d.ts +3 -25
  41. package/dist/types/public/context.d.ts +1 -1
  42. package/package.json +11 -11
  43. package/dist/core/config/schema.d.ts +0 -3402
@@ -1,10 +1,7 @@
1
- import path from "node:path";
2
- import { fileURLToPath, pathToFileURL } from "node:url";
3
1
  import { markdownConfigDefaults, syntaxHighlightDefaults } from "@astrojs/markdown-remark";
4
2
  import { bundledThemes } from "shiki";
5
3
  import { z } from "zod";
6
- import { EnvSchema } from "../../env/schema.js";
7
- import { appendForwardSlash, prependForwardSlash, removeTrailingForwardSlash } from "../path.js";
4
+ import { EnvSchema } from "../../../env/schema.js";
8
5
  const ASTRO_CONFIG_DEFAULTS = {
9
6
  root: ".",
10
7
  srcDir: "./src",
@@ -88,19 +85,7 @@ const AstroConfigSchema = z.object({
88
85
  client: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.client).transform((val) => new URL(val)),
89
86
  server: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.server).transform((val) => new URL(val)),
90
87
  assets: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.assets),
91
- assetsPrefix: z.string().optional().or(z.object({ fallback: z.string() }).and(z.record(z.string())).optional()).refine(
92
- (value) => {
93
- if (value && typeof value !== "string") {
94
- if (!value.fallback) {
95
- return false;
96
- }
97
- }
98
- return true;
99
- },
100
- {
101
- message: "The `fallback` is mandatory when defining the option as an object."
102
- }
103
- ),
88
+ assetsPrefix: z.string().optional().or(z.object({ fallback: z.string() }).and(z.record(z.string())).optional()),
104
89
  serverEntry: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.serverEntry),
105
90
  redirects: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.build.redirects),
106
91
  inlineStylesheets: z.enum(["always", "auto", "never"]).optional().default(ASTRO_CONFIG_DEFAULTS.build.inlineStylesheets),
@@ -158,16 +143,9 @@ const AstroConfigSchema = z.object({
158
143
  remotePatterns: z.array(
159
144
  z.object({
160
145
  protocol: z.string().optional(),
161
- hostname: z.string().refine(
162
- (val) => !val.includes("*") || val.startsWith("*.") || val.startsWith("**."),
163
- {
164
- message: "wildcards can only be placed at the beginning of the hostname"
165
- }
166
- ).optional(),
146
+ hostname: z.string().optional(),
167
147
  port: z.string().optional(),
168
- pathname: z.string().refine((val) => !val.includes("*") || val.endsWith("/*") || val.endsWith("/**"), {
169
- message: "wildcards can only be placed at the end of a pathname"
170
- }).optional()
148
+ pathname: z.string().optional()
171
149
  })
172
150
  ).default([]),
173
151
  experimentalLayout: z.enum(["responsive", "fixed", "full-width", "none"]).optional(),
@@ -251,92 +229,9 @@ const AstroConfigSchema = z.object({
251
229
  prefixDefaultLocale: z.boolean().optional().default(false),
252
230
  redirectToDefaultLocale: z.boolean().optional().default(true),
253
231
  fallbackType: z.enum(["redirect", "rewrite"]).optional().default("redirect")
254
- }).refine(
255
- ({ prefixDefaultLocale, redirectToDefaultLocale }) => {
256
- return !(prefixDefaultLocale === false && redirectToDefaultLocale === false);
257
- },
258
- {
259
- message: "The option `i18n.redirectToDefaultLocale` is only useful when the `i18n.prefixDefaultLocale` is set to `true`. Remove the option `i18n.redirectToDefaultLocale`, or change its value to `true`."
260
- }
261
- )
232
+ })
262
233
  ).optional().default({})
263
- }).optional().superRefine((i18n, ctx) => {
264
- if (i18n) {
265
- const { defaultLocale, locales: _locales, fallback, domains } = i18n;
266
- const locales = _locales.map((locale) => {
267
- if (typeof locale === "string") {
268
- return locale;
269
- } else {
270
- return locale.path;
271
- }
272
- });
273
- if (!locales.includes(defaultLocale)) {
274
- ctx.addIssue({
275
- code: z.ZodIssueCode.custom,
276
- message: `The default locale \`${defaultLocale}\` is not present in the \`i18n.locales\` array.`
277
- });
278
- }
279
- if (fallback) {
280
- for (const [fallbackFrom, fallbackTo] of Object.entries(fallback)) {
281
- if (!locales.includes(fallbackFrom)) {
282
- ctx.addIssue({
283
- code: z.ZodIssueCode.custom,
284
- message: `The locale \`${fallbackFrom}\` key in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`
285
- });
286
- }
287
- if (fallbackFrom === defaultLocale) {
288
- ctx.addIssue({
289
- code: z.ZodIssueCode.custom,
290
- message: `You can't use the default locale as a key. The default locale can only be used as value.`
291
- });
292
- }
293
- if (!locales.includes(fallbackTo)) {
294
- ctx.addIssue({
295
- code: z.ZodIssueCode.custom,
296
- message: `The locale \`${fallbackTo}\` value in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`
297
- });
298
- }
299
- }
300
- }
301
- if (domains) {
302
- const entries = Object.entries(domains);
303
- const hasDomains = domains ? Object.keys(domains).length > 0 : false;
304
- if (entries.length > 0 && !hasDomains) {
305
- ctx.addIssue({
306
- code: z.ZodIssueCode.custom,
307
- message: `When specifying some domains, the property \`i18n.routingStrategy\` must be set to \`"domains"\`.`
308
- });
309
- }
310
- for (const [domainKey, domainValue] of entries) {
311
- if (!locales.includes(domainKey)) {
312
- ctx.addIssue({
313
- code: z.ZodIssueCode.custom,
314
- message: `The locale \`${domainKey}\` key in the \`i18n.domains\` record doesn't exist in the \`i18n.locales\` array.`
315
- });
316
- }
317
- if (!domainValue.startsWith("https") && !domainValue.startsWith("http")) {
318
- ctx.addIssue({
319
- code: z.ZodIssueCode.custom,
320
- message: "The domain value must be a valid URL, and it has to start with 'https' or 'http'.",
321
- path: ["domains"]
322
- });
323
- } else {
324
- try {
325
- const domainUrl = new URL(domainValue);
326
- if (domainUrl.pathname !== "/") {
327
- ctx.addIssue({
328
- code: z.ZodIssueCode.custom,
329
- message: `The URL \`${domainValue}\` must contain only the origin. A subsequent pathname isn't allowed here. Remove \`${domainUrl.pathname}\`.`,
330
- path: ["domains"]
331
- });
332
- }
333
- } catch {
334
- }
335
- }
336
- }
337
- }
338
- }
339
- })
234
+ }).optional()
340
235
  ),
341
236
  security: z.object({
342
237
  checkOrigin: z.boolean().default(ASTRO_CONFIG_DEFAULTS.security.checkOrigin)
@@ -368,25 +263,7 @@ const AstroConfigSchema = z.object({
368
263
  contentIntellisense: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.contentIntellisense),
369
264
  responsiveImages: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.responsiveImages),
370
265
  session: z.boolean().optional(),
371
- svg: z.union([
372
- z.boolean(),
373
- z.object({
374
- mode: z.union([z.literal("inline"), z.literal("sprite")]).optional()
375
- }).optional()
376
- ]).optional().default(ASTRO_CONFIG_DEFAULTS.experimental.svg).transform((svgConfig) => {
377
- if (typeof svgConfig === "boolean") {
378
- return svgConfig ? {
379
- mode: "inline"
380
- } : void 0;
381
- } else {
382
- if (!svgConfig.mode) {
383
- return {
384
- mode: "inline"
385
- };
386
- }
387
- }
388
- return svgConfig;
389
- }),
266
+ svg: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.svg),
390
267
  serializeConfig: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.serializeConfig),
391
268
  headingIdCompat: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.headingIdCompat),
392
269
  preserveScriptOrder: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.preserveScriptOrder)
@@ -399,130 +276,7 @@ See https://docs.astro.build/en/reference/experimental-flags/ for a list of all
399
276
  collections: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.legacy.collections)
400
277
  }).default({})
401
278
  });
402
- function createRelativeSchema(cmd, fileProtocolRoot) {
403
- let originalBuildClient;
404
- let originalBuildServer;
405
- const AstroConfigRelativeSchema = AstroConfigSchema.extend({
406
- root: z.string().default(ASTRO_CONFIG_DEFAULTS.root).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
407
- srcDir: z.string().default(ASTRO_CONFIG_DEFAULTS.srcDir).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
408
- compressHTML: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.compressHTML),
409
- publicDir: z.string().default(ASTRO_CONFIG_DEFAULTS.publicDir).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
410
- outDir: z.string().default(ASTRO_CONFIG_DEFAULTS.outDir).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
411
- cacheDir: z.string().default(ASTRO_CONFIG_DEFAULTS.cacheDir).transform((val) => resolveDirAsUrl(val, fileProtocolRoot)),
412
- build: z.object({
413
- format: z.union([z.literal("file"), z.literal("directory"), z.literal("preserve")]).optional().default(ASTRO_CONFIG_DEFAULTS.build.format),
414
- // NOTE: `client` and `server` are transformed relative to the default outDir first,
415
- // later we'll fix this to be relative to the actual `outDir`
416
- client: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.client).transform((val) => {
417
- originalBuildClient = val;
418
- return resolveDirAsUrl(
419
- val,
420
- path.resolve(fileProtocolRoot, ASTRO_CONFIG_DEFAULTS.outDir)
421
- );
422
- }),
423
- server: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.server).transform((val) => {
424
- originalBuildServer = val;
425
- return resolveDirAsUrl(
426
- val,
427
- path.resolve(fileProtocolRoot, ASTRO_CONFIG_DEFAULTS.outDir)
428
- );
429
- }),
430
- assets: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.assets),
431
- assetsPrefix: z.string().optional().or(z.object({ fallback: z.string() }).and(z.record(z.string())).optional()).refine(
432
- (value) => {
433
- if (value && typeof value !== "string") {
434
- if (!value.fallback) {
435
- return false;
436
- }
437
- }
438
- return true;
439
- },
440
- {
441
- message: "The `fallback` is mandatory when defining the option as an object."
442
- }
443
- ),
444
- serverEntry: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.serverEntry),
445
- redirects: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.build.redirects),
446
- inlineStylesheets: z.enum(["always", "auto", "never"]).optional().default(ASTRO_CONFIG_DEFAULTS.build.inlineStylesheets),
447
- concurrency: z.number().min(1).optional().default(ASTRO_CONFIG_DEFAULTS.build.concurrency)
448
- }).optional().default({}),
449
- server: z.preprocess(
450
- // preprocess
451
- (val) => {
452
- if (typeof val === "function") {
453
- return val({ command: cmd === "dev" ? "dev" : "preview" });
454
- } else {
455
- return val;
456
- }
457
- },
458
- // validate
459
- z.object({
460
- open: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.open),
461
- host: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.host),
462
- port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port),
463
- headers: z.custom().optional(),
464
- streaming: z.boolean().optional().default(true),
465
- allowedHosts: z.union([z.array(z.string()), z.literal(true)]).optional().default(ASTRO_CONFIG_DEFAULTS.server.allowedHosts)
466
- }).optional().default({})
467
- )
468
- }).transform((config) => {
469
- if (config.outDir.toString() !== resolveDirAsUrl(ASTRO_CONFIG_DEFAULTS.outDir, fileProtocolRoot).toString()) {
470
- const outDirPath = fileURLToPath(config.outDir);
471
- config.build.client = resolveDirAsUrl(originalBuildClient, outDirPath);
472
- config.build.server = resolveDirAsUrl(originalBuildServer, outDirPath);
473
- }
474
- if (config.trailingSlash === "never") {
475
- config.base = prependForwardSlash(removeTrailingForwardSlash(config.base));
476
- config.image.endpoint.route = prependForwardSlash(
477
- removeTrailingForwardSlash(config.image.endpoint.route)
478
- );
479
- } else if (config.trailingSlash === "always") {
480
- config.base = prependForwardSlash(appendForwardSlash(config.base));
481
- config.image.endpoint.route = prependForwardSlash(
482
- appendForwardSlash(config.image.endpoint.route)
483
- );
484
- } else {
485
- config.base = prependForwardSlash(config.base);
486
- config.image.endpoint.route = prependForwardSlash(config.image.endpoint.route);
487
- }
488
- return config;
489
- }).refine((obj) => !obj.outDir.toString().startsWith(obj.publicDir.toString()), {
490
- message: "The value of `outDir` must not point to a path within the folder set as `publicDir`, this will cause an infinite loop"
491
- }).superRefine((configuration, ctx) => {
492
- const { site, i18n, output, image, experimental } = configuration;
493
- const hasDomains = i18n?.domains ? Object.keys(i18n.domains).length > 0 : false;
494
- if (hasDomains) {
495
- if (!site) {
496
- ctx.addIssue({
497
- code: z.ZodIssueCode.custom,
498
- message: "The option `site` isn't set. When using the 'domains' strategy for `i18n`, `site` is required to create absolute URLs for locales that aren't mapped to a domain."
499
- });
500
- }
501
- if (output !== "server") {
502
- ctx.addIssue({
503
- code: z.ZodIssueCode.custom,
504
- message: 'Domain support is only available when `output` is `"server"`.'
505
- });
506
- }
507
- }
508
- if (!experimental.responsiveImages && (image.experimentalLayout || image.experimentalObjectFit || image.experimentalObjectPosition || image.experimentalBreakpoints)) {
509
- ctx.addIssue({
510
- code: z.ZodIssueCode.custom,
511
- message: "The `experimentalLayout`, `experimentalObjectFit`, `experimentalObjectPosition` and `experimentalBreakpoints` options are only available when `experimental.responsiveImages` is enabled."
512
- });
513
- }
514
- });
515
- return AstroConfigRelativeSchema;
516
- }
517
- function resolveDirAsUrl(dir, root) {
518
- let resolvedDir = path.resolve(root, dir);
519
- if (!resolvedDir.endsWith(path.sep)) {
520
- resolvedDir += path.sep;
521
- }
522
- return pathToFileURL(resolvedDir);
523
- }
524
279
  export {
525
280
  ASTRO_CONFIG_DEFAULTS,
526
- AstroConfigSchema,
527
- createRelativeSchema
281
+ AstroConfigSchema
528
282
  };
@@ -0,0 +1,3 @@
1
+ export { AstroConfigSchema, ASTRO_CONFIG_DEFAULTS, type AstroConfigType } from './base.js';
2
+ export { createRelativeSchema } from './relative.js';
3
+ export { AstroConfigRefinedSchema } from './refined.js';
@@ -0,0 +1,9 @@
1
+ import { AstroConfigSchema, ASTRO_CONFIG_DEFAULTS } from "./base.js";
2
+ import { createRelativeSchema } from "./relative.js";
3
+ import { AstroConfigRefinedSchema } from "./refined.js";
4
+ export {
5
+ ASTRO_CONFIG_DEFAULTS,
6
+ AstroConfigRefinedSchema,
7
+ AstroConfigSchema,
8
+ createRelativeSchema
9
+ };
@@ -0,0 +1,3 @@
1
+ import { z } from 'zod';
2
+ import type { AstroConfig } from '../../../types/public/config.js';
3
+ export declare const AstroConfigRefinedSchema: z.ZodEffects<z.ZodType<AstroConfig, z.ZodTypeDef, AstroConfig>, AstroConfig, AstroConfig>;
@@ -0,0 +1,148 @@
1
+ import { z } from "zod";
2
+ const AstroConfigRefinedSchema = z.custom().superRefine((config, ctx) => {
3
+ if (config.build.assetsPrefix && typeof config.build.assetsPrefix !== "string" && !config.build.assetsPrefix.fallback) {
4
+ ctx.addIssue({
5
+ code: z.ZodIssueCode.custom,
6
+ message: "The `fallback` is mandatory when defining the option as an object.",
7
+ path: ["build", "assetsPrefix"]
8
+ });
9
+ }
10
+ for (let i = 0; i < config.image.remotePatterns.length; i++) {
11
+ const { hostname, pathname } = config.image.remotePatterns[i];
12
+ if (hostname && hostname.includes("*") && !(hostname.startsWith("*.") || hostname.startsWith("**."))) {
13
+ ctx.addIssue({
14
+ code: z.ZodIssueCode.custom,
15
+ message: "wildcards can only be placed at the beginning of the hostname",
16
+ path: ["image", "remotePatterns", i, "hostname"]
17
+ });
18
+ }
19
+ if (pathname && pathname.includes("*") && !(pathname.endsWith("/*") || pathname.endsWith("/**"))) {
20
+ ctx.addIssue({
21
+ code: z.ZodIssueCode.custom,
22
+ message: "wildcards can only be placed at the end of a pathname",
23
+ path: ["image", "remotePatterns", i, "pathname"]
24
+ });
25
+ }
26
+ }
27
+ if (config.i18n && typeof config.i18n.routing !== "string" && !config.i18n.routing.redirectToDefaultLocale && !config.i18n.routing.prefixDefaultLocale) {
28
+ ctx.addIssue({
29
+ code: z.ZodIssueCode.custom,
30
+ message: "The option `i18n.routing.redirectToDefaultLocale` is only useful when the `i18n.routing.prefixDefaultLocale` is set to `true`. Remove the option `i18n.routing.redirectToDefaultLocale`, or change its value to `true`.",
31
+ path: ["i18n", "routing", "redirectToDefaultLocale"]
32
+ });
33
+ }
34
+ if (config.outDir.toString().startsWith(config.publicDir.toString())) {
35
+ ctx.addIssue({
36
+ code: z.ZodIssueCode.custom,
37
+ message: "The value of `outDir` must not point to a path within the folder set as `publicDir`, this will cause an infinite loop",
38
+ path: ["outDir"]
39
+ });
40
+ }
41
+ if (config.i18n) {
42
+ const { defaultLocale, locales: _locales, fallback, domains } = config.i18n;
43
+ const locales = _locales.map((locale) => {
44
+ if (typeof locale === "string") {
45
+ return locale;
46
+ } else {
47
+ return locale.path;
48
+ }
49
+ });
50
+ if (!locales.includes(defaultLocale)) {
51
+ ctx.addIssue({
52
+ code: z.ZodIssueCode.custom,
53
+ message: `The default locale \`${defaultLocale}\` is not present in the \`i18n.locales\` array.`,
54
+ path: ["i18n", "locales"]
55
+ });
56
+ }
57
+ if (fallback) {
58
+ for (const [fallbackFrom, fallbackTo] of Object.entries(fallback)) {
59
+ if (!locales.includes(fallbackFrom)) {
60
+ ctx.addIssue({
61
+ code: z.ZodIssueCode.custom,
62
+ message: `The locale \`${fallbackFrom}\` key in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`,
63
+ path: ["i18n", "fallbacks"]
64
+ });
65
+ }
66
+ if (fallbackFrom === defaultLocale) {
67
+ ctx.addIssue({
68
+ code: z.ZodIssueCode.custom,
69
+ message: `You can't use the default locale as a key. The default locale can only be used as value.`,
70
+ path: ["i18n", "fallbacks"]
71
+ });
72
+ }
73
+ if (!locales.includes(fallbackTo)) {
74
+ ctx.addIssue({
75
+ code: z.ZodIssueCode.custom,
76
+ message: `The locale \`${fallbackTo}\` value in the \`i18n.fallback\` record doesn't exist in the \`i18n.locales\` array.`,
77
+ path: ["i18n", "fallbacks"]
78
+ });
79
+ }
80
+ }
81
+ }
82
+ if (domains) {
83
+ const entries = Object.entries(domains);
84
+ const hasDomains = domains ? Object.keys(domains).length > 0 : false;
85
+ if (entries.length > 0 && !hasDomains) {
86
+ ctx.addIssue({
87
+ code: z.ZodIssueCode.custom,
88
+ message: `When specifying some domains, the property \`i18n.routing.strategy\` must be set to \`"domains"\`.`,
89
+ path: ["i18n", "routing", "strategy"]
90
+ });
91
+ }
92
+ if (hasDomains) {
93
+ if (!config.site) {
94
+ ctx.addIssue({
95
+ code: z.ZodIssueCode.custom,
96
+ message: "The option `site` isn't set. When using the 'domains' strategy for `i18n`, `site` is required to create absolute URLs for locales that aren't mapped to a domain.",
97
+ path: ["site"]
98
+ });
99
+ }
100
+ if (config.output !== "server") {
101
+ ctx.addIssue({
102
+ code: z.ZodIssueCode.custom,
103
+ message: 'Domain support is only available when `output` is `"server"`.',
104
+ path: ["output"]
105
+ });
106
+ }
107
+ }
108
+ for (const [domainKey, domainValue] of entries) {
109
+ if (!locales.includes(domainKey)) {
110
+ ctx.addIssue({
111
+ code: z.ZodIssueCode.custom,
112
+ message: `The locale \`${domainKey}\` key in the \`i18n.domains\` record doesn't exist in the \`i18n.locales\` array.`,
113
+ path: ["i18n", "domains"]
114
+ });
115
+ }
116
+ if (!domainValue.startsWith("https") && !domainValue.startsWith("http")) {
117
+ ctx.addIssue({
118
+ code: z.ZodIssueCode.custom,
119
+ message: "The domain value must be a valid URL, and it has to start with 'https' or 'http'.",
120
+ path: ["i18n", "domains"]
121
+ });
122
+ } else {
123
+ try {
124
+ const domainUrl = new URL(domainValue);
125
+ if (domainUrl.pathname !== "/") {
126
+ ctx.addIssue({
127
+ code: z.ZodIssueCode.custom,
128
+ message: `The URL \`${domainValue}\` must contain only the origin. A subsequent pathname isn't allowed here. Remove \`${domainUrl.pathname}\`.`,
129
+ path: ["i18n", "domains"]
130
+ });
131
+ }
132
+ } catch {
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
138
+ if (!config.experimental.responsiveImages && (config.image.experimentalLayout || config.image.experimentalObjectFit || config.image.experimentalObjectPosition || config.image.experimentalBreakpoints)) {
139
+ ctx.addIssue({
140
+ code: z.ZodIssueCode.custom,
141
+ message: "The `experimentalLayout`, `experimentalObjectFit`, `experimentalObjectPosition` and `experimentalBreakpoints` options are only available when `experimental.responsiveImages` is enabled.",
142
+ path: ["experimental", "responsiveImages"]
143
+ });
144
+ }
145
+ });
146
+ export {
147
+ AstroConfigRefinedSchema
148
+ };