import XMLWriter = require ( 'xml-writer' ) ; export class Fetch { filter : Filter ; public attributes : string [ ] = [ ] ; class classdesc param entityName { string } param attr { string | boolean | string [ ] } param filterConditions { object } Optional. Object that describes conditions in an JSON notation. More Info:  Fetch example example example constructor ( public entityName ? , attr ? , filterConditions ? ) { if ( this . attributes != undefined ) this . setAttributes ( attr ) ; if ( filterConditions != undefined ) this . setFilter ( filterConditions ) ; } toString ( ) { var xw = new XMLWriter ( true ) ; xw . startElement ( 'fetch' ) ; xw . startElement ( 'entity' ) ; if ( this . entityName ) { xw . writeAttribute ( 'name' , this . entityName . toLowerCase ( ) ) ; } this . serializeAttributes ( this . attributes , xw ) ; this . serializeConditions ( this . filter , xw ) ; xw . endDocument ( ) ; return xw . toString ( ) ; } private serializeAttributes ( value , writer ) { for ( var i = 0 ; i < value . length ; i ++ ) { var attr = value [ i ] . toLowerCase ( ) ; if ( attr == "*" ) { writer . startElement ( "all-attributes" ) ; } else { writer . startElement ( "attribute" ) ; writer . writeAttribute ( "name" , attr ) ; } writer . endElement ( ) ; } } /**
     * Sets the filter criteria of the current <i>FetchXml</i> with the specified values.
     *
     * The specified value can be eiher a  Filter object or a conditions object.
     *
     * A conditions object is a Javascript object where every property represents a condition.
     *
     * If the object contains a property, and that property contains a simple value, like an string or a number, that means property equals to value.
     *
     * If you need to specify another operator, then you have to use the form: {attribute:{$operator:value}}
     *
     * If the value is an array, then the $in operator is used.
     *
     * If the value is a null value, then the nulloperator is applied. For example: {name:null} will retrieve all the records where the name is null.
     *
     *  method param filterCondition { Filter | object } see Build queries with FetchXML:  https example example example example example example example public setFilter ( filterConditions ) { if ( filterConditions != null ) { if ( filterConditions instanceof Filter ) { this . filter = filterConditions ; } else { this . filter = this . convert ( filterConditions ) ; } } } public setAttributes ( attributes ) { if ( attributes == null ) { this . attributes = [ ] ; } else { if ( Array . isArray ( attributes ) ) { this . attributes = attributes ; } else if ( typeof attributes == "string" ) { this . attributes = [ < string > attributes ] ; } else if ( typeof attributes == "boolean" ) { this . attributes = [ "*" ] ; } } } private serializeValue ( value ) { var strValue = "" ; if ( value !== null && value !== undefined ) { if ( value instanceof Date ) { var dateValue = < Date > value ; var pad2 = x => String ( "00" + x ) . slice ( - 2 ) ; strValue = `${ dateValue . getUTCFullYear ( ) }-${ pad2 ( dateValue . getUTCMonth ( ) ) }-${ pad2 ( dateValue . getUTCDate ( ) ) } ${ pad2 ( dateValue . getUTCHours ( ) ) }:${ pad2 ( dateValue . getUTCMinutes ( ) ) }:${ pad2 ( dateValue . getUTCSeconds ( ) ) }` ; } else { strValue = value + "" ; } } return strValue ; } private serializeConditions ( filter , writer ) { if ( filter && filter . conditions && filter . conditions . length > 0 ) { var filterTypeName = FilterTypes [ filter . filterType ] . toLowerCase ( ) ; writer . startElement ( "filter" ) . writeAttribute ( "type" , filterTypeName ) ; for ( var i = 0 ; i < filter . conditions . length ; i ++ ) { var filterCondition = filter . conditions [ i ] ; var operatorName = this . operatorNames [ filterCondition . operator ] ; var attributeName = filterCondition . attribute . toLowerCase ( ) ; writer . startElement ( "condition" ) . writeAttribute ( "attribute" , attributeName ) . writeAttribute ( "operator" , operatorName ) ; if ( filterCondition . values && filterCondition . values . length > 0 ) { if ( filterCondition . operator == Operators . In || filterCondition . operator == Operators . NotIn || filterCondition . values . length > 1 ) { for ( var j = 0 ; j < filterCondition . values . length ; j ++ ) { var strValue = this . serializeValue ( filterCondition . values [ j ] ) ; writer . startElement ( "value" ) . text ( strValue ) . endElement ( ) ; } } else { var strValue = this . serializeValue ( filterCondition . values [ 0 ] ) ; writer . writeAttribute ( "value" , strValue ) ; } } writer . endElement ( ) ; } writer . endElement ( ) ; } } private operatorNames : string [ ] = [ 'eq' , 'neq' , 'gt' , 'ge' , 'le' , 'lt' , 'like' , 'not-like' , 'in' , 'not-in' , 'between' , 'not-between' , 'null' , 'not-null' ] ; private operatorJsonNames : string [ ] = [ '$eq' , '$neq' , '$gt' , '$ge' , '$le' , '$lt' , '$like' , '$notlLike' , '$in' , '$notIn' , '$between' , '$notBetween' , "" , , "" ] ; private NOT_NULL_OPERATOR = "$notNull" ; private convert ( conditionExpression ) { var filter = new Filter ( ) ; for ( var propName in conditionExpression ) { var propValue = conditionExpression [ propName ] ; if ( propValue == null ) { filter . conditions . push ( new Condition ( propName , Operators . Null ) ) ; } else if ( propValue == this . NOT_NULL_OPERATOR ) { filter . conditions . push ( new Condition ( propName , Operators . NotNull ) ) ; } else if ( typeof propValue === 'number' || propValue instanceof Number || typeof propValue === 'string' || propValue instanceof String || typeof propValue === 'boolean' || propValue instanceof Date ) { filter . conditions . push ( new Condition ( propName , Operators . Equal , [ propValue ] ) ) ; } else if ( Array . isArray ( propValue ) ) { filter . conditions . push ( new Condition ( propName , Operators . In , propValue ) ) ; } else if ( typeof propValue === 'object' && ! ( propValue instanceof Date ) ) { for ( var i = 0 ; i < this . operatorJsonNames . length ; i ++ ) { var operatorName = this . operatorJsonNames [ i ] ; if ( operatorName && propValue [ operatorName ] != undefined ) { propValue = propValue [ operatorName ] ; if ( Array . isArray ( propValue ) ) { filter . conditions . push ( new Condition ( propName , i , propValue ) ) ; } else { filter . conditions . push ( new Condition ( propName , i , [ propValue ] ) ) ; } break ; } } } } return filter ; } } typedef FilterTypes property { number } And property { number } Or export enum FilterTypes { And , Or } export class Filter { class classdesc Describes a Filter in a  Fetch query.
      member member constructor ( public conditions ? , public filterType ? ) { if ( this . conditions == null ) this . conditions = new Array < Condition > ( ) ; if ( this . filterType == null ) this . filterType = FilterTypes . And ; } } export enum Operators { Equal , NotEqual , GreaterThan , GreaterEqual , LessEqual , LessThan , Like , NotLike , In , NotIn , Between , NotBetween , Null , NotNull } export class Condition { constructor ( public attribute ? , public operator ? , public values ? ) { } }