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
JavaScript
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
};