'use strict' ; import { Entity } from '@Entities/Entity' ; import { FieldDefn , ValidateResponse } from '@Route-Tools/EntityFieldDefn' ; import { SArray } from '@Tools/vTypes' ; import { IsNotNullOrEmpty , IsNullOrEmpty } from '@Tools/Misc' ; import { Logger } from '@Tools/Logging' ; export async function noValidation ( pField , pEntity , pValue ) { return { valid : true } ; } ; export async function isStringValidator ( pField , pEntity , pValue ) { if ( typeof ( pValue ) === 'string' ) { return { valid : true } ; } ; return { valid : false , reason : 'field value must be a string' } ; } ; export async function isNumberValidator ( pField , pEntity , pValue ) { if ( typeof ( pValue ) === 'number' ) { return { valid : true } ; } ; return { valid : false , reason : 'field value must be a number' } ; } ; export async function isBooleanValidator ( pField , pEntity , pValue ) { if ( typeof ( pValue ) === 'boolean' ) { return { valid : true } ; } ; return { valid : false , reason : 'field value must be a boolean' } ; } ; export async function isPathValidator ( pField , pEntity , pValue ) { if ( typeof ( pValue ) === 'string' ) { if ( /^\/-?\d+(\.\d*)?,-?\d+(\.\d*)?,-?\d+(\.\d*)?\/-?\d+(\.\d*)?,-?\d+(\.\d*)?,-?\d+(\.\d*)?,-?\d+(\.\d*)?$/ . test ( pValue ) ) { return { valid : true } ; } ; } ; return { valid : false , reason : 'path must be a string of the form "/f,f,f/f,f,f,f' } ; } ; export async function isLongPathValidator ( pField , pEntity , pValue ) { if ( typeof ( pValue ) === 'string' ) { if ( /^.*\/-?\d+(\.\d*)?,-?\d+(\.\d*)?,-?\d+(\.\d*)?\/-?\d+(\.\d*)?,-?\d+(\.\d*)?,-?\d+(\.\d*)?,-?\d+(\.\d*)?$/ . test ( pValue ) ) { return { valid : true } ; } ; } ; return { valid : false , reason : 'path must be a string of the form "optional-domain/f,f,f/f,f,f,f' } ; } ; export async function isDateValidator ( pField , pEntity , pValue ) { if ( pValue instanceof Date ) { return { valid : true } ; } ; return { valid : false , reason : 'field value must be a valid date string' } ; } ; export async function isObjectValidator ( pField , pEntity , pValue ) { if ( pValue instanceof Object ) { return { valid : true } ; } ; return { valid : false , reason : 'field value must resolve to an object' } ; } ; export async function isSArraySet ( pField , pEntity , pValue ) { if ( isValidSArraySet ( pValue ) ) { return { valid : true } ; } ; return { valid : false , reason : 'field value must be an array of strings' } ; } ; export function isValidSArraySet ( pValue ) { let ret = false ; if ( typeof ( pValue ) === 'string' ) { Logger . cdebug ( 'field-setting' , `isValidSArraySet: value is string and assuming set` ) ; ret = true ; } else { if ( isValidSArray ( pValue ) ) { Logger . cdebug ( 'field-setting' , `isValidSArraySet: value is an SArray` ) ; ret = true ; } else { if ( pValue && ( pValue . set || pValue . add || pValue . remove ) ) { Logger . cdebug ( 'field-setting' , `isValidSArraySet: object with one of the fields` ) ; let eachIsOk = true ; if ( eachIsOk && pValue . set ) { eachIsOk = typeof ( pValue . set ) === 'string' || isValidSArray ( pValue . set ) ; Logger . cdebug ( 'field-setting' , `isValidSArraySet: pValue.set is ${ eachIsOk }` ) ; } ; if ( eachIsOk && pValue . add ) { eachIsOk = typeof ( pValue . add ) === 'string' || isValidSArray ( pValue . add ) ; Logger . cdebug ( 'field-setting' , `isValidSArraySet: pValue.add is ${ eachIsOk }` ) ; } ; if ( eachIsOk && pValue . remove ) { eachIsOk = typeof ( pValue . remove ) === 'string' || isValidSArray ( pValue . remove ) ; Logger . cdebug ( 'field-setting' , `isValidSArraySet: pValue.remove is ${ eachIsOk }` ) ; } ; ret = eachIsOk ; } ; } ; } ; return ret ; } ; export function isSArray ( pField , pEntity , pValue ) { return isValidSArray ( pValue ) ; } ; export function isValidSArray ( pValue ) { let ret = false ; if ( pValue ) { if ( Array . isArray ( pValue ) ) { let allStrings = true ; for ( const val of pValue ) { if ( typeof ( val ) !== 'string' ) { allStrings = false ; break ; } ; } ; ret = allStrings ; } ; } ; Logger . cdebug ( 'field-setting' , `isSArray: "${ JSON . stringify ( pValue ) }" is ${ ret }` ) ; return ret ; } ; export function * walkSArraySetter ( pValue ) { if ( IsNotNullOrEmpty ( pValue ) ) { if ( typeof ( pValue ) === 'string' ) { yield ( pValue as string ) ; } else { if ( Array . isArray ( pValue ) ) { for ( const aVal of pValue ) { yield aVal ; } ; } else { for ( const manipulationSection of [ 'set' , 'add' , 'remove' ] ) { if ( pValue . hasOwnProperty ( manipulationSection ) ) { const sectionVal = pValue [ manipulationSection ] ; if ( Array . isArray ( sectionVal ) ) { for ( const aVal of sectionVal ) { yield aVal ; } ; } else { yield sectionVal ; } ; } ; } ; } ; } ; } ; } ; export type ValidCheckFunction = ( pVal : string ) => Promise < boolean > ; export async function verifyAllSArraySetValues ( pValue , pCheckFunction ) { let ret = false ; if ( IsNotNullOrEmpty ( pCheckFunction ) && isValidSArraySet ( pValue ) ) { ret = true ; for ( const aVal of walkSArraySetter ( pValue ) ) { if ( ! await pCheckFunction ( aVal ) ) { ret = false ; break ; } ; } ; } ; return ret ; } ; export async function noGetter ( pField , pEntity ) { Logger . error ( `noGetter: attempt to get field ${ pField . entity_field }` ) ; } ; export async function simpleGetter ( pField , pEntity ) { if ( pEntity . hasOwnProperty ( pField . entity_field ) ) { return ( pEntity as any ) [ pField . entity_field ] ; } ; return undefined ; } ; export async function dateStringGetter ( pField , pEntity ) { if ( pEntity . hasOwnProperty ( pField . entity_field ) ) { const dateVal = ( pEntity as any ) [ pField . entity_field ] ; return dateVal ? dateVal . toISOString ( ) : undefined ; } ; return undefined ; } ; export async function noSetter ( pField , pEntity , pVal ) { Logger . error ( `noSetter: attempt to set field ${ pField . entity_field }` ) ; } ; export async function simpleSetter ( pField , pEntity , pVal ) { Logger . cdebug ( 'field-setting' , `simpleSetter: setting ${ pField . entity_field }=>${ JSON . stringify ( pVal ) }` ) ; ( pEntity as any ) [ pField . entity_field ] = pVal ; } ; export async function noOverwriteSetter ( pField , pEntity , pVal ) { if ( IsNotNullOrEmpty ( pVal ) ) { if ( Array . isArray ( pVal ) ) { if ( pVal . length > 0 ) { simpleSetter ( pField , pEntity , pVal ) ; } ; } else { simpleSetter ( pField , pEntity , pVal ) ; } ; } ; } ; export async function sArraySetter ( pField , pEntity , pVal ) { const fieldName = pField . entity_field ; Logger . cdebug ( 'field-setting' , `sArraySetter: setting ${ fieldName } with ${ JSON . stringify ( pVal ) }` ) ; let val = ( pEntity as any ) [ fieldName ] ?? [ ] ; if ( typeof ( val ) === 'string' ) { Logger . cdebug ( 'field-setting' , `sArraySetter: old value of ${ fieldName } is just string. Making array` ) ; val = [ val ] ; } ; if ( typeof ( pVal ) === 'string' ) { Logger . cdebug ( 'field-setting' , `sArraySetter: adding string ${ fieldName }` ) ; SArray . add ( val , pVal ) ; } else { if ( isSArray ( pField , pEntity , pVal ) ) { Logger . cdebug ( 'field-setting' , `sArraySetter: just passed SArray for ${ fieldName }. Assuming set` ) ; val = pVal ; } else { if ( typeof ( pVal ) === 'object' && ( pVal . set || pVal . add || pVal . remove ) ) { if ( pVal . set ) { val = ( typeof ( pVal . set ) === 'string' ) ? [ pVal . set ] : pVal . set ; } ; if ( pVal . add ) { if ( Array . isArray ( pVal . add ) ) { Logger . cdebug ( 'field-setting' , `sArraySetter: adding array ${ fieldName }=>${ JSON . stringify ( pVal . add ) }` ) ; for ( const aVal of pVal . add ) { SArray . add ( val , aVal ) ; } ; } else { Logger . cdebug ( 'field-setting' , `sArraySetter: adding one ${ fieldName }=>${ JSON . stringify ( pVal . add ) }` ) ; SArray . add ( val , pVal . add ) ; } ; } ; if ( pVal . remove ) { if ( Array . isArray ( pVal . remove ) ) { Logger . cdebug ( 'field-setting' , `sArraySetter: removing array ${ fieldName }=>${ JSON . stringify ( pVal . remove ) }` ) ; for ( const aVal of pVal . remove ) { SArray . remove ( val , aVal ) ; } ; } else { Logger . cdebug ( 'field-setting' , `sArraySetter: removing one ${ fieldName }=>${ JSON . stringify ( pVal . remove ) }` ) ; SArray . remove ( val , pVal . remove ) ; } ; } ; } else { Logger . cdebug ( 'field-setting' , `sArraySetter: passed value that is not string, SArray, or manipulation object` ) ; } ; } ; } ; Logger . cdebug ( 'field-setting' , `sArraySetter: resulting ${ fieldName }=>${ JSON . stringify ( val ) }` ) ; ( pEntity as any ) [ pField . entity_field ] = cleanStringArray ( val ) ; } ; function cleanStringArray ( pValues ) { const ret = [ ] ; if ( Array . isArray ( pValues ) ) { for ( const val of pValues ) { if ( typeof ( val ) === 'string' ) { ret . push ( val ) ; } ; } ; } ; return ret ; } ;