Repository: withastro/astro
File: packages/astro/src/env/schema.ts (TypeScript)

Code before:
	}),
]);
export type EnvFieldType = z.infer<typeof EnvFieldType>;

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 EnvFieldMetadata = z.custom<z.input<typeof _EnvFieldMetadata>>().superRefine((data, ctx) => {
	const result = _EnvFieldMetadata.safeParse(data);
	if (result.success) {
		return;
	}
	for (const issue of result.error.issues) {
		if (issue.code === z.ZodIssueCode.invalid_union) {
			ctx.addIssue({
				code: z.ZodIssueCode.custom,
				message: `**Invalid combination** of "access" and "context" options:\n  Review the configuration of \`env.schema.${ctx.path.at(-1)}\`.\n  Learn more at https://docs.astro.build/en/guides/environment-variables/#variable-types`,
				path: ['context', 'access'],
			});
		} else {
			ctx.addIssue(issue);
		}
	}
});

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.',
	});

export const EnvSchema = z.record(EnvSchemaKey, z.intersection(EnvFieldMetadata, EnvFieldType));


Review comment (suggestion):
~~Can you explain to me where we check the **values** of `access` and `context`? I can't see it in the code, it's probably somewhere~~

I checked the source code, I am up to speed. To be honest, I would move the refine inside `PublicClientEnvFieldMetadata`, etc. instead, because it allow us to actually provide a good error message. 

Code after:
	}),
]);
export type EnvFieldType = z.infer<typeof EnvFieldType>;

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 EnvFieldMetadata = z.custom<z.input<typeof _EnvFieldMetadata>>().superRefine((data, ctx) => {
	const result = _EnvFieldMetadata.safeParse(data);
	if (result.success) {
		return;
	}
	for (const issue of result.error.issues) {
		if (issue.code === z.ZodIssueCode.invalid_union) {
			ctx.addIssue({
				code: z.ZodIssueCode.custom,
				message: `**Invalid combination** of "access" and "context" options:\n  Secret client variables are not supported. Please review the configuration of \`env.schema.${ctx.path.at(-1)}\`.\n  Learn more at https://docs.astro.build/en/guides/environment-variables/#variable-types`,
				path: ['context', 'access'],
			});
		} else {
			ctx.addIssue(issue);
		}
	}
});

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.',
	});

export const EnvSchema = z.record(EnvSchemaKey, z.intersection(EnvFieldMetadata, EnvFieldType));