export class Utils { constructor(options){ } isValidIsoTimestamp(val) { const isoTimestampRegex = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]|60)(\.\d+)?(Z|([+-])(0[0-9]|1[0-3]):([0-5][0-9])|(14):00)?$/ return(isoTimestampRegex.test(val)) } isValidMail(val) { const mailRFC5322Regex = /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/ return(mailRFC5322Regex.test(val)) } isValidUUIDV4(val) { const uuidV4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i return(uuidV4Regex.test(val)) } isValidUUIDV7(val) { const uuidV7Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i return(uuidV7Regex.test(val)) } isIterable(obj) { if (obj == null) { return false; } return typeof obj[Symbol.iterator] === "function"; } FilterMapArray(rows, condition) { if(!rows || (typeof(rows[Symbol.iterator]) != 'function')) return([]) let filteredRows = [] for(let row of rows) { if(condition(row)) filteredRows.push(row) } return(filteredRows) } CheckMapArray(rows, remap, transformers) { if(!rows || (typeof(rows[Symbol.iterator]) != 'function')) return([]) let filteredRows = [] for(let row of rows) { filteredRows.push(this.CheckMapObject(row, remap, transformers)) } return(filteredRows) } CheckMapObject(row, remap, transformers) { let filteredRow = {} let tempTransformers = { ...transformers } for(let key of Object.keys(row)){ if(Object.keys(remap).indexOf(key)>-1) { if(tempTransformers && tempTransformers[key] && (typeof(tempTransformers[key])=='function')) { this.remap(filteredRow, remap[key], tempTransformers[key](row)) delete(tempTransformers[remap[key]]) } else this.remap(filteredRow, remap[key], row[key]) //filteredRow[remap[key]] = row[key] } } // now use remaining transformers for other virtual, non-original keys for(let virtkey of Object.keys(tempTransformers)){ filteredRow[virtkey] = tempTransformers[virtkey](row) } return(filteredRow) } validateMapObject(row, validators, remap){ let isok = true let badkeys = [] for(let key of Object.keys(validators)){ if(typeof(validators[key])=='function') { let result = validators[key](row[key], row) if(result!==true) { isok = false badkeys.push(key + ((typeof(result)=='string') ? ' - '+result : '') ) } } } let remappedRow = {} if(!isok) return([false, {}, badkeys]) for(let key of Object.keys(row)){ if(Object.keys(remap).indexOf(key)>-1){ this.remap(remappedRow, remap[key], row[key]) } } return([true, remappedRow, badkeys]) } validateMapArray(rows, validators, remap){ if(!rows || (typeof(rows[Symbol.iterator]) != 'function')) return([false, [], ['First parameter of validateMapArray is not an array']]) let remappedRows = [] let allErrors = [] let isOk = true for(let row of rows){ let isValid,remappedRow, errors [isValid, remappedRow, errors] = this.validateMapObject(row, validators, remap) isOk = isOk && isValid remappedRows.push(remappedRow) allErrors = allErrors.concat(errors) } return([isOk, remappedRows, allErrors]) } remap(obj, newKey, value){ let ref = obj // create sub-struct as needed newKey.split('.').slice(0,-1).forEach( (keyPart) => { if(!ref.hasOwnProperty(keyPart)) ref[keyPart]={} ref = ref[keyPart] }) ref[newKey.split('.').slice(-1)[0]] = value } }