UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

280 lines (279 loc) • 12.1 kB
import { markdownConfigDefaults, syntaxHighlightDefaults } from "@astrojs/markdown-remark"; import { bundledThemes } from "shiki"; import { z } from "zod"; import { localFontFamilySchema, remoteFontFamilySchema } from "../../../assets/fonts/config.js"; import { EnvSchema } from "../../../env/schema.js"; const ASTRO_CONFIG_DEFAULTS = { root: ".", srcDir: "./src", publicDir: "./public", outDir: "./dist", cacheDir: "./node_modules/.astro", base: "/", trailingSlash: "ignore", build: { format: "directory", client: "./client/", server: "./server/", assets: "_astro", serverEntry: "entry.mjs", redirects: true, inlineStylesheets: "auto", concurrency: 1 }, image: { endpoint: { entrypoint: void 0, route: "/_image" }, service: { entrypoint: "astro/assets/services/sharp", config: {} } }, devToolbar: { enabled: true }, compressHTML: true, server: { host: false, port: 4321, open: false, allowedHosts: [] }, integrations: [], markdown: markdownConfigDefaults, vite: {}, legacy: { collections: false }, redirects: {}, security: { checkOrigin: true }, env: { schema: {}, validateSecrets: false }, session: void 0, experimental: { clientPrerender: false, contentIntellisense: false, responsiveImages: false, headingIdCompat: false, preserveScriptOrder: false } }; const highlighterTypesSchema = z.union([z.literal("shiki"), z.literal("prism")]).default(syntaxHighlightDefaults.type); const AstroConfigSchema = z.object({ root: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.root).transform((val) => new URL(val)), srcDir: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.srcDir).transform((val) => new URL(val)), publicDir: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.publicDir).transform((val) => new URL(val)), outDir: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.outDir).transform((val) => new URL(val)), cacheDir: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.cacheDir).transform((val) => new URL(val)), site: z.string().url().optional(), compressHTML: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.compressHTML), base: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.base), trailingSlash: z.union([z.literal("always"), z.literal("never"), z.literal("ignore")]).optional().default(ASTRO_CONFIG_DEFAULTS.trailingSlash), output: z.union([z.literal("static"), z.literal("server")]).optional().default("static"), scopedStyleStrategy: z.union([z.literal("where"), z.literal("class"), z.literal("attribute")]).optional().default("attribute"), adapter: z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) }).optional(), integrations: z.preprocess( // preprocess (val) => Array.isArray(val) ? val.flat(Infinity).filter(Boolean) : val, // validate z.array(z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) })).default(ASTRO_CONFIG_DEFAULTS.integrations) ), build: z.object({ format: z.union([z.literal("file"), z.literal("directory"), z.literal("preserve")]).optional().default(ASTRO_CONFIG_DEFAULTS.build.format), client: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.client).transform((val) => new URL(val)), server: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.server).transform((val) => new URL(val)), assets: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.assets), assetsPrefix: z.string().optional().or(z.object({ fallback: z.string() }).and(z.record(z.string())).optional()), serverEntry: z.string().optional().default(ASTRO_CONFIG_DEFAULTS.build.serverEntry), redirects: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.build.redirects), inlineStylesheets: z.enum(["always", "auto", "never"]).optional().default(ASTRO_CONFIG_DEFAULTS.build.inlineStylesheets), concurrency: z.number().min(1).optional().default(ASTRO_CONFIG_DEFAULTS.build.concurrency) }).default({}), server: z.preprocess( // preprocess // NOTE: Uses the "error" command here because this is overwritten by the // individualized schema parser with the correct command. (val) => typeof val === "function" ? val({ command: "error" }) : val, // validate z.object({ open: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.open), host: z.union([z.string(), z.boolean()]).optional().default(ASTRO_CONFIG_DEFAULTS.server.host), port: z.number().optional().default(ASTRO_CONFIG_DEFAULTS.server.port), headers: z.custom().optional(), allowedHosts: z.union([z.array(z.string()), z.literal(true)]).optional().default(ASTRO_CONFIG_DEFAULTS.server.allowedHosts) }).default({}) ), redirects: z.record( z.string(), z.union([ z.string(), z.object({ status: z.union([ z.literal(300), z.literal(301), z.literal(302), z.literal(303), z.literal(304), z.literal(307), z.literal(308) ]), destination: z.string() }) ]) ).default(ASTRO_CONFIG_DEFAULTS.redirects), prefetch: z.union([ z.boolean(), z.object({ prefetchAll: z.boolean().optional(), defaultStrategy: z.enum(["tap", "hover", "viewport", "load"]).optional() }) ]).optional(), image: z.object({ endpoint: z.object({ route: z.literal("/_image").or(z.string()).default(ASTRO_CONFIG_DEFAULTS.image.endpoint.route), entrypoint: z.string().optional() }).default(ASTRO_CONFIG_DEFAULTS.image.endpoint), service: z.object({ entrypoint: z.union([z.literal("astro/assets/services/sharp"), z.string()]).default(ASTRO_CONFIG_DEFAULTS.image.service.entrypoint), config: z.record(z.any()).default({}) }).default(ASTRO_CONFIG_DEFAULTS.image.service), domains: z.array(z.string()).default([]), remotePatterns: z.array( z.object({ protocol: z.string().optional(), hostname: z.string().optional(), port: z.string().optional(), pathname: z.string().optional() }) ).default([]), experimentalLayout: z.enum(["constrained", "fixed", "full-width", "none"]).optional(), experimentalObjectFit: z.string().optional(), experimentalObjectPosition: z.string().optional(), experimentalBreakpoints: z.array(z.number()).optional() }).default(ASTRO_CONFIG_DEFAULTS.image), devToolbar: z.object({ enabled: z.boolean().default(ASTRO_CONFIG_DEFAULTS.devToolbar.enabled) }).default(ASTRO_CONFIG_DEFAULTS.devToolbar), markdown: z.object({ syntaxHighlight: z.union([ z.object({ type: highlighterTypesSchema, excludeLangs: z.array(z.string()).optional().default(syntaxHighlightDefaults.excludeLangs) }).default(syntaxHighlightDefaults), highlighterTypesSchema, z.literal(false) ]).default(ASTRO_CONFIG_DEFAULTS.markdown.syntaxHighlight), shikiConfig: z.object({ langs: z.custom().array().transform((langs) => { for (const lang of langs) { if (typeof lang === "object") { if (lang.id) { lang.name = lang.id; } if (lang.grammar) { Object.assign(lang, lang.grammar); } } } return langs; }).default([]), langAlias: z.record(z.string(), z.string()).optional().default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.langAlias), theme: z.enum(Object.keys(bundledThemes)).or(z.custom()).default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.theme), themes: z.record( z.enum(Object.keys(bundledThemes)).or(z.custom()) ).default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.themes), defaultColor: z.union([z.literal("light"), z.literal("dark"), z.string(), z.literal(false)]).optional(), wrap: z.boolean().or(z.null()).default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.wrap), transformers: z.custom().array().default(ASTRO_CONFIG_DEFAULTS.markdown.shikiConfig.transformers) }).default({}), remarkPlugins: z.union([ z.string(), z.tuple([z.string(), z.any()]), z.custom((data) => typeof data === "function"), z.tuple([z.custom((data) => typeof data === "function"), z.any()]) ]).array().default(ASTRO_CONFIG_DEFAULTS.markdown.remarkPlugins), rehypePlugins: z.union([ z.string(), z.tuple([z.string(), z.any()]), z.custom((data) => typeof data === "function"), z.tuple([z.custom((data) => typeof data === "function"), z.any()]) ]).array().default(ASTRO_CONFIG_DEFAULTS.markdown.rehypePlugins), remarkRehype: z.custom((data) => data instanceof Object && !Array.isArray(data)).default(ASTRO_CONFIG_DEFAULTS.markdown.remarkRehype), gfm: z.boolean().default(ASTRO_CONFIG_DEFAULTS.markdown.gfm), smartypants: z.boolean().default(ASTRO_CONFIG_DEFAULTS.markdown.smartypants) }).default({}), vite: z.custom((data) => data instanceof Object && !Array.isArray(data)).default(ASTRO_CONFIG_DEFAULTS.vite), i18n: z.optional( z.object({ defaultLocale: z.string(), locales: z.array( z.union([ z.string(), z.object({ path: z.string(), codes: z.string().array().nonempty() }) ]) ), domains: z.record( z.string(), z.string().url( "The domain value must be a valid URL, and it has to start with 'https' or 'http'." ) ).optional(), fallback: z.record(z.string(), z.string()).optional(), routing: z.literal("manual").or( z.object({ prefixDefaultLocale: z.boolean().optional().default(false), // TODO: Astro 6.0 change to false redirectToDefaultLocale: z.boolean().optional().default(true), fallbackType: z.enum(["redirect", "rewrite"]).optional().default("redirect") }) ).optional().default({}) }).optional() ), security: z.object({ checkOrigin: z.boolean().default(ASTRO_CONFIG_DEFAULTS.security.checkOrigin) }).optional().default(ASTRO_CONFIG_DEFAULTS.security), env: z.object({ schema: EnvSchema.optional().default(ASTRO_CONFIG_DEFAULTS.env.schema), validateSecrets: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.env.validateSecrets) }).strict().optional().default(ASTRO_CONFIG_DEFAULTS.env), session: z.object({ driver: z.string(), options: z.record(z.any()).optional(), cookie: z.object({ name: z.string().optional(), domain: z.string().optional(), path: z.string().optional(), maxAge: z.number().optional(), sameSite: z.union([z.enum(["strict", "lax", "none"]), z.boolean()]).optional(), secure: z.boolean().optional() }).or(z.string()).transform((val) => { if (typeof val === "string") { return { name: val }; } return val; }).optional(), ttl: z.number().optional() }).optional(), experimental: z.object({ clientPrerender: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.clientPrerender), contentIntellisense: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.contentIntellisense), responsiveImages: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.responsiveImages), headingIdCompat: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.headingIdCompat), preserveScriptOrder: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.preserveScriptOrder), fonts: z.array(z.union([localFontFamilySchema, remoteFontFamilySchema])).optional() }).strict( `Invalid or outdated experimental feature. Check for incorrect spelling or outdated Astro version. See https://docs.astro.build/en/reference/experimental-flags/ for a list of all current experiments.` ).default({}), legacy: z.object({ collections: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.legacy.collections) }).default({}) }); export { ASTRO_CONFIG_DEFAULTS, AstroConfigSchema };