Parsing : Add array support, refactor env reading and default/missing management

This commit is contained in:
2025-09-12 09:49:30 +02:00
parent 2d6f8f6730
commit 7762154d32
+33 -26
View File
@@ -18,19 +18,38 @@ export async function object<S extends yup.Maybe<yup.AnyObject>>(
for (const key in schema.fields) {
const sub_key = base_name + key.toUpperCase()
const sub_scheme = schema.fields[key] as yup.AnySchema
let value: Ok<unknown>
const type = sub_scheme.describe().type
if (type === 'object') {
value = await object(sub_scheme as yup.ObjectSchema<yup.Maybe<yup.AnyObject>>, sub_key)
} else {
value = await generic(sub_scheme, sub_key)
}
log.debug(`Parse ${sub_key} with type ${type}`)
if (!value.ok) return value
if (value.data === undefined) continue
// If it is an object, do not try to read from env
let value: Ok<S>
if (type === 'object') {
value = await object(sub_scheme as yup.ObjectSchema<S>, sub_key)
if (!value.ok) return value
} else {
// For all other types, read value from env
const raw = await read_env(sub_key)
if (!raw.ok) return raw
// if undef : might have a default, might be opt, might be missing
if (raw.data === undefined) {
const def = sub_scheme.getDefault()
if (def !== undefined) value = {ok: true, data: def}
else if (sub_scheme.spec.optional) continue
else {
log.warn('Missing value for', key)
return {}
}
} else {
// Normal handling of value (for arrays, split by ',')
const less_raw = type === 'array' ? (raw.data.length === 0 ? [] : raw.data.split(',')) : raw.data
value = await generic(less_raw, sub_scheme)
if (!value.ok) return value
}
}
data[key] = value.data
}
@@ -38,28 +57,16 @@ export async function object<S extends yup.Maybe<yup.AnyObject>>(
return {ok: true, data}
}
export async function generic<S>(scheme: yup.AnySchema<S>, key: string): Promise<Ok<S | undefined>> {
export async function generic<S>(value: string | string[], scheme: yup.AnySchema<S>): Promise<Ok<S>> {
log.debug('Generic', scheme.describe().type)
const value = await read_env(key)
if (!value.ok) return value
if (value.data === undefined) {
const def = scheme.getDefault()
if (def !== undefined) return {ok: true, data: def}
else if (scheme.spec.optional) return {ok: true, data: undefined}
log.warn('Missing value for', key)
if (!(await scheme.isValid(value))) {
log.warn('Invalid value')
log.debug('Value:', value)
return {}
}
if (!(await scheme.isValid(value.data))) {
log.warn('Invaid value for', key)
log.debug('Value:', value.data)
return {}
}
const res = scheme.cast(value.data)
const res = scheme.cast(value)
return {ok: true, data: res}
}