export namespace ModelsInternals { export function hasValue(value: T | undefined | null): value is T { if (value === null) return false ; if (value === undefined) return false ; return true } export function filterValidation(value: any, validations: Model.PrimitiveValidationType[]) { for (let i = 0; i < validations.length; i++) { const validation = validations[i] if (validation.filter !== undefined) { value = validation.filter(value) } } return value } export function filterTemplate(value: any, template: Y) { for (const param in template) { const t = template[param] // Objeto => param: { ... } if (t.length === undefined) { if (!ModelsInternals.hasValue(value[param])) { value[param] = Object.create(null) } value[param] = filterTemplate(value[param], t as Model.Template) continue } // Parametro => param: [ PlataModels.Required() ] if (typeof t[0] === 'function') { if (!ModelsInternals.hasValue(value[param])) { value[param] = null continue } value[param] = ModelsInternals.filterValidation(value[param], t as Model.PrimitiveValidationType[]) continue } // Array de valores => param: [[ PlataModels.Required() ]] if (t[0].length !== undefined) { if (!ModelsInternals.hasValue(value[param])) { value[param] = [] } if (!Array.isArray(value[param])) { value[param] = [value[param]] } for (let i = 0; i < value[param].length; i++) { value[param][i] = ModelsInternals.filterValidation(value[param][i], t[0] as Model.PrimitiveValidationType[]) } continue } // Array de Objetos => param: [{ ... }] if (!ModelsInternals.hasValue(value[param])) { value[param] = [] continue } if (!Array.isArray(value[param])) { if (typeof value[param] !== 'object') { value[param] = [] continue } value[param] = [value[param]] } for (let i = 0; i < value[param].length; i++) { value[param][i] = filterTemplate(value[param][i], t[0]) } } return value as DeepWritable> } export async function validateTemplateEnv(value: Record, template: Model.TemplateEnv): PlataPromise { const promises: Promise[] = [] for (const env in template) { promises.push(Plata.FastPromise(() => validateParameter( value[env] ?? null, template[env], env ))) } return Promise.all(promises).then( result => result.filter(Boolean).flatMap(r => r) as PlataError[], err => ({ errorID: 'BPLMINVLTMEN001', msg: `unexpected error while validating template for env`, error: err }) ) } export async function validateParameter(value: any, pipeline: readonly Model.PrimitiveValidationType[], name: string): Promise { for (const validation of pipeline) { const result = await validation(name, value) if (result.error !== undefined) { return result.error } if (!result.continua) { break } } return null } export async function validateTemplate(value: any, template: Y, name?: string): PlataPromise { const promises: any[] = [] for (const param in template) { const t = template[param] if (t.length === undefined) { promises.push(Plata.FastPromise(() => validateTemplate( value[param], t as Model.Template, `${name ?? ''}${param}.` ))) continue } if (typeof t[0] === 'function') { promises.push( Plata.FastPromise(() => validateParameter( value[param], t as Model.PrimitiveValidationType[], `${name ?? ''}${param}` )) ) continue } if (t[0].length !== undefined) { for (let i = 0; i < value[param].length; i++) { promises.push( Plata.FastPromise(() => validateParameter( value[param][i], t[0], `${name ?? ''}${param}[${i}]` )) ) } continue } for (let i = 0; i < value[param].length; i++) { promises.push( Plata.FastPromise(() => validateTemplate( value[param][i], t[0], `${name ?? ''}${param}[${i}].` )) ) } } return Promise.all(promises).then( result => [].concat(...result).filter(v => v !== null), err => { return { errorID: 'BPLM0001', msg: `unexpected error while validating template (${name})`, error: err } } ) } }