import {Schema, CheckFunction, DateInstance, OptionalDate, DateArray, Field, CheckType} from "./Schema"; import {FieldSetUtil} from "./FieldSetUtil"; import {Validation} from "@anyhowstep/validation"; import {Configuration} from "./Configuration"; export class SchemaUtil { public static Fill (name : string, mixed : any, schema : Schema) : Promise { if (Configuration.DebugSchema) { console.log("SchemaUtil", "Fill", name, mixed, schema, new Error("Debug stack")); } if (mixed == null) { return Promise.reject(new Error(`${name} is null or undefined, and cannot be filled`)); } if (!(mixed instanceof Object)) { return Promise.reject(new Error(`${name} is is not an object, and cannot be filled`)); } for (let fieldName in schema.fields) { if (!mixed.hasOwnProperty(fieldName) || mixed[fieldName] == null) { const check : Field = schema.fields[fieldName]; if (FieldSetUtil.IsCheckObject(check)) { const defaultValue = check.default; if (defaultValue instanceof Function) { mixed[fieldName] = defaultValue(); } else { mixed[fieldName] = defaultValue; } } } } const arr : Promise[] = []; for (let fieldName in schema.fields) { //Commenting this out, we don't want to add keys that don't exist /*if (!mixed.hasOwnProperty(fieldName) || mixed[fieldName] == null) { mixed[fieldName] = undefined; }*/ const field : Field = schema.fields[fieldName]; const check = FieldSetUtil.GetCheck(field); const value = mixed[fieldName]; if (FieldSetUtil.IsSchema(check)) { arr.push(SchemaUtil.Fill(`${name}.${fieldName}`, value, check)); //Treat dates special, try to convert to Date, if string|number } else if (check as any == DateInstance || check as any == OptionalDate) { if (typeof value == "string" || typeof value == "number") { if (!isNaN(new Date(value).getTime())) { mixed[fieldName] = new Date(value); } } } else if (check as any == DateArray) { if (value instanceof Array) { for (let i=0; i { return FieldSetUtil.HasValidField(name, mixed, schema); }); } public static GetArrayCheck (schema : Schema) : CheckFunction { return (name, mixed) => { return Validation.IsArray(name, mixed) .then((arr) => { const p : Promise[] = []; for (let i=0; i { return mixed as T[]; }); } } public static GetArrayCheckValidate (validate : CheckFunction) : CheckFunction { return (name, mixed) => { return Validation.IsArray(name, mixed) .then((arr) => { const p : Promise[] = []; for (let i=0; i { return mixed as T[]; }); } } public static GetOptionalCheck (schema : Schema) : CheckFunction { return (name, mixed) => { return Validation.IsOptional(name, mixed, (name, mixed) => { return SchemaUtil.Fill(name, mixed, schema); }); }; } public static FillArray (name : string, mixed : any, schema : Schema) { return SchemaUtil.GetArrayCheck(schema)(name, mixed); } public static Copy (schema : Schema) : Schema { return { allowExtraFields: schema.allowExtraFields, check: schema.check, fields: Object.assign({}, schema.fields) }; } public static ToPartial (src : Schema) : Schema> { const result : Schema> = SchemaUtil.Copy(src); for (let k in src.fields) { const check : CheckType = FieldSetUtil.GetCheck(src.fields[k]); const field : Field = Validation.IsOptionalHandler((name, mixed) => { return FieldSetUtil.Check(name, mixed, check); }); result.fields[k] = field; } return result; } }