UNPKG

astro

Version:

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

81 lines (80 loc) 2.48 kB
import { z } from "zod"; const StringSchema = z.object({ type: z.literal("string"), optional: z.boolean().optional(), default: z.string().optional(), max: z.number().optional(), min: z.number().min(0).optional(), length: z.number().optional(), url: z.boolean().optional(), includes: z.string().optional(), startsWith: z.string().optional(), endsWith: z.string().optional() }); const NumberSchema = z.object({ type: z.literal("number"), optional: z.boolean().optional(), default: z.number().optional(), gt: z.number().optional(), min: z.number().optional(), lt: z.number().optional(), max: z.number().optional(), int: z.boolean().optional() }); const BooleanSchema = z.object({ type: z.literal("boolean"), optional: z.boolean().optional(), default: z.boolean().optional() }); const EnumSchema = z.object({ type: z.literal("enum"), values: z.array( // We use "'" for codegen so it can't be passed here z.string().refine((v) => !v.includes("'"), { message: `The "'" character can't be used as an enum value` }) ), optional: z.boolean().optional(), default: z.string().optional() }); const EnvFieldType = z.union([ StringSchema, NumberSchema, BooleanSchema, EnumSchema.superRefine((schema, ctx) => { if (schema.default) { if (!schema.values.includes(schema.default)) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `The default value "${schema.default}" must be one of the specified values: ${schema.values.join(", ")}.` }); } } }) ]); const PublicClientEnvFieldMetadata = z.object({ context: z.literal("client"), access: z.literal("public") }); const PublicServerEnvFieldMetadata = z.object({ context: z.literal("server"), access: z.literal("public") }); const SecretServerEnvFieldMetadata = z.object({ context: z.literal("server"), access: z.literal("secret") }); const EnvFieldMetadata = z.union([ PublicClientEnvFieldMetadata, PublicServerEnvFieldMetadata, SecretServerEnvFieldMetadata ]); const EnvSchemaKey = z.string().min(1).refine(([firstChar]) => isNaN(Number.parseInt(firstChar)), { message: "A valid variable name cannot start with a number." }).refine((str) => /^[A-Z0-9_]+$/.test(str), { message: "A valid variable name can only contain uppercase letters, numbers and underscores." }); const EnvSchema = z.record(EnvSchemaKey, z.intersection(EnvFieldMetadata, EnvFieldType)); export { EnvSchema };