utils/validationFunctions.jsjavascript
/*
Generic parser/validator for config values coming from either .env variables
or URL search params. Both sources only ever give us strings (or null/undefined
if unset), so this function's job is to turn that raw string into the right
type and fall back to a sane default if the value is missing or invalid.
Used by `useConfig` (src/services/config.jsx) together with the CONFIG_SCHEMA
list - one `parseConfigValue` call per schema entry, instead of a dedicated
validate*() function per config variable like we used to have.
*/
/**
* Parses and validates a single raw config value against its schema definition.
*
* @param {string|null|undefined} rawValue - The raw value as read from
* `searchParams.get(...)` or `import.meta.env[...]`. Always a string when set.
* @param {Object} definition - The matching entry from CONFIG_SCHEMA.
* @param {"boolean"|"number"|"string"} definition.type - How to interpret rawValue.
* @param {*} definition.default - Value to use when rawValue is missing/invalid.
* @param {number} [definition.min] - Only for type "number": reject values below this.
* @param {number} [definition.max] - Only for type "number": reject values above this.
* @param {string} definition.key - Config key name, used only for warning messages.
* @returns {*} The parsed value, or `definition.default` if rawValue was empty
* or failed validation.
*/
export const parseConfigValue = (rawValue, { type, default: defaultValue, min, max, key }) => {
// No value was provided at all (param/env var not set) - just use the default.
if (rawValue === null || rawValue === undefined || rawValue === "") {
return defaultValue;
}
switch (type) {
// Env vars and URL params are strings, so "true"/"false" is the only sane
// boolean representation - anything else (typos, "1", etc.) counts as false.
case "boolean":
return rawValue === "true";
case "number": {
const parsed = parseInt(rawValue, 10);
if (isNaN(parsed)) {
// eslint-disable-next-line no-console
console.warn(`${key}: "${rawValue}" is not a number, using default (${defaultValue}).`);
return defaultValue;
}
if (min !== undefined && parsed < min) {
// eslint-disable-next-line no-console
console.warn(
`${key}: ${parsed} is below minimum (${min}), using default (${defaultValue}).`
);
return defaultValue;
}
if (max !== undefined && parsed > max) {
// eslint-disable-next-line no-console
console.warn(
`${key}: ${parsed} exceeds maximum (${max}), using default (${defaultValue}).`
);
return defaultValue;
}
return parsed;
}
// Strings need no further parsing - pass them through as-is.
case "string":
default:
return rawValue;
}
};