@withstudiocms/config-utils
Version:
Utilities for managing configuration files
58 lines (57 loc) • 2.03 kB
JavaScript
import { z } from "astro/zod";
import { deepmerge } from "deepmerge-ts";
function parseConfig(schema, opts) {
try {
return schema.parse(opts);
} catch (error) {
if (error instanceof Error) {
throw new Error(`Invalid Configuration Options: ${error.message}`);
}
throw new Error("An unknown error occurred while parsing the configuration options.");
}
}
function deepRemoveDefaults(schema) {
if (schema instanceof z.ZodDefault) return deepRemoveDefaults(schema.removeDefault());
if (schema instanceof z.ZodObject) {
const newShape = {};
for (const key in schema.shape) {
const fieldSchema = schema.shape[key];
newShape[key] = z.ZodOptional.create(deepRemoveDefaults(fieldSchema));
}
return new z.ZodObject({
...schema._def,
shape: () => newShape
// biome-ignore lint/suspicious/noExplicitAny: This is a valid use case for explicit any.
});
}
if (schema instanceof z.ZodArray) return z.ZodArray.create(deepRemoveDefaults(schema.element));
if (schema instanceof z.ZodOptional)
return z.ZodOptional.create(deepRemoveDefaults(schema.unwrap()));
if (schema instanceof z.ZodNullable)
return z.ZodNullable.create(deepRemoveDefaults(schema.unwrap()));
if (schema instanceof z.ZodTuple)
return z.ZodTuple.create(schema.items.map((item) => deepRemoveDefaults(item)));
return schema;
}
function parseAndMerge(schema, inlineConfig, configFile) {
try {
const ZeroDefaultsSchema = deepRemoveDefaults(schema);
if (!configFile) {
return inlineConfig ?? schema.parse({});
}
const parsedConfigFile = ZeroDefaultsSchema.parse(configFile);
return deepmerge(inlineConfig ?? {}, parsedConfigFile);
} catch (error) {
if (error instanceof Error) {
throw new Error(`Invalid Config Options: ${error.message}`);
}
throw new Error(
"Invalid Config Options: An unknown error occurred while parsing the Config options."
);
}
}
export {
deepRemoveDefaults,
parseAndMerge,
parseConfig
};