UNPKG

astro

Version:

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

156 lines (154 loc) 5.71 kB
import { z } from "zod"; import { LOCAL_PROVIDER_NAME } from "./constants.js"; const weightSchema = z.union([z.string(), z.number()]); const styleSchema = z.enum(["normal", "italic", "oblique"]); const familyPropertiesSchema = z.object({ /** * A [font weight](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight). If the associated font is a [variable font](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_fonts/Variable_fonts_guide), you can specify a range of weights: * * ```js * weight: "100 900" * ``` */ weight: weightSchema, /** * A [font style](https://developer.mozilla.org/en-US/docs/Web/CSS/font-style). */ style: styleSchema, /** * @default `"swap"` * * A [font display](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display). */ display: z.enum(["auto", "block", "swap", "fallback", "optional"]).optional(), /** * A [unicode range](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/unicode-range). */ unicodeRange: z.array(z.string()).nonempty().optional(), /** * A [font stretch](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-stretch). */ stretch: z.string().optional(), /** * Font [feature settings](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-feature-settings). */ featureSettings: z.string().optional(), /** * Font [variation settings](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-variation-settings). */ variationSettings: z.string().optional() }); const fallbacksSchema = z.object({ /** * @default `["sans-serif"]` * * An array of fonts to use when your chosen font is unavailable, or loading. Fallback fonts will be chosen in the order listed. The first available font will be used: * * ```js * fallbacks: ["CustomFont", "serif"] * ``` * * To disable fallback fonts completely, configure an empty array: * * ```js * fallbacks: [] * ``` * * If the last font in the `fallbacks` array is a [generic family name](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#generic-name), Astro will attempt to generate [optimized fallbacks](https://developer.chrome.com/blog/font-fallbacks) using font metrics will be generated. To disable this optimization, set `optimizedFallbacks` to false. */ fallbacks: z.array(z.string()).optional(), /** * @default `true` * * Whether or not to enable optimized fallback generation. You may disable this default optimization to have full control over `fallbacks`. */ optimizedFallbacks: z.boolean().optional() }); const requiredFamilyAttributesSchema = z.object({ /** * The font family name, as identified by your font provider. */ name: z.string(), /** * A valid [ident](https://developer.mozilla.org/en-US/docs/Web/CSS/ident) in the form of a CSS variable (i.e. starting with `--`). */ cssVariable: z.string() }); const entrypointSchema = z.union([z.string(), z.instanceof(URL)]); const fontProviderSchema = z.object({ /** * URL, path relative to the root or package import. */ entrypoint: entrypointSchema, /** * Optional serializable object passed to the unifont provider. */ config: z.record(z.string(), z.any()).optional() }).strict(); const localFontFamilySchema = requiredFamilyAttributesSchema.merge(fallbacksSchema).merge( z.object({ /** * The source of your font files. Set to `"local"` to use local font files. */ provider: z.literal(LOCAL_PROVIDER_NAME), /** * Each variant represents a [`@font-face` declaration](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/). */ variants: z.array( familyPropertiesSchema.merge( z.object({ /** * Font [sources](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src). It can be a path relative to the root, a package import or a URL. URLs are particularly useful if you inject local fonts through an integration. */ src: z.array( z.union([ entrypointSchema, z.object({ url: entrypointSchema, tech: z.string().optional() }).strict() ]) ).nonempty() // TODO: find a way to support subsets (through fontkit?) }).strict() ) ).nonempty() }) ).strict(); const remoteFontFamilySchema = requiredFamilyAttributesSchema.merge( familyPropertiesSchema.omit({ weight: true, style: true }) ).merge(fallbacksSchema).merge( z.object({ /** * The source of your font files. You can use a built-in provider or write your own custom provider. */ provider: fontProviderSchema, /** * @default `[400]` * * An array of [font weights](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight). If the associated font is a [variable font](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_fonts/Variable_fonts_guide), you can specify a range of weights: * * ```js * weight: "100 900" * ``` */ weights: z.array(weightSchema).nonempty().optional(), /** * @default `["normal", "italic"]` * * An array of [font styles](https://developer.mozilla.org/en-US/docs/Web/CSS/font-style). */ styles: z.array(styleSchema).nonempty().optional(), /** * @default `["cyrillic-ext", "cyrillic", "greek-ext", "greek", "vietnamese", "latin-ext", "latin"]` * * An array of [font subsets](https://knaap.dev/posts/font-subsetting/): */ subsets: z.array(z.string()).nonempty().optional() }) ).strict(); export { fontProviderSchema, localFontFamilySchema, remoteFontFamilySchema };