├── LICENSE.txt ├── README.md └── Sdk.FetchXml.ts /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Jim Daly 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ClientSideFetchXmlObjectLibraries 2 | JavaScript and TypeScript libraries which provide an object model for Microsoft Dynamics CRM FetchXML Queries 3 | 4 | These libraries provide an object model to compose FetchXml queries using either JavaScript directly, 5 | or by using TypeScript. 6 | ## In this README 7 | * [Ordinary use cases for client-side fetchXml queries](#ordinary-use-cases-for-client-side-fetchxml-queries) 8 | * [Why these libraries?](#why-these-libraries) 9 | * [Convert from XML to object and back](#convert-from-xml-to-object-and-back) 10 | * [Why two separate libraries?](#why-two-separate-libraries) 11 | * [When to use these libraries?](#when-to-use-these-libraries) 12 | * [Examples](#examples) 13 | * [Why do some classes have a read-only hash property?](#why-do-some-classes-have-a-read-only-hash-property) 14 | * [How were these tested?](#how-were-these-tested) 15 | * [Why aren't these in the CRM SDK?](#why-arent-these-in-the-crm-sdk) 16 | 17 | ## Ordinary use cases for client-side fetchXml queries 18 | Typically developers will use the advanced find tool in the CRM web application to compose a query and then 19 | download the fetchxml definition of the query. They can then modify the query as needed and use the fetch.xsd 20 | schema from the SDK if they want to make sure that the edits they make are valid according to the schema. They 21 | can then include include the fetchxml query definition as a string within JavaScript functions in the application. 22 | This approach is effective and these libraries are not intended as a replacement for this proven approach. 23 | 24 | ## Why these libraries? 25 | These libraries are an experiment to provide a better development experience when a developer wants 26 | more flexibilty to compose a query programmatically. With the 2011 (SOAP) endpoint C# developers can use the 27 | [QueryExpression Class](https://msdn.microsoft.com/en-us/library/microsoft.xrm.sdk.query.queryexpression.aspx) 28 | to compose queries. With JavaScript, the [Sdk.Soap.js](https://code.msdn.microsoft.com/SdkSoapjs-9b51b99a) sample 29 | library provides an Sdk.Query.QueryExpression class which provides the same functionality. 30 | 31 | However, with the Microsoft Dynamics CRM Web API there is no similar object designed to compose queries 32 | programmatically. You can compose queries using the OData syntax 33 | (see [Query Data using the Web API](https://msdn.microsoft.com/en-us/library/gg334767.aspx)), but this doesn't 34 | yet provide all the capabilities of FetchXML. So these libraries were created in an effort to see whether providing 35 | a wrapper around the objects defined by the fetchXML could provide a better way to compose queries in code. 36 | 37 | Both of these libraries provide the same interface which allows for instantiating instances of objects defined 38 | in the FetchXML Schema and public properties to set the values. In addition, these libraries provide methods 39 | to set every property and add or remove objects from collections. These methods are chainable because they return 40 | the object that they are applied to. 41 | 42 | ## Convert from XML to object and back 43 | Both of these libraries provide a `Sdk.FetchXml.fetch.fromXml` static method which accept a fetchXML string and 44 | return an `Sdk.FetchXML.fetch` object with all the child objects contained within it. The 45 | `Sdk.FetchXml.fetch.toXml` method returns a string that is the valid fetchXml for the objects contained within it. 46 | So this is basically a way to deserialize and serialize the fetchXml into the `Sdk.FetchXml.fetch` object. 47 | 48 | ## Why two separate libraries? 49 | At the end of the day, both of these result in a JavaScript library. I wrote the JavaScript library first. 50 | Then I wrote the TypeScript version because more and more people have been asking for TypeScript libraries. 51 | Not having a lot of experience with TypeScript, I wanted to see how it could be used to get the same result 52 | I'm used to getting with plain old JavaScript. In the end, I was able to get the same interfaces but I had to apply some different strategies. 53 | 54 | For example, in JavaScript I prefer to return sealed objects because I want to eliminate the possiblity that people 55 | might add or remove the properties of the class instances. In Typescript I found I had to enable 56 | [Decorators](https://www.typescriptlang.org/docs/handbook/decorators.html) to get the behavior I wanted. So you will 57 | need to enable `experimentalDecorators` and use a tsconfig.json with this setting set to true. Also, in JavaScript I 58 | like to use [Object.freeze](https://msdn.microsoft.com/en-us/library/ff806186.aspx) for static objects I use for enumerations. 59 | Seems that TypeScript enumerations can only have number values, so I used decorators again to ensure that the properties 60 | for these object could not be modified. 61 | 62 | I certainly like that the IntelliSense provided for TypeScript is much more solid that the extremely fragile IntelliSense 63 | that the JavaScript language service provides in Visual Studio. But I think I'd need to build an full TypeScript application 64 | before it becomes my my preferred way to write JavaScript. 65 | 66 | ## When to use these libraries? 67 | These libraries are relatively large (3000+ lines of code) and even minified they are about 40KB. For the typical use 68 | case where a developer simply needs to configure a relatively static query, or just include a few variables, the approach 69 | described in [Ordinary use cases for client-side fetchXml queries](#ordinary-use-cases-for-client-side-fetchxml-queries) 70 | is still probably the most effective approach for client-side scripts. 71 | 72 | I expect that these libraries may be helpful when a developer needs to provide a user interface like the advanced find tool 73 | in the CRM application. I can imagine leveraging CRM metadata together with these libraries to create this experience. 74 | Or perhaps a developer will leverage the objects in this library to provide an IQueryable type interface specifically for 75 | Microsoft CRM queries? Or perhaps some other Node.js or Cordova application I can't even imagine. 76 | 77 | If you use these libraries, please let me know how you use them. 78 | 79 | ## Examples 80 | Looking at the example in the CRM SDK [Use FetchXML to construct a query](https://msdn.microsoft.com/en-us/library/gg328117.aspx). 81 | ```xml 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | ``` 94 | The following JavaScript produces the equivalent XML: 95 | ```javascript 96 | var ns = Sdk.FetchXml; 97 | var q = ns.fetch( 98 | ns.entity("account") 99 | .addAttribute("accountid") 100 | .addAttribute("name") 101 | .addLinkEntity( 102 | ns.linkEntity("systemuser",null,"owninguser") 103 | .addFilter( 104 | ns.filter(ns.FilterType.And) 105 | .addCondition( 106 | ns.condition( 107 | "lastname", 108 | ns.Operator.NotEqual, 109 | [ns.value("Cannon")] 110 | ) 111 | ) 112 | ) 113 | ) 114 | ) 115 | console.log(q.toXml()); 116 | ``` 117 | Note that specifying a namespace variable, in this case `ns` means less typing. Also notice that using the `new` keyword 118 | is optional when instantiating classes. The classes are defined so that they will still work if you forget to use it. 119 | 120 | The enumerations return string values. You can use string values instead of the enumerations if you know them, but they must match the 121 | value of an enumeration. i.e. Use either `Sdk.FetchXml.FilterType.And` or just `and`. 122 | 123 | Also note the exclusive use of the chained add* methods to compose the object. The same query could also be composed this way: 124 | ```javascript 125 | var ns = Sdk.FetchXml; 126 | var condition = ns.condition("lastname", ns.Operator.NotEqual, [ns.value("Cannon")]); 127 | var filter = ns.filter(ns.FilterType.And); 128 | filter.conditions = [condition]; 129 | var linkEntity = ns.linkEntity("systemuser"); 130 | linkEntity.to = "owninguser"; 131 | linkEntity.filters = [filter]; 132 | var entity = ns.entity("account", [ns.attribute("accountid"), ns.attribute("name")]); 133 | entity.linkEntities = [linkEntity]; 134 | var q = ns.fetch(entity); 135 | console.log(q.toXml()); 136 | ``` 137 | But I think this style is difficult to read. But these can also be used in combination: 138 | ```javascript 139 | var ns = Sdk.FetchXml; 140 | var condition = ns.condition("lastname", ns.Operator.NotEqual, [ns.value("Cannon")]); 141 | 142 | var filter = ns.filter(ns.FilterType.And) 143 | .addCondition(condition); 144 | 145 | var linkEntity = ns.linkEntity("systemuser",null,"owninguser") 146 | .addFilter(filter); 147 | 148 | var entity = ns.entity("account", [ns.attribute("accountid"), ns.attribute("name")]) 149 | .addLinkEntity(linkEntity); 150 | 151 | var q = ns.fetch(entity); 152 | console.log(q.toXml()); 153 | ``` 154 | 155 | All values must be set using an array, even when there is just a single value. If it is a single value, the XML will set 156 | the value as an attribute on the condition. If multiple values are used, they will result in separate child `value` elements 157 | of the condition element. 158 | 159 | TypeScript is very similar to JavaScript except that you must use the `new` keyword. 160 | ```typescript 161 | var ns = Sdk.FetchXml; 162 | var q = new ns.fetch( 163 | new ns.entity("account") 164 | .addAttribute("accountid") 165 | .addAttribute("name") 166 | .addLinkEntity( 167 | new ns.linkEntity("systemuser",null,"owninguser") 168 | .addFilter( 169 | new ns.filter(ns.FilterType.And) 170 | .addCondition( 171 | new ns.condition( 172 | "lastname", 173 | ns.Operator.NotEqual, 174 | [new ns.value("Cannon")] 175 | ) 176 | ) 177 | ) 178 | ) 179 | ); 180 | console.log(q.toXml()); 181 | ``` 182 | ## Why do some classes have a read-only hash property? 183 | In order to implement methods to add or remove items from a collection it was challenging to identify which specific item 184 | to remove. If you had an instance of an object used in a query that would match using a `===` operator, you can detect it 185 | and remove it by reference. But if you add an object using the chaining methods you wouldn't have a reference and none of these 186 | objects have a unique identifier property. So I found some code on stack overflow 187 | [Generate a Hash from string in Javascript/jQuery](http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery) 188 | which cited this source [Javascript implementation of Java’s String.hashCode() method](http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/) 189 | Using this extension to the String.prototype, I implemented a read-only hash property that seems to uniquely match the available 190 | property values for each object. Using this property, I implemented various `remove*` methods that will remove a matching object from a reference 191 | when you don't happen to have a reference to it. There are also various `remove*ByRef` methods you can use if you do have a reference 192 | to an item in a collection. 193 | For `Sdk.FetchXml.entity`, `Sdk.FetchXml.linkEntity` and `Sdk.FetchXml.condition`, there are `removeAttributeByName` and `removeValueByValue` methods 194 | because it seems that people will want to remove attributes or values based on the name or value directly. 195 | 196 | ## How were these tested? 197 | To test these I wrote a script to retrieve the fetchXML for all the system views (savedquery entity) and pass the string to the 198 | `Sdk.FetchXml.fetch.fromXml` method to instantiate the object. Then I called the `toXml` method on that instantiated object. 199 | After a few normalization adjustments, I compared the length of the strings to make sure they were identical. 200 | Most of the normalization adjustments had to do with inconsistent closing of elements, whether default attribute values were set, 201 | and different ways to set boolean values. 202 | The following is the function I used that highlight where differences were found that had no impact on the query defined: 203 | ```javascript 204 | function normalizeStrings(str) { 205 | 206 | if (str.indexOf(" distinct=\"false\"") > -1) { 207 | str = str.replace(" distinct=\"false\"", ""); 208 | } 209 | 210 | if (str.indexOf("\">") > -1) { 211 | str = str.replace("\">", "\" />"); 212 | } 213 | 214 | if (str.indexOf("\">") > -1) { 215 | str = str.replace("\">", "\" />"); 216 | } 217 | 218 | if (str.indexOf("\">") > -1) { 219 | str = str.replace("\">", "\" />"); 220 | } 221 | 222 | if (str.indexOf("isquickfindfields=\"1\"") > -1) { 223 | str = str.replace("isquickfindfields=\"1\"", "isquickfindfields=\"true\""); 224 | } 225 | 226 | if (str.indexOf("") > -1) { 227 | str = str.replace("", ""); 228 | } 229 | 230 | if (str.indexOf("") > -1) { 231 | str = str.replace("", ""); 232 | } 233 | 234 | if (str.indexOf(" descending=\"false\"") > -1) { 235 | str = str.replace(" descending=\"false\"", ""); 236 | } 237 | return str; 238 | } 239 | ``` 240 | 241 | ## Why aren't these in the CRM SDK? 242 | A combination of reasons: 243 | * It isn't known whether people are interested in this style of composing queries. If we publish them in the SDK it would 244 | seem like this is something the CRM product team thinks people want and need. You might start seeing questions about it on 245 | certification exams. 246 | * I wrote these on my own time just as an experiment. If I include them in the SDK we are obligated to maintain them. 247 | * I used some code I found on stack overflow to implement hash values for classes which may be in a collection. 248 | (See [Why do some classes have a read-only hash property?](#why-do-some-classes-have-a-read-only-hash-property)) 249 | This is not allowed for official Microsoft samples. 250 | * I would like to share these with the community. If you have an enhancement, GitHub makes it easy for you to contribute to it or fork it. 251 | -------------------------------------------------------------------------------- /Sdk.FetchXml.ts: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 Jim Daly 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | namespace Sdk.FetchXml { 26 | @sealed 27 | export class attribute { 28 | /** 29 | * Contains the data for a fetchXml attribute element. 30 | * @param name The logical name of the attribute 31 | */ 32 | constructor(name: string) { 33 | //new keyword not required 34 | if (!(this instanceof attribute)) 35 | { return new attribute(name) } 36 | 37 | this.name = name; 38 | } 39 | 40 | private _name: string; 41 | private _build: Build = null; 42 | private _addedBy: string = null; 43 | private _alias: string = null; 44 | private _aggregate: Aggregate = null; 45 | private _groupBy: boolean = null; 46 | private _dateGrouping: DateGrouping = null; 47 | private _userTimeZone: boolean = null; 48 | 49 | /** 50 | *Gets or sets logical name of the attribute 51 | */ 52 | public get name(): string { 53 | return this._name; 54 | } 55 | public set name(value: string) { 56 | if (!Util.isString(value)) { 57 | throw new Error("Sdk.FetchXml.attribute name property must be an string."); 58 | } 59 | this._name = value; 60 | } 61 | /** 62 | *Gets or sets the build of the attribute 63 | */ 64 | public get build(): Build { 65 | return this._build; 66 | } 67 | public set build(value: Build) { 68 | if (!Util.isEnumMemberOrNull(Build, value)) { 69 | throw new Error("Sdk.FetchXml.attribute build property must be an Sdk.FetchXml.Build value or null."); 70 | } 71 | this._build = value; 72 | } 73 | /** 74 | *Gets or sets the addedBy property of the attribute 75 | */ 76 | public get addedBy(): string { 77 | return this._addedBy; 78 | } 79 | public set addedBy(value: string) { 80 | if (!Util.isStringOrNull(value)) { 81 | throw new Error("Sdk.FetchXml.attribute addedBy property must be an string value or null."); 82 | } 83 | this._addedBy = value; 84 | } 85 | /** 86 | *Gets or sets the alias property of the attribute 87 | */ 88 | public get alias(): string { 89 | return this._alias; 90 | } 91 | public set alias(value: string) { 92 | if (!Util.isStringOrNull(value)) { 93 | throw new Error("Sdk.FetchXml.attribute alias property must be an string value or null."); 94 | } 95 | this._alias = value; 96 | } 97 | /** 98 | *Gets or sets the aggregate property of the attribute 99 | */ 100 | public get aggregate(): Aggregate { 101 | return this._aggregate; 102 | } 103 | public set aggregate(value: Aggregate) { 104 | if (!Util.isEnumMemberOrNull(Aggregate, value)) { 105 | throw new Error("Sdk.FetchXml.attribute aggregate property must be an Sdk.FetchXml.Aggregate value or null."); 106 | } 107 | this._aggregate = value; 108 | } 109 | /** 110 | *Gets or sets the groupBy property of the attribute 111 | */ 112 | public get groupBy(): boolean { 113 | return this._groupBy; 114 | } 115 | public set groupBy(value: boolean) { 116 | if (!Util.isBooleanOrNull(value)) { 117 | throw new Error("Sdk.FetchXml.attribute groupBy property must be an boolean value or null."); 118 | } 119 | this._groupBy = value; 120 | } 121 | /** 122 | * Gets or sets the dateGrouping property of the attribute 123 | */ 124 | public get dateGrouping(): DateGrouping { 125 | return this._dateGrouping; 126 | } 127 | public set dateGrouping(value: DateGrouping) { 128 | if (!Util.isEnumMemberOrNull(DateGrouping, value)) { 129 | throw new Error("Sdk.FetchXml.attribute dateGrouping property must be an Sdk.FetchXml.DateGrouping value or null."); 130 | } 131 | this._dateGrouping = value; 132 | } 133 | /** 134 | *Gets or sets the userTimeZone property of the attribute 135 | */ 136 | public get userTimeZone(): boolean { 137 | return this._userTimeZone; 138 | } 139 | public set userTimeZone(value: boolean) { 140 | if (!Util.isBooleanOrNull(value)) { 141 | throw new Error("Sdk.FetchXml.attribute userTimeZone property must be an boolean value or null."); 142 | } 143 | this._userTimeZone = value; 144 | } 145 | 146 | /** @description Sets the name property of the attribute attribute 147 | * @param {string} name The name value to apply to the attribute 148 | * @returns {Sdk.FetchXml.attribute} 149 | */ 150 | public setName(name: string) { 151 | this.name = name; 152 | return this; 153 | } 154 | 155 | /** @description Sets the build property of the build attribute 156 | * @param {Sdk.FetchXml.Build | null} build The build value to apply to the attribute 157 | * @returns {Sdk.FetchXml.attribute} 158 | */ 159 | public setBuild(build?: Build) { 160 | (build) ? this.build = build : this.build = null; 161 | return this; 162 | } 163 | 164 | /** @description Sets the addedBy property of the attribute attribute 165 | * @param {string | null} addedBy The addedBy value to apply to the attribute 166 | * @returns {Sdk.FetchXml.attribute} 167 | */ 168 | public setAddedBy(addedBy?: string) { 169 | (addedBy) ? this.addedBy = addedBy : this.addedBy = null; 170 | return this; 171 | } 172 | 173 | /** @description Sets the alias property of the attribute attribute 174 | * @param {string} alias The alias value to apply to the attribute 175 | * @returns {Sdk.FetchXml.attribute} 176 | */ 177 | public setAlias(alias?: string) { 178 | (alias) ? this.alias = alias : this.alias = null; 179 | return this; 180 | } 181 | 182 | /** @description Sets the aggregate property of the attribute attribute 183 | * @param {Sdk.FetchXml.Aggregate | null } aggregate The aggregate value to apply to the attribute 184 | * @returns {Sdk.FetchXml.attribute} 185 | */ 186 | 187 | public setAggregate(aggregate?: Aggregate) { 188 | (aggregate) ? this.aggregate = aggregate : this.aggregate = null; 189 | return this; 190 | } 191 | /** @description Sets the groupBy property of the attribute attribute 192 | * @param {boolean | null} groupBy The groupBy value to apply to the attribute 193 | * @returns {Sdk.FetchXml.attribute} 194 | */ 195 | 196 | public setGroupBy(groupBy?: boolean) { 197 | (groupBy) ? this.groupBy = groupBy : groupBy = null; 198 | return this; 199 | } 200 | 201 | /** @description Sets the dateGrouping property of the attribute attribute 202 | * @param {Sdk.FetchXml.DateGrouping | null} dateGrouping The dateGrouping value to apply to the attribute 203 | * @returns {Sdk.FetchXml.attribute} 204 | */ 205 | public setDateGrouping(dateGrouping?: DateGrouping) { 206 | (dateGrouping) ? this.dateGrouping = dateGrouping : this.dateGrouping = null; 207 | return this; 208 | } 209 | 210 | /** @description Sets the userTimeZone property of the attribute attribute 211 | * @param {boolean | null} userTimeZone The userTimeZone value to apply to the attribute 212 | * @returns {Sdk.FetchXml.attribute} 213 | */ 214 | public setUserTimeZone(userTimeZone?: boolean) { 215 | (userTimeZone) ? this.userTimeZone = userTimeZone : this.userTimeZone = null; 216 | return this; 217 | } 218 | 219 | //Internal use only 220 | toXml(doc: XMLDocument): Node { 221 | var aNode = doc.createElement("attribute"); 222 | aNode.setAttribute("name", this.name); 223 | if (this.build) { 224 | aNode.setAttribute("build", this.build); 225 | } 226 | if (this.addedBy) { 227 | aNode.setAttribute("addedby", this.addedBy); 228 | } 229 | if (this.alias) { 230 | aNode.setAttribute("alias", this.alias); 231 | } 232 | if (this.aggregate) { 233 | aNode.setAttribute("aggregate", this.aggregate); 234 | } 235 | if (Util.isBoolean(this.groupBy)) { 236 | aNode.setAttribute("groupby", (this.groupBy) ? "true" : "false"); 237 | } 238 | if (this.dateGrouping) { 239 | aNode.setAttribute("dategrouping", this.dateGrouping); 240 | } 241 | if (Util.isBoolean(this.userTimeZone)) { 242 | aNode.setAttribute("usertimezone", (this.userTimeZone) ? "true" : "false"); 243 | } 244 | return aNode; 245 | } 246 | 247 | //Internal use only 248 | static attributeFromXml(xml) { 249 | var attObj = new attribute(xml.attributes.getNamedItem("name").nodeValue); 250 | 251 | Util.parseAttributes(xml, attObj, (attObj, name, value) => { 252 | switch (name) { 253 | case "build": 254 | case "alias": 255 | case "aggregate": 256 | attObj[name] = value; 257 | break; 258 | case "addedby": 259 | attObj.addedBy = value; 260 | break; 261 | case "dategrouping": 262 | attObj.dateGrouping = value; 263 | break; 264 | case "groupby": 265 | attObj.groupBy = Util.convertFetchBoolType(value); 266 | case "usertimezone": 267 | attObj.userTimeZone = Util.convertFetchBoolType(value); 268 | break; 269 | default: 270 | break; 271 | 272 | } 273 | }) 274 | 275 | return attObj; 276 | } 277 | } 278 | @sealed 279 | export class condition { 280 | /** 281 | * Contains the data for a fetchXml condition element. 282 | * @param attribute The attribute to evaluate in the condition 283 | * @param operator The operator to use when evaluating the attribute 284 | * @param [values] The value(s) to apply in the comparison. 285 | */ 286 | constructor(attribute: string, operator: Sdk.FetchXml.Operator, values?: Array) { 287 | //New keyword not required in JS 288 | if (!(this instanceof Sdk.FetchXml.condition)) 289 | { return new Sdk.FetchXml.condition(attribute, operator, values) } 290 | 291 | if (attribute && operator) { 292 | this.attribute = attribute; 293 | this.operator = operator; 294 | } 295 | else { 296 | throw new Error("Sdk.FetchXml.condition constructor parameters attribute and operator are required.") 297 | } 298 | if (values) 299 | this.values = values; 300 | } 301 | 302 | private _aggregate: Sdk.FetchXml.Aggregate = null; 303 | private _alias: string = null; 304 | private _attribute: string = null; 305 | private _column: string = null; 306 | private _entityname: string = null; 307 | private _operator: Sdk.FetchXml.Operator = null; 308 | private _rowAggregate: Sdk.FetchXml.RowAggregate = null; 309 | private _uihidden: boolean = null; 310 | private _uiname: string = null; 311 | private _uitype: string = null; 312 | private _values: Array = []; 313 | 314 | /** 315 | * Gets or sets the aggregate value to apply to the condition. 316 | */ 317 | public get aggregate(): Sdk.FetchXml.Aggregate { 318 | return this._aggregate; 319 | } 320 | public set aggregate(value: Sdk.FetchXml.Aggregate) { 321 | this._aggregate = value; 322 | } 323 | /** 324 | * Gets or sets the alias value to apply to the condition. 325 | */ 326 | public get alias(): string { 327 | return this._alias; 328 | } 329 | public set alias(value: string) { 330 | this._alias = value; 331 | } 332 | /** 333 | * Gets or sets the attribute value to apply to the condition. 334 | */ 335 | public get attribute(): string { 336 | return this._attribute; 337 | } 338 | public set attribute(value: string) { 339 | this._attribute = value; 340 | } 341 | /** 342 | * Gets or sets the column attribute value to apply to the condition. 343 | */ 344 | public get column(): string { 345 | return this._column; 346 | } 347 | public set column(value: string) { 348 | this._column = value; 349 | } 350 | /** 351 | * Gets or sets the entityname attribute value to apply to the condition. 352 | */ 353 | public get entityname(): string { 354 | return this._entityname; 355 | } 356 | public set entityname(value: string) { 357 | this._entityname = value; 358 | } 359 | /** 360 | * Gets or sets the operator attribute value to apply to the condition. 361 | */ 362 | public get operator(): Sdk.FetchXml.Operator { 363 | return this._operator; 364 | } 365 | public set operator(value: Sdk.FetchXml.Operator) { 366 | this._operator = value; 367 | } 368 | /** 369 | * Gets or sets the rowAggregate attribute value to apply to the condition. 370 | */ 371 | public get rowAggregate(): Sdk.FetchXml.RowAggregate { 372 | return this._rowAggregate; 373 | } 374 | public set rowAggregate(value: Sdk.FetchXml.RowAggregate) { 375 | this._rowAggregate = value; 376 | } 377 | /** 378 | * Gets or sets the uihidden attribute value to apply to the condition. 379 | */ 380 | public get uihidden(): boolean { 381 | return this._uihidden; 382 | } 383 | public set uihidden(value: boolean) { 384 | this._uihidden = value; 385 | } 386 | /** 387 | * Gets or sets the uiname attribute value to apply to the condition. 388 | */ 389 | public get uiname(): string { 390 | return this._uiname; 391 | } 392 | public set uiname(value: string) { 393 | this._uiname = value; 394 | } 395 | /** 396 | * Gets or sets the uitype attribute value to apply to the condition. 397 | */ 398 | public get uitype(): string { 399 | return this._uitype; 400 | } 401 | public set uitype(value: string) { 402 | this._uitype = value; 403 | } 404 | /** 405 | * Gets or sets the array of values to be applied to the query results 406 | */ 407 | public get values(): Array { 408 | return this._values; 409 | } 410 | public set values(value: Array) { 411 | if (!Sdk.FetchXml.Util.isValueArrayOrNull(value)) { 412 | throw new Error("Sdk.FetchXml.condition.values must be an array of Sdk.FetchXml.value or null.") 413 | } 414 | if (value == null) { 415 | this._values = []; 416 | } else { 417 | this._values = value; 418 | } 419 | } 420 | //Internal use only 421 | public get hash(): string { 422 | var s = this._attribute.concat(this._operator, 423 | (this._aggregate ? this._aggregate : ""), 424 | (this._alias ? this._alias : ""), 425 | (this._column ? this._column : ""), 426 | (this._entityname ? this._entityname : ""), 427 | (this._rowAggregate ? this._rowAggregate : ""), 428 | (Sdk.FetchXml.Util.isNullOrUndefined(this._uihidden) ? "" : this._uihidden.toString()), 429 | (this._uiname ? this._uiname : ""), 430 | (this._uitype ? this._uitype : ""), 431 | Sdk.FetchXml.Util.getCollectionHash(this._values) 432 | ); 433 | return s.hashCode(); 434 | } 435 | 436 | /** @description Sets the value of the condition attribute 437 | * @param {string} attribute The attribute to evaluate in the condition. 438 | * @returns {Sdk.FetchXml.condition} 439 | */ 440 | public setAttribute(attributeName) { 441 | this.attribute = attributeName; 442 | return this; 443 | } 444 | 445 | /** @description Sets the value of the condition attribute 446 | * @param {Sdk.FetchXml.Operator} operator The operator to use when evaluating the attribute. 447 | * @returns {Sdk.FetchXml.condition} 448 | */ 449 | public setOperator(operator) { 450 | this.operator = operator; 451 | return this; 452 | } 453 | 454 | /** @description Sets the value of the condition operator 455 | * @param {Array} values The the value(s) to apply in the comparison. 456 | * @returns {Sdk.FetchXml.condition} 457 | */ 458 | public setValues(values) { 459 | this.values = values; 460 | return this; 461 | } 462 | 463 | /** @description Adds a value to the values to apply in the comparison 464 | * @param {Sdk.FetchXml.value | any} value The the value to add to the values. 465 | * @returns {Sdk.FetchXml.condition} 466 | */ 467 | public addValue(value) { 468 | if (Sdk.FetchXml.Util.isValue(value)) { 469 | this.values.push(value); 470 | } 471 | else { 472 | this.values.push(new Sdk.FetchXml.value(value)); 473 | } 474 | return this; 475 | } 476 | 477 | /** @description Removes any values from the values collection by reference 478 | * @param {Sdk.FetchXml.value} value The value to remove from the values collection 479 | * @returns {Sdk.FetchXml.condition} 480 | */ 481 | public removeValueByRef(value) { 482 | if (!Sdk.FetchXml.Util.isValue(value)) { 483 | throw new Error("Sdk.FetchXml.condition removeValueByRef method value parameter must be an Sdk.FetchXml.value.") 484 | } 485 | Sdk.FetchXml.Util.removeCollectionValueByRef(this.values, value); 486 | return this; 487 | } 488 | 489 | /** @description Removes all matching values from the values collection 490 | * @param {Sdk.FetchXml.value} value The value to remove from the values collection 491 | * @returns {Sdk.FetchXml.condition} 492 | */ 493 | public removeValue(value) { 494 | if (!Sdk.FetchXml.Util.isValue(value)) { 495 | throw new Error("Sdk.FetchXml.condition removeValue method value parameter must be an Sdk.FetchXml.value.") 496 | } 497 | Sdk.FetchXml.Util.removeCollectionValue(this.values, value); 498 | return this; 499 | } 500 | 501 | /** @description Removes all any values from the values collection with the specified value property 502 | * @param {object} value The value to remove from the values collection 503 | * @returns {Sdk.FetchXml.condition} 504 | */ 505 | public removeValueByValue(value) { 506 | Sdk.FetchXml.Util.removeCollectionValueByProperty(this.values, "value", value); 507 | return this; 508 | } 509 | 510 | /** @description Sets the Aggregate to apply in the condition 511 | * @param {Sdk.FetchXml.Aggregate} aggregate The Aggregate to apply in the condition 512 | * @returns {Sdk.FetchXml.condition} 513 | */ 514 | public setAggregate(aggregate) { 515 | this.aggregate = aggregate; 516 | return this; 517 | } 518 | 519 | /** @description Sets the Alias to apply in the condition 520 | * @param {string} alias The alias to apply in the condition 521 | * @returns {Sdk.FetchXml.condition} 522 | */ 523 | public setAlias(alias) { 524 | this.alias = alias; 525 | return this; 526 | } 527 | 528 | /** @description Sets the Column to apply in the condition 529 | * @param {string} column The column to apply in the condition 530 | * @returns {Sdk.FetchXml.condition} 531 | */ 532 | public setColumn(column) { 533 | this.column = column; 534 | return this; 535 | } 536 | 537 | /** @description Sets the entityname to apply in the condition 538 | * @param {string} entityname The entityname to apply in the condition 539 | * @returns {Sdk.FetchXml.condition} 540 | */ 541 | public setEntityname(entityname) { 542 | this.entityname = entityname; 543 | return this; 544 | } 545 | 546 | /** @description Sets the rowAggregate to apply in the condition 547 | * @param {Sdk.FetchXml.RowAggregate} rowAggregate The rowAggregate to apply in the condition 548 | * @returns {Sdk.FetchXml.condition} 549 | */ 550 | public setRowAggregate(rowAggregate) { 551 | this.rowAggregate = rowAggregate; 552 | return this; 553 | } 554 | 555 | /** @description Sets the uihidden to apply in the condition 556 | * @param {boolean | null} uihidden The uihidden to apply in the condition 557 | * @returns {Sdk.FetchXml.condition} 558 | */ 559 | public setUIhidden(uihidden) { 560 | this.uihidden = uihidden; 561 | return this; 562 | } 563 | 564 | /** @description Sets the uiname to apply in the condition 565 | * @param {string} uihidden The uiname to apply in the condition 566 | * @returns {Sdk.FetchXml.condition} 567 | */ 568 | public setUIname(uiname) { 569 | this.uiname = uiname; 570 | return this; 571 | } 572 | 573 | /** @description Sets the uitype to apply in the condition 574 | * @param {string} uitype The uitype to apply in the condition 575 | * @returns {Sdk.FetchXml.condition} 576 | */ 577 | public setUItype(uitype) { 578 | this.uitype = uitype; 579 | return this; 580 | } 581 | 582 | //Internal use only 583 | toXml(doc: XMLDocument): Node { 584 | 585 | var cNode = doc.createElement("condition"); 586 | if (this.aggregate) { 587 | cNode.setAttribute("aggregate", this.aggregate) 588 | } 589 | if (this.alias) { 590 | cNode.setAttribute("alias", this.alias) 591 | } 592 | if (this.attribute) { 593 | cNode.setAttribute("attribute", this.attribute) 594 | } 595 | if (this.column) { 596 | cNode.setAttribute("column", this.column) 597 | } 598 | if (this.entityname) { 599 | cNode.setAttribute("entityname", this.entityname) 600 | } 601 | if (this.operator) { 602 | cNode.setAttribute("operator", this.operator) 603 | } 604 | if (this.rowAggregate) { 605 | cNode.setAttribute("rowAggregate", this.rowAggregate) 606 | } 607 | if (Sdk.FetchXml.Util.isBoolean(this.uihidden)) { 608 | cNode.setAttribute("uihidden", this.uihidden.toString()) 609 | } 610 | if (this.uiname) { 611 | cNode.setAttribute("uiname", this.uiname) 612 | } 613 | if (this.uitype) { 614 | cNode.setAttribute("uitype", this.uitype) 615 | } 616 | /* 617 | Note from fetch.xsd: 618 | The attribute "value" is used for all operators that compare to a single value (for example, eq). 619 | The element "value" is used for operators that compare to multiple values (for example, in). 620 | Some operators require neither the attribute "value" or the element "value" (for example, null). 621 | 622 | Groupings below are guesses and not confirmed. 623 | */ 624 | switch (this.operator) { 625 | //Operators used for single values 626 | case "begins-with": 627 | case "ends-with": 628 | case "eq": 629 | case "ge": 630 | case "gt": 631 | case "last-x-days": 632 | case "last-x-fiscal-periods": 633 | case "last-x-fiscal-years": 634 | case "last-x-hours": 635 | case "last-x-months": 636 | case "last-x-weeks": 637 | case "last-x-years": 638 | case "last-year": 639 | case "le": 640 | case "like": 641 | case "lt": 642 | case "ne": 643 | case "neq": //Is this the same as 'ne'? 644 | case "next-x-days": 645 | case "next-x-fiscal-periods": 646 | case "next-x-fiscal-years": 647 | case "next-x-hours": 648 | case "next-x-months": 649 | case "next-x-weeks": 650 | case "next-x-years": 651 | case "not-begin-with": 652 | case "not-end-with": 653 | case "not-like": 654 | case "olderthan-x-days": 655 | case "olderthan-x-hours": 656 | case "olderthan-x-minutes": 657 | case "olderthan-x-months": 658 | case "olderthan-x-weeks": 659 | case "olderthan-x-years": 660 | case "on": 661 | case "on-or-after": 662 | case "on-or-before": 663 | case "in-fiscal-period": 664 | case "in-fiscal-year": 665 | 666 | if (this.values.length == 1) { 667 | cNode.setAttribute("value", this.values[0].value) 668 | } 669 | else { 670 | var enumPropertyName = Sdk.FetchXml.Util.getEnumNameFromValue(Sdk.FetchXml.Operator, this.operator); 671 | throw new Error("Sdk.FetchXml.condition values property must contain single value when the Sdk.FetchXml.Operator." + enumPropertyName + " operator is used."); 672 | } 673 | break; 674 | //Operators used for multiple values 675 | case "between": 676 | case "in": 677 | case "not-between": 678 | case "not-in": 679 | case "in-fiscal-period-and-year": 680 | case "in-or-after-fiscal-period-and-year": 681 | case "in-or-before-fiscal-period-and-year": 682 | if (this.values.length > 1) { 683 | this.values.forEach(function (v) { 684 | cNode.appendChild(v.toXml(doc)); 685 | }) 686 | } 687 | else { 688 | var enumPropertyName = Sdk.FetchXml.Util.getEnumNameFromValue(Sdk.FetchXml.Operator, this.operator); 689 | throw new Error("Sdk.FetchXml.condition values property must contain multiple values when the Sdk.FetchXml.Operator." + enumPropertyName + " operator is used."); 690 | } 691 | break; 692 | //Operators that require no values 693 | case "above": 694 | case "eq-businessid": 695 | case "eq-or-above": 696 | case "eq-or-under": 697 | case "eq-userid": //? 698 | case "eq-userlanguage": //? 699 | case "eq-useroruserhierarchy": 700 | case "eq-useroruserhierarchyandteams": 701 | case "eq-useroruserteams": 702 | case "eq-userteams": 703 | case "last-fiscal-period": 704 | case "last-fiscal-year": 705 | case "last-month": 706 | case "last-seven-days": 707 | case "last-week": 708 | case "ne-businessid"://? 709 | case "ne-userid"://? 710 | case "next-fiscal-period": 711 | case "next-fiscal-year": 712 | case "next-month": 713 | case "next-seven-days": 714 | case "next-week": 715 | case "next-year": 716 | case "not-null": 717 | case "not-under": 718 | case "null": 719 | case "this-fiscal-period": 720 | case "this-fiscal-year": 721 | case "this-month": 722 | case "this-week": 723 | case "this-year": 724 | case "today": 725 | case "tomorrow": 726 | case "under": 727 | case "yesterday": 728 | //No value required 729 | if (this.values.length > 0) { 730 | var enumPropertyName = Sdk.FetchXml.Util.getEnumNameFromValue(Sdk.FetchXml.Operator, this.operator); 731 | console.log("Sdk.FetchXml.condition doesn't require values when the Sdk.FetchXml.Operator.%s operator is used. The values passed were ignored.", enumPropertyName); 732 | } 733 | 734 | break; 735 | default: 736 | throw new Error(this.operator + " is an unexpected Sdk.FetchXml.Operator value.") 737 | break; 738 | } 739 | 740 | 741 | return cNode; 742 | } 743 | //Internal use only 744 | static conditionFromXml(xml) { 745 | var attributeName = xml.attributes.getNamedItem("attribute").nodeValue; 746 | var operator = xml.attributes.getNamedItem("operator").nodeValue; 747 | 748 | var conditionObj = new Sdk.FetchXml.condition(attributeName, operator); 749 | 750 | Sdk.FetchXml.Util.parseAttributes(xml, conditionObj, (conditionObj, name, value) => { 751 | switch (name) { 752 | case "column": 753 | case "entityname": 754 | case "aggregate": 755 | case "alias": 756 | case "uiname": 757 | case "uitype": 758 | conditionObj[name] = value; 759 | break; 760 | case "rowaggregate": 761 | conditionObj.rowAggregate = value; 762 | break; 763 | case "uihidden": 764 | conditionObj.uihidden = Util.convertFetchBoolType(value); 765 | break; 766 | case "value": 767 | conditionObj.addValue(value); 768 | break; 769 | default: 770 | break; 771 | } 772 | }) 773 | 774 | for (var i = 0; i < xml.childNodes.length; i++) { 775 | 776 | if (xml.childNodes[i].nodeName == "value") { 777 | conditionObj.addValue(value.valueFromXml(xml.childNodes[i])); 778 | } 779 | 780 | } 781 | return conditionObj; 782 | } 783 | 784 | } 785 | @sealed 786 | export class entity { 787 | /** 788 | * Contains the data for a fetchXml entity element. 789 | * @param name The logical name of the attribute 790 | * @param [attributes] The attributes to include with the entity 791 | * @param [orders] The orders to apply to the query 792 | * @param [filters] The filters to apply to the query 793 | */ 794 | constructor(name: string, attributes?: Array, orders?: Array, filters?: Array) { 795 | if (!(this instanceof Sdk.FetchXml.entity)) 796 | { return new Sdk.FetchXml.entity(name, attributes, orders, filters) } 797 | 798 | this.name = name; 799 | if (attributes) 800 | this.attributes = attributes; 801 | if (orders) 802 | this.orders = orders; 803 | if (filters) 804 | this.filters = filters; 805 | } 806 | 807 | private _allAttributes: boolean = null; 808 | private _attributes: Array = []; 809 | private _orders: Array = []; 810 | private _linkEntities: Array = []; 811 | private _filters: Array = []; 812 | private _name: string; 813 | 814 | /** 815 | * Gets or sets whether all attributes for the entity should be returned 816 | */ 817 | public get allAttributes(): boolean { 818 | return this._allAttributes; 819 | } 820 | public set allAttributes(value: boolean) { 821 | if (!Sdk.FetchXml.Util.isBooleanOrNull(value)) { 822 | throw new Error("Sdk.FetchXml.entity.allAttributes must be a boolean value or null.") 823 | } 824 | this._allAttributes = value; 825 | } 826 | /** 827 | * Gets or sets the array of attribute of the entity to be returned in the query results 828 | */ 829 | public get attributes(): Array { 830 | return this._attributes; 831 | } 832 | public set attributes(value: Array) { 833 | if (!Sdk.FetchXml.Util.isAttributeArrayOrNull(value)) { 834 | throw new Error("Sdk.FetchXml.entity.attributes must be an array of Sdk.FetchXml.attribute or null.") 835 | } 836 | if (value == null) { 837 | this._attributes = []; 838 | } else { 839 | this._attributes = value; 840 | } 841 | 842 | } 843 | /** 844 | * Gets or sets the array of attribute of the entity to be returned in the query results 845 | */ 846 | public get orders(): Array { 847 | return this._orders; 848 | } 849 | public set orders(value: Array) { 850 | if (!Sdk.FetchXml.Util.isOrderArrayOrNull(value)) { 851 | throw new Error("Sdk.FetchXml.entity.orders must be an array of Sdk.FetchXml.order or null.") 852 | } 853 | if (value == null) { 854 | this._orders = []; 855 | } else { 856 | this._orders = value; 857 | } 858 | 859 | } 860 | /** 861 | * Gets or sets the array of related entities to be returned in the query results 862 | */ 863 | public get linkEntities(): Array { 864 | return this._linkEntities; 865 | } 866 | public set linkEntities(value: Array) { 867 | if (!Sdk.FetchXml.Util.isLinkEntityArrayOrNull(value)) { 868 | throw new Error("Sdk.FetchXml.entity.linkEntities must be an array of Sdk.FetchXml.linkEntity or null.") 869 | } 870 | if (value == null) { 871 | this._linkEntities = []; 872 | } else { 873 | this._linkEntities = value; 874 | } 875 | 876 | } 877 | /** 878 | * Gets or sets the array of filters to be applied to the query results 879 | */ 880 | public get filters(): Array { 881 | return this._filters; 882 | } 883 | public set filters(value: Array) { 884 | if (!Sdk.FetchXml.Util.isFilterArrayOrNull(value)) { 885 | throw new Error("Sdk.FetchXml.entity.filters must be an array of Sdk.FetchXml.filter or null.") 886 | } 887 | if (value == null) { 888 | this._filters = []; 889 | } else { 890 | this._filters = value; 891 | } 892 | 893 | } 894 | /** 895 | * Gets or sets the logical name of the entity 896 | */ 897 | public get name(): string { 898 | return this._name; 899 | } 900 | public set name(value: string) { 901 | if (!Sdk.FetchXml.Util.isString(value)) { 902 | throw new Error("Sdk.FetchXml.entity.name must be a string.") 903 | } 904 | this._name = value; 905 | 906 | } 907 | 908 | /** @description Adds an attribute to the attribute collection 909 | * @param {Sdk.FetchXml.attribute | string} attributeOrAttributeName the attribute or attribute name to add 910 | * @returns {Sdk.FetchXml.entity} 911 | */ 912 | public addAttribute(attributeOrAttributeName: Sdk.FetchXml.attribute | string) { 913 | if (Sdk.FetchXml.Util.isString(attributeOrAttributeName)) { 914 | 915 | // Some saved queries have duplicate attributes defined, so this is a bit more strict than it has to be. 916 | var exists = false; 917 | this.attributes.forEach(function (a) { 918 | if (a.name == attributeOrAttributeName) { 919 | exists = true; 920 | } 921 | }); 922 | if (!exists) { 923 | this.attributes.push(new Sdk.FetchXml.attribute(attributeOrAttributeName)) 924 | } 925 | return this; 926 | } 927 | if (Sdk.FetchXml.Util.isAttribute(attributeOrAttributeName)) { 928 | var exists = false; 929 | this.attributes.forEach(function (a) { 930 | if (a.name == (attributeOrAttributeName).name) { 931 | exists = true; 932 | } 933 | }); 934 | if (!exists) { 935 | this.attributes.push(attributeOrAttributeName); 936 | } 937 | } 938 | else { 939 | throw new Error("Sdk.FetchXml.entity addAttribute method attributeOrAttributeName parameter must be an Sdk.FetchXml.attribute or a string value."); 940 | } 941 | return this; 942 | } 943 | 944 | /** @description Removes an attribute from the attributes collection by name 945 | * @param {string} attributeName The name of the attribute to remove 946 | * @returns {Sdk.FetchXml.entity} 947 | */ 948 | public removeAttributeByName(attributeName: string) { 949 | Sdk.FetchXml.Util.removeCollectionValueByProperty(this.attributes, "name", attributeName) 950 | } 951 | 952 | /** @description Removes an attribute from the attributes collection by reference 953 | * @param {Sdk.FetchXml.attribute} attribute The attribute to remove 954 | * @returns {Sdk.FetchXml.entity} 955 | */ 956 | public removeAttributeByRef(attribute: Sdk.FetchXml.attribute) { 957 | Sdk.FetchXml.Util.removeCollectionValueByRef(this.attributes, attribute); 958 | } 959 | 960 | /** @description Removes an attribute from the attributes collection 961 | * @param {Sdk.FetchXml.attribute} attribute The attribute to remove 962 | * @returns {Sdk.FetchXml.entity} 963 | */ 964 | public removeAttribute(attribute: Sdk.FetchXml.attribute) { 965 | Sdk.FetchXml.Util.removeCollectionValue(this.attributes, attribute); 966 | } 967 | 968 | /** @description Adds an order to the orders collection 969 | * @param {Sdk.FetchXml.order | string} orderOrAttribute The order to add to the attributes collection or the Attribute property of a new order to create 970 | * @param {boolean} descending Whether the order is descending. True if descending, otherwise false 971 | * @param {string} alias The alias to set for the order 972 | * @returns {Sdk.FetchXml.entity} 973 | */ 974 | public addOrder(orderOrAttribute: any, descending?, alias?) { 975 | if (Sdk.FetchXml.Util.isOrder(orderOrAttribute)) { 976 | this.orders.push(orderOrAttribute); 977 | return this; 978 | } 979 | if (Sdk.FetchXml.Util.isString(orderOrAttribute)) { 980 | this.orders.push(new Sdk.FetchXml.order(orderOrAttribute, descending, alias)); 981 | } 982 | else { 983 | throw new Error("Sdk.FetchXml.entity addOrder method orderOrAttribute parameter must be a Sdk.FetchXml.order value or a string."); 984 | } 985 | return this; 986 | } 987 | 988 | /** @description Removes a order from the orders collection by reference 989 | * @param {Sdk.FetchXml.order} order The order to remove from the orders collection 990 | * @returns {Sdk.FetchXml.entity} 991 | */ 992 | public removeOrderByRef(order: Sdk.FetchXml.order) { 993 | if (!Sdk.FetchXml.Util.isOrder(order)) { 994 | throw new Error("Sdk.FetchXml.entity removeOrderByRef method order parameter must be an Sdk.FetchXml.order.") 995 | } 996 | Sdk.FetchXml.Util.removeCollectionValueByRef(this.orders, order); 997 | return this; 998 | } 999 | 1000 | /** @description Removes a order from the orders collection by value 1001 | * @param {Sdk.FetchXml.order} order The order to remove from the orders collection 1002 | * @returns {Sdk.FetchXml.entity} 1003 | */ 1004 | public removeOrder(order) { 1005 | if (!Sdk.FetchXml.Util.isOrder(order)) { 1006 | throw new Error("Sdk.FetchXml.entity removeOrder method order parameter must be an Sdk.FetchXml.order.") 1007 | } 1008 | Sdk.FetchXml.Util.removeCollectionValue(this.orders, order); 1009 | return this; 1010 | } 1011 | 1012 | /** @description Sets the name property of the entity element 1013 | * @param {string} name The name value to apply to the entity 1014 | * @returns {Sdk.FetchXml.entity} 1015 | */ 1016 | public setName(name: string) { 1017 | this.name = name; 1018 | return this; 1019 | } 1020 | 1021 | /** @description Sets the allAttributes property of the entity 1022 | * @param {boolean} [allAttributes] The allAttributes value to apply to the entity. The default is true; 1023 | * @returns {Sdk.FetchXml.entity} 1024 | */ 1025 | public setAllAttributes(allAttributes?: boolean) { 1026 | if (Sdk.FetchXml.Util.isBoolean(allAttributes)) { 1027 | this.allAttributes = allAttributes; 1028 | } 1029 | else { 1030 | if (Sdk.FetchXml.Util.isNullOrUndefined(allAttributes)) { 1031 | this.allAttributes = true; 1032 | } 1033 | else { 1034 | throw new Error("Sdk.FetchXml.entity setAllAttributes method allAttributes parameter must be a boolean value or null."); 1035 | } 1036 | } 1037 | 1038 | return this; 1039 | } 1040 | 1041 | /** @description Adds an linkEntity to the linkEntities collection 1042 | * @param {Sdk.FetchXml.linkEntity} linkEntity The linkEntity to add to the entity 1043 | * @returns {Sdk.FetchXml.entity} 1044 | */ 1045 | public addLinkEntity(linkEntity: Sdk.FetchXml.linkEntity) { 1046 | if (Sdk.FetchXml.Util.isLinkEntity(linkEntity)) { 1047 | this.linkEntities.push(linkEntity); 1048 | return this; 1049 | } 1050 | else { 1051 | throw new Error("Sdk.FetchXml.entity addLinkEntity method linkEntity parameter must be a Sdk.FetchXml.linkEntity value."); 1052 | } 1053 | return this; 1054 | } 1055 | 1056 | /** @description Removes a linkEntity from the linkEntities collection by reference 1057 | * @param {Sdk.FetchXml.linkEntity} linkEntity The linkEntity to remove from the linkEntities collection 1058 | * @returns {Sdk.FetchXml.entity} 1059 | */ 1060 | public removeLinkEntityByRef(linkEntity: Sdk.FetchXml.linkEntity) { 1061 | if (!Sdk.FetchXml.Util.isLinkEntity(linkEntity)) { 1062 | throw new Error("Sdk.FetchXml.entity removeLinkEntityByRef method linkEntity parameter must be an Sdk.FetchXml.linkEntity.") 1063 | } 1064 | Sdk.FetchXml.Util.removeCollectionValueByRef(this.linkEntities, linkEntity); 1065 | return this; 1066 | } 1067 | 1068 | /** @description Removes a linkEntity from the linkEntities collection by value 1069 | * @param {Sdk.FetchXml.linkEntity} linkEntity The linkEntity to remove from the linkEntities collection 1070 | * @returns {Sdk.FetchXml.entity} 1071 | */ 1072 | public removeLinkEntity(linkEntity: Sdk.FetchXml.linkEntity) { 1073 | if (!Sdk.FetchXml.Util.isLinkEntity(linkEntity)) { 1074 | throw new Error("Sdk.FetchXml.entity removeLinkEntity method linkEntity parameter must be an Sdk.FetchXml.linkEntity.") 1075 | } 1076 | Sdk.FetchXml.Util.removeCollectionValue(this.linkEntities, linkEntity); 1077 | return this; 1078 | } 1079 | 1080 | /** @description Adds an filter to the filters collection 1081 | * @param {Sdk.FetchXml.filter} filter The filter to add to the entity 1082 | * @returns {Sdk.FetchXml.entity} 1083 | */ 1084 | public addFilter(filter: Sdk.FetchXml.filter) { 1085 | if (Sdk.FetchXml.Util.isFilter(filter)) { 1086 | this.filters.push(filter); 1087 | return this; 1088 | } 1089 | else { 1090 | throw new Error("Sdk.FetchXml.entity addFilter method filter parameter must be a Sdk.FetchXml.filter value."); 1091 | } 1092 | return this; 1093 | } 1094 | 1095 | /** @description Removes a filter from the filters collection by reference 1096 | * @param {Sdk.FetchXml.filter} filter The filter to remove from the filters collection 1097 | * @returns {Sdk.FetchXml.entity} 1098 | */ 1099 | public removeFilterByRef(filter: Sdk.FetchXml.filter) { 1100 | if (!Sdk.FetchXml.Util.isFilter(filter)) { 1101 | throw new Error("Sdk.FetchXml.entity removeFilterByRef method filter parameter must be an Sdk.FetchXml.filter.") 1102 | } 1103 | Sdk.FetchXml.Util.removeCollectionValueByRef(this.filters, filter); 1104 | return this; 1105 | } 1106 | 1107 | /** @description Removes a filter from the filters collection by value 1108 | * @param {Sdk.FetchXml.filter} filter The filter to remove from the filters collection 1109 | * @returns {Sdk.FetchXml.entity} 1110 | */ 1111 | public removeFilter(filter: Sdk.FetchXml.filter) { 1112 | if (!Sdk.FetchXml.Util.isFilter(filter)) { 1113 | throw new Error("Sdk.FetchXml.entity removeFilter method filter parameter must be an Sdk.FetchXml.filter.") 1114 | } 1115 | Sdk.FetchXml.Util.removeCollectionValue(this.filters, filter); 1116 | return this; 1117 | } 1118 | 1119 | //internal use only 1120 | toXml(doc: XMLDocument): Node { 1121 | var entityNode = doc.createElement("entity"); 1122 | if (this.allAttributes) { 1123 | entityNode.appendChild(doc.createElement("all-attributes")); 1124 | } 1125 | else { 1126 | this.attributes.forEach(function (a, i) { 1127 | entityNode.appendChild(a.toXml(doc)); 1128 | }) 1129 | } 1130 | this.orders.forEach(function (o, i) { 1131 | entityNode.appendChild(o.toXml(doc)); 1132 | }) 1133 | 1134 | this.linkEntities.forEach(function (l, i) { 1135 | entityNode.appendChild(l.toXml(doc)); 1136 | }) 1137 | 1138 | this.filters.forEach(function (f, i) { 1139 | entityNode.appendChild(f.toXml(doc)); 1140 | }) 1141 | 1142 | //Is required so no need to check 1143 | entityNode.setAttribute("name", this.name); 1144 | 1145 | return entityNode; 1146 | } 1147 | //Internal use only 1148 | static entityFromXml(xml) { 1149 | var entityObj = new Sdk.FetchXml.entity(xml.attributes.getNamedItem("name").nodeValue); 1150 | entityObj.allAttributes = (xml.getElementsByTagName("all-attributes").length == 1); 1151 | 1152 | for (var i = 0; i < xml.childNodes.length; i++) { 1153 | 1154 | if (xml.childNodes[i].nodeName == "attribute") { 1155 | entityObj.addAttribute(attribute.attributeFromXml(xml.childNodes[i])); 1156 | } 1157 | if (xml.childNodes[i].nodeName == "order") { 1158 | 1159 | entityObj.addOrder(order.orderFromXml(xml.childNodes[i])); 1160 | } 1161 | if (xml.childNodes[i].nodeName == "link-entity") { 1162 | entityObj.addLinkEntity(linkEntity.linkEntityFromXml(xml.childNodes[i])); 1163 | } 1164 | if (xml.childNodes[i].nodeName == "filter") { 1165 | entityObj.addFilter(filter.filterFromXml(xml.childNodes[i])); 1166 | } 1167 | 1168 | } 1169 | 1170 | return entityObj; 1171 | } 1172 | 1173 | 1174 | } 1175 | @sealed 1176 | export class fetch { 1177 | 1178 | 1179 | /** 1180 | * Contains the data for a fetchXml fetch element. 1181 | * @param entity The entity that is being queried 1182 | */ 1183 | constructor(entity?: Sdk.FetchXml.entity) { 1184 | //new keyword not required 1185 | if (!(this instanceof Sdk.FetchXml.fetch)) 1186 | { return new Sdk.FetchXml.fetch(entity) } 1187 | if (entity) 1188 | this.entity = entity; 1189 | } 1190 | 1191 | private _aggregate: boolean = null; 1192 | private _count: number = null; 1193 | private _distinct: boolean = null; 1194 | private _entity: Sdk.FetchXml.entity; 1195 | private _mapping: Sdk.FetchXml.Mapping = null; 1196 | private _minActiveRowVersion: boolean = null; 1197 | private _noLock: boolean = null; 1198 | private _order: Sdk.FetchXml.order = null; 1199 | private _outputFormat: Sdk.FetchXml.OutputFormat = null; 1200 | private _page: number = null; 1201 | private _pagingCookie: string = null; 1202 | private _returnTotalRecordCount: boolean = null; 1203 | private _top: number = null; 1204 | private _utcOffset: number = null; 1205 | private _version: string = null; 1206 | 1207 | /** 1208 | * Gets or sets the aggregate attribute of the fetch element. 1209 | */ 1210 | public get aggregate(): boolean { 1211 | return this._aggregate; 1212 | } 1213 | public set aggregate(value: boolean) { 1214 | if (!Sdk.FetchXml.Util.isBooleanOrNull(value)) { 1215 | throw new Error("Sdk.FetchXml.fetch.aggregate must be a boolean value or null.") 1216 | } 1217 | this._aggregate = value; 1218 | } 1219 | /** 1220 | * Gets or sets the count attribute of the fetch element. 1221 | */ 1222 | public get count(): number { 1223 | return this._count; 1224 | } 1225 | public set count(value: number) { 1226 | if (!Sdk.FetchXml.Util.isNumberOrNull(value)) { 1227 | throw new Error("Sdk.FetchXml.fetch.count must be a number value or null.") 1228 | } 1229 | this._count = value; 1230 | } 1231 | /** 1232 | * Gets or sets the distinct attribute of the fetch element. 1233 | */ 1234 | public get distinct(): boolean { 1235 | return this._distinct; 1236 | } 1237 | public set distinct(value: boolean) { 1238 | if (!Sdk.FetchXml.Util.isBooleanOrNull(value)) { 1239 | throw new Error("Sdk.FetchXml.fetch.distinct must be a boolean value or null.") 1240 | } 1241 | this._distinct = value; 1242 | } 1243 | /** 1244 | * Gets or sets the entity attribute of the fetch element. 1245 | */ 1246 | public get entity(): Sdk.FetchXml.entity { 1247 | return this._entity; 1248 | } 1249 | public set entity(value: Sdk.FetchXml.entity) { 1250 | if (!Sdk.FetchXml.Util.isEntity(value)) { 1251 | throw new Error("Sdk.FetchXml.fetch.entity must be a Sdk.FetchXml.entity value.") 1252 | } 1253 | this._entity = value; 1254 | } 1255 | /** 1256 | * Gets or sets the mapping attribute of the fetch element. 1257 | */ 1258 | public get mapping(): Sdk.FetchXml.Mapping { 1259 | return this._mapping; 1260 | } 1261 | public set mapping(value: Sdk.FetchXml.Mapping) { 1262 | if (!Sdk.FetchXml.Util.isEnumMemberOrNull(Sdk.FetchXml.Mapping, value)) { 1263 | throw new Error("Sdk.FetchXml.fetch.mapping must be a Sdk.FetchXml.Mapping value or null.") 1264 | } 1265 | this._mapping = value; 1266 | } 1267 | /** 1268 | * Gets or sets the minActiveRowVersion attribute of the fetch element. 1269 | */ 1270 | public get minActiveRowVersion(): boolean { 1271 | return this._minActiveRowVersion; 1272 | } 1273 | public set minActiveRowVersion(value: boolean) { 1274 | if (!Sdk.FetchXml.Util.isBooleanOrNull(value)) { 1275 | throw new Error("Sdk.FetchXml.fetch.minActiveRowVersion must be a boolean value or null.") 1276 | } 1277 | this._minActiveRowVersion = value; 1278 | } 1279 | /** 1280 | * Gets or sets the noLock attribute of the fetch element. 1281 | */ 1282 | public get noLock(): boolean { 1283 | return this._noLock; 1284 | } 1285 | public set noLock(value: boolean) { 1286 | if (!Sdk.FetchXml.Util.isBooleanOrNull(value)) { 1287 | throw new Error("Sdk.FetchXml.fetch.noLock must be a boolean value or null.") 1288 | } 1289 | this._noLock = value; 1290 | } 1291 | /** 1292 | * Gets or sets the order attribute of the fetch element. 1293 | */ 1294 | public get order(): Sdk.FetchXml.order { 1295 | return this._order; 1296 | } 1297 | public set order(value: Sdk.FetchXml.order) { 1298 | if (!Sdk.FetchXml.Util.isOrderOrNull(value)) { 1299 | throw new Error("Sdk.FetchXml.fetch.order must be a Sdk.FetchXml.order value or null.") 1300 | } 1301 | this._order = value; 1302 | } 1303 | /** 1304 | * Gets or sets the outputFormat attribute of the fetch element. 1305 | */ 1306 | public get outputFormat(): Sdk.FetchXml.OutputFormat { 1307 | return this._outputFormat; 1308 | } 1309 | public set outputFormat(value: Sdk.FetchXml.OutputFormat) { 1310 | if (!Sdk.FetchXml.Util.isEnumMemberOrNull(Sdk.FetchXml.OutputFormat, value)) { 1311 | throw new Error("Sdk.FetchXml.fetch.outputFormat must be a Sdk.FetchXml.OutputFormat value or null.") 1312 | } 1313 | this._outputFormat = value; 1314 | } 1315 | /** 1316 | * Gets or sets the page attribute of the fetch element. 1317 | */ 1318 | public get page(): number { 1319 | return this._page; 1320 | } 1321 | public set page(value: number) { 1322 | if (!Sdk.FetchXml.Util.isNumberOrNull(value)) { 1323 | throw new Error("Sdk.FetchXml.fetch.page must be a number value or null.") 1324 | } 1325 | this._page = value; 1326 | } 1327 | /** 1328 | * Gets or sets the pagingCookie attribute of the fetch element. 1329 | */ 1330 | public get pagingCookie(): string { 1331 | return this._pagingCookie; 1332 | } 1333 | public set pagingCookie(value: string) { 1334 | if (!Sdk.FetchXml.Util.isStringOrNull(value)) { 1335 | throw new Error("Sdk.FetchXml.fetch.pagingCookie must be a string value or null.") 1336 | } 1337 | this._pagingCookie = value; 1338 | } 1339 | /** 1340 | * Gets or sets the returnTotalRecordCount attribute of the fetch element. 1341 | */ 1342 | public get returnTotalRecordCount(): boolean { 1343 | return this._returnTotalRecordCount; 1344 | } 1345 | public set returnTotalRecordCount(value: boolean) { 1346 | if (!Sdk.FetchXml.Util.isBooleanOrNull(value)) { 1347 | throw new Error("Sdk.FetchXml.fetch.returnTotalRecordCount must be a boolean value or null.") 1348 | } 1349 | this._returnTotalRecordCount = value; 1350 | } 1351 | /** 1352 | * Gets or sets the top attribute of the fetch element. 1353 | */ 1354 | public get top(): number { 1355 | return this._top; 1356 | } 1357 | public set top(value: number) { 1358 | if (!Sdk.FetchXml.Util.isNumberOrNull(value)) { 1359 | throw new Error("Sdk.FetchXml.fetch.top must be a number value or null.") 1360 | } 1361 | this._top = value; 1362 | } 1363 | /** 1364 | * Gets or sets the utcOffset attribute of the fetch element. 1365 | */ 1366 | public get utcOffset(): number { 1367 | return this._utcOffset; 1368 | } 1369 | public set utcOffset(value: number) { 1370 | if (!Sdk.FetchXml.Util.isNumberOrNull(value)) { 1371 | throw new Error("Sdk.FetchXml.fetch.utcOffset must be a number value or null.") 1372 | } 1373 | this._utcOffset = value; 1374 | } 1375 | /** 1376 | * Gets or sets the version attribute of the fetch element. 1377 | */ 1378 | public get version(): string { 1379 | return this._version; 1380 | } 1381 | public set version(value: string) { 1382 | if (!Sdk.FetchXml.Util.isStringOrNull(value)) { 1383 | throw new Error("Sdk.FetchXml.fetch.version must be a string value or null.") 1384 | } 1385 | this._version = value; 1386 | } 1387 | 1388 | /** @description Sets the aggregate attribute of the fetch element 1389 | * @param {boolean | null} aggregate The aggregate value to apply to the fetch element 1390 | * @returns {Sdk.FetchXml.fetch} 1391 | */ 1392 | public setAggregate(aggregate?: boolean) { 1393 | (aggregate) ? this.aggregate = aggregate : this.aggregate = null; 1394 | return this; 1395 | } 1396 | 1397 | /** @description Sets the count attribute of the fetch element 1398 | * @param {number | null} count The count value to apply to the fetch element 1399 | * @returns {Sdk.FetchXml.fetch} 1400 | */ 1401 | public setCount(count?: number) { 1402 | (count) ? this.count = count : this.count = null; 1403 | return this; 1404 | } 1405 | 1406 | /** @description Sets the distinct attribute of the fetch element 1407 | * @param {boolean | null} distinct The distinct value to apply to the fetch element 1408 | * @returns {Sdk.FetchXml.fetch} 1409 | */ 1410 | public setDistinct(distinct?: boolean) { 1411 | (distinct) ? this.distinct = distinct : this.distinct = null; 1412 | return this; 1413 | } 1414 | 1415 | /** @description Sets the aggregate entity of the fetch element 1416 | * @param {Sdk.FetchXml.entity} entity The entity value to apply to the fetch element 1417 | * @returns {Sdk.FetchXml.fetch} 1418 | */ 1419 | public setEntity(entity: Sdk.FetchXml.entity) { 1420 | this.entity = entity; 1421 | return this; 1422 | } 1423 | 1424 | /** @description Sets the mapping attribute of the fetch element 1425 | * @param {Sdk.FetchXml.Mapping} mapping The mapping value to apply to the fetch element 1426 | * @returns {Sdk.FetchXml.fetch} 1427 | */ 1428 | public setMapping(mapping?: Sdk.FetchXml.Mapping) { 1429 | (mapping) ? this.mapping = mapping : this.mapping = null; 1430 | return this; 1431 | } 1432 | 1433 | /** @description Sets the minActiveRowVersion attribute of the fetch element 1434 | * @param {boolean | null} minActiveRowVersion The minActiveRowVersion value to apply to the fetch element 1435 | * @returns {Sdk.FetchXml.fetch} 1436 | */ 1437 | public setMinActiveRowVersion(minActiveRowVersion?: boolean) { 1438 | (minActiveRowVersion) ? this.minActiveRowVersion = minActiveRowVersion : this.minActiveRowVersion = null; 1439 | return this; 1440 | } 1441 | 1442 | /** @description Sets the noLock attribute of the fetch element 1443 | * @param {boolean | null} noLock The noLock value to apply to the fetch element 1444 | * @returns {Sdk.FetchXml.fetch} 1445 | */ 1446 | public setNoLock(noLock: boolean = null) { 1447 | this.noLock = noLock; 1448 | return this; 1449 | } 1450 | 1451 | /** @description Sets the order attribute of the fetch element 1452 | * @param {Sdk.FetchXml.order | null} order The order value to apply to the fetch element 1453 | * @returns {Sdk.FetchXml.fetch} 1454 | */ 1455 | public setOrder(order: Sdk.FetchXml.order = null) { 1456 | this.order = order; 1457 | return this; 1458 | } 1459 | 1460 | /** @description Sets the outputFormat attribute of the fetch element 1461 | * @param {Sdk.FetchXml.OutputFormat | null} outputFormat The outputFormat value to apply to the fetch element 1462 | * @returns {Sdk.FetchXml.fetch} 1463 | */ 1464 | public setOutputFormat(outputFormat?: Sdk.FetchXml.OutputFormat) { 1465 | (outputFormat) ? this.outputFormat = outputFormat : this.outputFormat = null; 1466 | return this; 1467 | } 1468 | 1469 | /** @description Sets the page attribute of the fetch element 1470 | * @param {number | null} page The page value to apply to the fetch element 1471 | * @returns {Sdk.FetchXml.fetch} 1472 | */ 1473 | public setPage(page?: number) { 1474 | (page) ? this.page = page : this.page = null; 1475 | return this; 1476 | } 1477 | 1478 | /** @description Sets the pagingCookie attribute of the fetch element 1479 | * @param {string | null} pagingCookie The pagingCookie value to apply to the fetch element 1480 | * @returns {Sdk.FetchXml.fetch} 1481 | */ 1482 | public setPagingCookie(pagingCookie: string = null) { 1483 | this.pagingCookie = pagingCookie; 1484 | return this; 1485 | } 1486 | 1487 | /** @description Sets the returnTotalRecordCount attribute of the fetch element 1488 | * @param {boolean} returnTotalRecordCount The returnTotalRecordCount value to apply to the fetch element 1489 | * @returns {Sdk.FetchXml.fetch} 1490 | */ 1491 | public setReturnTotalRecordCount(returnTotalRecordCount?: boolean) { 1492 | (returnTotalRecordCount) ? this.returnTotalRecordCount = returnTotalRecordCount : this.returnTotalRecordCount = null; 1493 | return this; 1494 | } 1495 | 1496 | /** @description Sets the top attribute of the fetch element 1497 | * @param {number | null} top The top value to apply to the fetch element 1498 | * @returns {Sdk.FetchXml.fetch} 1499 | */ 1500 | public setTop(top?: number) { 1501 | (top) ? this.top = top : this.top = null; 1502 | return this; 1503 | } 1504 | 1505 | /** @description Sets the utcOffset attribute of the fetch element 1506 | * @param {number | null} utcOffset The utcOffset value to apply to the fetch element 1507 | * @returns {Sdk.FetchXml.fetch} 1508 | */ 1509 | public setUtcOffset(utcOffset?: number) { 1510 | (utcOffset) ? this.utcOffset = utcOffset : this.utcOffset = null; 1511 | return this; 1512 | } 1513 | 1514 | /** @description Sets the version attribute of the fetch element 1515 | * @param {string | null} version The version value to apply to the fetch element 1516 | * @returns {Sdk.FetchXml.fetch} 1517 | */ 1518 | public setVersion(version?: string) { 1519 | (version) ? this.version = version : this.version = null; 1520 | return this; 1521 | } 1522 | 1523 | /** 1524 | * Serializes the fetch query into a FetchXML string 1525 | */ 1526 | public toXml(): string { 1527 | 1528 | var root = ""; 1529 | var doc = new DOMParser().parseFromString(root, "text/xml"); 1530 | if (this.version) { 1531 | doc.documentElement.setAttribute("version", this.version) 1532 | } 1533 | if (this.outputFormat) { 1534 | doc.documentElement.setAttribute("output-format", this.outputFormat) 1535 | } 1536 | if (this.mapping) { 1537 | doc.documentElement.setAttribute("mapping", this.mapping) 1538 | } 1539 | if (this.aggregate) { 1540 | doc.documentElement.setAttribute("aggregate", (this.aggregate) ? "true" : "false") 1541 | } 1542 | if (this.count) { 1543 | doc.documentElement.setAttribute("count", this.count.toString()) 1544 | } 1545 | if (this.distinct) { 1546 | doc.documentElement.setAttribute("distinct", (this.distinct) ? "true" : "false") 1547 | } 1548 | if (this.entity) { 1549 | doc.documentElement.appendChild(this.entity.toXml(doc)); 1550 | } 1551 | 1552 | if (this.minActiveRowVersion) { 1553 | doc.documentElement.setAttribute("min-active-row-version", (this.minActiveRowVersion) ? "true" : "false") 1554 | } 1555 | if (this.noLock) { 1556 | doc.documentElement.setAttribute("no-lock", (this.noLock) ? "true" : "false") 1557 | } 1558 | if (this.order) { 1559 | doc.documentElement.appendChild(this.order.toXml(doc)); 1560 | } 1561 | 1562 | if (this.page) { 1563 | doc.documentElement.setAttribute("page", this.page.toString()) 1564 | } 1565 | if (this.pagingCookie) { 1566 | doc.documentElement.setAttribute("paging-cookie", this.pagingCookie) //Does this need special handling? 1567 | } 1568 | if (this.returnTotalRecordCount) { 1569 | doc.documentElement.setAttribute("returntotalrecordcount", (this.returnTotalRecordCount) ? "true" : "false") 1570 | } 1571 | if (this.top) { 1572 | doc.documentElement.setAttribute("top", this.top.toString()) 1573 | } 1574 | if (this.utcOffset) { 1575 | doc.documentElement.setAttribute("utc-offset", this.utcOffset.toString()) 1576 | } 1577 | 1578 | return new XMLSerializer().serializeToString(doc); 1579 | } 1580 | /** 1581 | * Instantiates a fetch object from a fetchXml string 1582 | * @param xml A FetchXML string 1583 | * @returns Sdk.FetchXml.fetch 1584 | */ 1585 | public static fromXml(xml: string) { 1586 | var doc = new DOMParser().parseFromString(xml, "text/xml"); 1587 | var fetchObj = new Sdk.FetchXml.fetch(); 1588 | var errorMessage = "The XML string is not a valid fetchXML document"; 1589 | 1590 | if (doc.documentElement.localName == "fetch") { 1591 | 1592 | Sdk.FetchXml.Util.parseAttributes(doc.documentElement, fetchObj, (fetchObj, name, value) => { 1593 | switch (name) { 1594 | case "count": 1595 | case "top": 1596 | case "page": 1597 | fetchObj[name] = parseInt(value, 10); 1598 | break; 1599 | case "utc-offset": 1600 | if (!isNaN(value)) { 1601 | fetchObj.utcOffset = parseInt(value, 10); 1602 | } 1603 | else { 1604 | fetchObj.utcOffset = null; 1605 | } 1606 | break; 1607 | case "paging-cookie": 1608 | fetchObj.pagingCookie = value; 1609 | break; 1610 | case "min-active-row-version": 1611 | fetchObj.minActiveRowVersion = (value == "true") ? true : false; 1612 | break; 1613 | case "output-format": 1614 | fetchObj.outputFormat = value; 1615 | break; 1616 | case "returntotalrecordcount": 1617 | fetchObj.returnTotalRecordCount = (value == "true") ? true : false; 1618 | break; 1619 | case "no-lock": 1620 | fetchObj.noLock = (value == "true") ? true : false; 1621 | break; 1622 | case "aggregate": //xs:boolean 1623 | case "distinct": 1624 | fetchObj[name] = (value == "true") ? true : false; 1625 | break; 1626 | default: 1627 | fetchObj[name] = value; 1628 | break; 1629 | } 1630 | }); 1631 | 1632 | for (var i = 0; i < doc.documentElement.childNodes.length; i++) { 1633 | 1634 | if (doc.documentElement.childNodes[i].nodeName == "entity") { 1635 | fetchObj.entity = Sdk.FetchXml.entity.entityFromXml(doc.documentElement.childNodes[i]); 1636 | } 1637 | if (doc.documentElement.childNodes[i].nodeName == "order") { 1638 | fetchObj.order = Sdk.FetchXml.order.orderFromXml(doc.documentElement.childNodes[i]); 1639 | } 1640 | } 1641 | 1642 | } 1643 | else { 1644 | throw new Error(errorMessage); 1645 | } 1646 | 1647 | return fetchObj; 1648 | } 1649 | 1650 | } 1651 | @sealed 1652 | export class filter { 1653 | /** @description Contains the data for a fetchXml filter element. 1654 | * @param [type] The type of filter: 'and' or 'or'. Default is 'and' 1655 | * @param [conditions] An array of Sdk.FetchXml.condition to apply to the filter 1656 | * @param [filters] An array of Sdk.FetchXml.filter to apply to the filter 1657 | * @property conditions Gets or sets the array of Sdk.FetchXml.condition to apply in the filter 1658 | * @property filters Gets or sets the array of Sdk.FetchXml.filter to apply to the filter 1659 | * @property type Gets or sets the type of filter. 1660 | * @property isQuickFindFields Gets or sets the isQuickFindFields property of the filter 1661 | * @returns {Sdk.FetchXml.filter} 1662 | */ 1663 | constructor(type?: string, conditions?: Array, filters?: Array) { 1664 | //new keyword is not required in JS 1665 | if (!(this instanceof filter)) 1666 | { return new filter(type, conditions, filters) } 1667 | if (type) 1668 | this.type = type; 1669 | if (conditions) 1670 | this.conditions = conditions; 1671 | if (filters) 1672 | this.filters = filters; 1673 | } 1674 | 1675 | private _conditions: Array = []; 1676 | private _filters: Array = []; 1677 | private _type: FilterType = null; 1678 | private _isQuickFindFields: boolean = null; 1679 | 1680 | /** 1681 | * Gets or sets the array of condition to be applied to the query results 1682 | */ 1683 | public get conditions(): Array { 1684 | return this._conditions; 1685 | } 1686 | public set conditions(value: Array) { 1687 | if (!Util.isFilterArrayOrNull(value)) { 1688 | throw new Error("Sdk.FetchXml.filter.conditions must be an array of Sdk.FetchXml.condition or null.") 1689 | } 1690 | if (value == null) { 1691 | this._conditions = []; 1692 | } else { 1693 | this._conditions = value; 1694 | } 1695 | } 1696 | /** 1697 | * Gets or sets the array of filters to be applied to the query results 1698 | */ 1699 | public get filters(): Array { 1700 | return this._filters; 1701 | } 1702 | public set filters(value: Array) { 1703 | if (!Util.isFilterArrayOrNull(value)) { 1704 | throw new Error("Sdk.FetchXml.filter.filters must be an array of Sdk.FetchXml.filter or null.") 1705 | } 1706 | if (value == null) { 1707 | this._filters = []; 1708 | } else { 1709 | this._filters = value; 1710 | } 1711 | } 1712 | /** 1713 | * Gets or sets the type property of the filter 1714 | */ 1715 | public get type(): FilterType { 1716 | return this._type; 1717 | } 1718 | public set type(value: FilterType) { 1719 | this._type = value; 1720 | } 1721 | /** 1722 | * Gets or sets the isQuickFindFields property of the filter 1723 | */ 1724 | public get isQuickFindFields(): boolean { 1725 | return this._isQuickFindFields; 1726 | } 1727 | public set isQuickFindFields(value: boolean) { 1728 | this._isQuickFindFields = value; 1729 | } 1730 | 1731 | /** @description Adds a condition to the conditions collection 1732 | * @param {Sdk.FetchXml.attribute | Sdk.FetchXml.condition} attributeOrCondition When Sdk.FetchXml.condition the condition is added. 1733 | When Sdk.FetchXml.attribute, the attribute property of a new condition 1734 | * @param {Sdk.FetchXml.Operator} [operator] The operator property for a new condition. Required when the first parameter is an Sdk.FetchXml.attribute 1735 | * @param {Array} [values] The values to compare for a new condition. 1736 | * @returns {Sdk.FetchXml.filter} 1737 | */ 1738 | public addCondition(attributeOrCondition: any, operator?, values?) { 1739 | if (Util.isCondition(attributeOrCondition)) { 1740 | this.conditions.push(attributeOrCondition); 1741 | } 1742 | else { 1743 | this.conditions.push(new condition(attributeOrCondition, operator, values)); 1744 | } 1745 | 1746 | return this; 1747 | } 1748 | 1749 | /** @description Removes a condition from the conditions collection by reference 1750 | * @param {Sdk.FetchXml.condition} condition The condition to remove from the conditions collection 1751 | * @returns {Sdk.FetchXml.filter} 1752 | */ 1753 | public removeConditionByRef(condition) { 1754 | if (!Util.isCondition(condition)) { 1755 | throw new Error("Sdk.FetchXml.filter removeConditionByRef method condition parameter must be an Sdk.FetchXml.condition.") 1756 | } 1757 | Util.removeCollectionValueByRef(this.conditions, condition); 1758 | 1759 | return this; 1760 | } 1761 | 1762 | /** @description Removes a condition from the conditions collection by value 1763 | * @param {Sdk.FetchXml.condition} condition The condition to remove from the conditions collection 1764 | * @returns {Sdk.FetchXml.filter} 1765 | */ 1766 | public removeCondition(condition) { 1767 | if (!Util.isCondition(condition)) { 1768 | throw new Error("Sdk.FetchXml.filter removeCondition method condition parameter must be an Sdk.FetchXml.condition.") 1769 | } 1770 | Util.removeCollectionValue(this.conditions, condition); 1771 | 1772 | return this; 1773 | } 1774 | 1775 | /** @description Adds a filter to the filters collection 1776 | * @param {Sdk.FetchXml.filter} filter The filter to add to the filters collectio 1777 | * @returns {Sdk.FetchXml.filter} 1778 | */ 1779 | public addFilter(filter) { 1780 | if (Util.isFilter(filter)) { 1781 | this.filters.push(filter); 1782 | 1783 | } else { 1784 | throw new Error("Sdk.FetchXml.filter addFilter method filter parameter must be a Sdk.FetchXml.filter value.") 1785 | } 1786 | return this; 1787 | } 1788 | 1789 | /** @description Removes all references to a filter object 1790 | * @param {Sdk.FetchXml.filter} filter The filter to remove from the filters collectio 1791 | * @returns {Sdk.FetchXml.filter} 1792 | */ 1793 | public removeFilterByRef(filter) { 1794 | if (!Util.isFilter(filter)) { 1795 | throw new Error("Sdk.FetchXml.filter removeFilterByRef method filter parameter must be an Sdk.FetchXml.filter.") 1796 | } 1797 | Util.removeCollectionValueByRef(this.filters, filter); 1798 | 1799 | return this; 1800 | } 1801 | 1802 | /** @description Removes all matching filters from the filters collection 1803 | * @param {Sdk.FetchXml.filter} filter The filter to remove from the filters collectio 1804 | * @returns {Sdk.FetchXml.filter} 1805 | */ 1806 | public removeFilter(filter) { 1807 | if (!Util.isFilter(filter)) { 1808 | throw new Error("Sdk.FetchXml.filter removeFilter method filter parameter must be an Sdk.FetchXml.filter.") 1809 | } 1810 | Util.removeCollectionValue(this.filters, filter); 1811 | 1812 | return this; 1813 | } 1814 | 1815 | /** @description Sets the isQuickFindFields property 1816 | * @param {boolean | null} value The value to set 1817 | * @returns {Sdk.FetchXml.filter} 1818 | */ 1819 | public setIsQuickFindFields(value) { 1820 | this.isQuickFindFields = value; 1821 | return this; 1822 | } 1823 | 1824 | /** @description Sets the type property 1825 | * @param {Sdk.FetchXml.FilterType} value The value to set 1826 | * @returns {Sdk.FetchXml.filter} 1827 | */ 1828 | public setType(value) { 1829 | this.type = value; 1830 | return this; 1831 | } 1832 | 1833 | //Internal use only 1834 | toXml(doc: XMLDocument): Node { 1835 | var fNode = doc.createElement("filter"); 1836 | if (this.type) { 1837 | fNode.setAttribute("type", this.type) 1838 | } 1839 | if (Util.isBoolean(this.isQuickFindFields)) { 1840 | fNode.setAttribute("isquickfindfields", this.isQuickFindFields.toString()) 1841 | } 1842 | this.conditions.forEach(function (c) { 1843 | fNode.appendChild(c.toXml(doc)); 1844 | }) 1845 | this.filters.forEach(function (f) { 1846 | fNode.appendChild(f.toXml(doc)); 1847 | }) 1848 | return fNode; 1849 | } 1850 | 1851 | static filterFromXml(xml) { 1852 | var filterObj = new filter(); 1853 | 1854 | Util.parseAttributes(xml, filterObj, (filterObj, name, value) => { 1855 | switch (name) { 1856 | case "type": 1857 | filterObj.type = value; 1858 | break; 1859 | case "isquickfindfields": 1860 | filterObj.isQuickFindFields = (value == "true" || value == "1") ? true : false; 1861 | break; 1862 | default: 1863 | break; 1864 | } 1865 | }); 1866 | 1867 | 1868 | 1869 | for (var i = 0; i < xml.childNodes.length; i++) { 1870 | 1871 | if (xml.childNodes[i].nodeName == "condition") { 1872 | filterObj.addCondition(condition.conditionFromXml(xml.childNodes[i])); 1873 | } 1874 | 1875 | if (xml.childNodes[i].nodeName == "filter") { 1876 | filterObj.addFilter(filter.filterFromXml(xml.childNodes[i])); 1877 | } 1878 | 1879 | } 1880 | 1881 | return filterObj; 1882 | } 1883 | 1884 | } 1885 | @sealed 1886 | export class linkEntity { 1887 | /** 1888 | * Contains the data for a fetchXml link-entity element. 1889 | * @param name The logical name of the entity 1890 | * @param from The from property of the linkEntity 1891 | * @param to The to property of the linkEntity 1892 | * @param linktype The linktype property of the linkEntity 1893 | * @param alias The alias property of the linkEntity 1894 | */ 1895 | constructor(name: string, from?: string, to?: string, linktype?: string, alias?: string) { 1896 | if (!(this instanceof linkEntity)) 1897 | { return new linkEntity(name, from, to, linktype, alias) } 1898 | 1899 | this.name = name; 1900 | if (from) 1901 | this.from = from; 1902 | if (to) 1903 | this.to = to; 1904 | if (linktype) 1905 | this.linktype = linktype; 1906 | if (alias) 1907 | this.alias = alias; 1908 | } 1909 | 1910 | private _name: string = null; 1911 | private _alias: string = null; 1912 | private _from: string = null; 1913 | private _intersect: boolean = null; 1914 | private _linktype: string = null; 1915 | private _to: string = null; 1916 | private _visible: boolean = null; 1917 | private _allAttributes: boolean = null; 1918 | private _attributes: Array = []; 1919 | private _orders: Array = []; 1920 | private _linkEntities: Array = []; 1921 | private _filters: Array = []; 1922 | 1923 | /** 1924 | * Gets or sets the name property of the linkEntity 1925 | */ 1926 | public get name(): string { 1927 | return this._name; 1928 | } 1929 | public set name(value: string) { 1930 | this._name = value; 1931 | } 1932 | /** 1933 | * Gets or sets the alias property of the linkEntity 1934 | */ 1935 | public get alias(): string { 1936 | return this._alias; 1937 | } 1938 | public set alias(value: string) { 1939 | this._alias = value; 1940 | } 1941 | /** 1942 | * Gets or sets the from property of the linkEntity 1943 | */ 1944 | public get from(): string { 1945 | return this._from; 1946 | } 1947 | public set from(value: string) { 1948 | this._from = value; 1949 | } 1950 | /** 1951 | * Gets or sets the intersect property of the linkEntity 1952 | */ 1953 | public get intersect(): boolean { 1954 | return this._intersect; 1955 | } 1956 | public set intersect(value: boolean) { 1957 | this._intersect = value; 1958 | } 1959 | /** 1960 | * Gets or sets the linktype property of the linkEntity 1961 | */ 1962 | public get linktype(): string { 1963 | return this._linktype; 1964 | } 1965 | public set linktype(value: string) { 1966 | this._linktype = value; 1967 | } 1968 | /** 1969 | * Gets or sets the to property of the linkEntity 1970 | */ 1971 | public get to(): string { 1972 | return this._to; 1973 | } 1974 | public set to(value: string) { 1975 | this._to = value; 1976 | } 1977 | /** 1978 | * Gets or sets the visible property of the linkEntity 1979 | */ 1980 | public get visible(): boolean { 1981 | return this._visible; 1982 | } 1983 | public set visible(value: boolean) { 1984 | this._visible = value; 1985 | } 1986 | /** 1987 | * Gets or sets the allAttributes property of the linkEntity 1988 | */ 1989 | public get allAttributes(): boolean { 1990 | return this._allAttributes; 1991 | } 1992 | public set allAttributes(value: boolean) { 1993 | this._allAttributes = value; 1994 | } 1995 | /** 1996 | * Gets or sets the array of attribute of the entity to be returned in the query results 1997 | */ 1998 | public get attributes(): Array { 1999 | return this._attributes; 2000 | } 2001 | public set attributes(value: Array) { 2002 | if (!Util.isAttributeArrayOrNull(value)) { 2003 | throw new Error("Sdk.FetchXml.linkEntity.attributes must be an array of Sdk.FetchXml.attribute or null.") 2004 | } 2005 | if (value == null) { 2006 | this._attributes = []; 2007 | } else { 2008 | this._attributes = value; 2009 | } 2010 | 2011 | } 2012 | /** 2013 | * Gets or sets the array of attribute of the entity to be returned in the query results 2014 | */ 2015 | public get orders(): Array { 2016 | return this._orders; 2017 | } 2018 | public set orders(value: Array) { 2019 | if (!Util.isOrderArrayOrNull(value)) { 2020 | throw new Error("Sdk.FetchXml.linkEntity.orders must be an array of Sdk.FetchXml.order or null.") 2021 | } 2022 | if (value == null) { 2023 | this._orders = []; 2024 | } else { 2025 | this._orders = value; 2026 | } 2027 | 2028 | } 2029 | /** 2030 | * Gets or sets the array of linkEntity to be applied to the query results 2031 | */ 2032 | public get linkEntities(): Array { 2033 | return this._linkEntities; 2034 | } 2035 | public set linkEntities(value: Array) { 2036 | if (!Util.isLinkEntityArrayOrNull(value)) { 2037 | throw new Error("Sdk.FetchXml.linkEntity.linkEntities must be an array of Sdk.FetchXml.linkEntity or null.") 2038 | } 2039 | if (value == null) { 2040 | this._linkEntities = []; 2041 | } else { 2042 | this._linkEntities = value; 2043 | } 2044 | } 2045 | /** 2046 | * Gets or sets the array of filters to be applied to the query results 2047 | */ 2048 | public get filters(): Array { 2049 | return this._filters; 2050 | } 2051 | public set filters(value: Array) { 2052 | if (!Util.isFilterArrayOrNull(value)) { 2053 | throw new Error("Sdk.FetchXml.linkEntity.filters must be an array of Sdk.FetchXml.filter or null.") 2054 | } 2055 | if (value == null) { 2056 | this._filters = []; 2057 | } else { 2058 | this._filters = value; 2059 | } 2060 | 2061 | } 2062 | //Internal use only 2063 | public get hash(): string { 2064 | var s = this._name.concat( 2065 | (this._alias ? this._alias : ""), 2066 | (this._from ? this._from : ""), 2067 | (Util.isNullOrUndefined(this._intersect) ? "" : this._intersect.toString()), 2068 | (this._linktype ? this._linktype : ""), 2069 | (this._to ? this._to : ""), 2070 | (Util.isNullOrUndefined(this._visible) ? "" : this._visible.toString()), 2071 | (Util.isNullOrUndefined(this._allAttributes) ? "" : this._allAttributes.toString()), 2072 | (Util.getCollectionHash(this._attributes)), 2073 | (Util.getCollectionHash(this._orders)), 2074 | (Util.getCollectionHash(this._linkEntities)), 2075 | (Util.getCollectionHash(this._filters)) 2076 | ); 2077 | return s.hashCode(); 2078 | } 2079 | 2080 | /** @description Sets the alias property of the linkEntity attribute 2081 | * @param {string} alias The alias value to apply to the linkEntity 2082 | * @returns {Sdk.FetchXml.linkEntity} 2083 | */ 2084 | public setAlias(alias) { 2085 | this.alias = alias; 2086 | return this; 2087 | } 2088 | 2089 | /** @description Sets the from property of the linkEntity attribute 2090 | * @param {string} from The from value to apply to the linkEntity 2091 | * @returns {Sdk.FetchXml.linkEntity} 2092 | */ 2093 | public setFrom(from) { 2094 | this.from = from; 2095 | return this; 2096 | } 2097 | 2098 | /** @description Sets the intersect property of the linkEntity attribute 2099 | * @param {boolean | null} intersect The intersect value to apply to the linkEntity 2100 | * @returns {Sdk.FetchXml.linkEntity} 2101 | */ 2102 | public setIntersect(intersect) { 2103 | this.intersect = intersect; 2104 | return this; 2105 | } 2106 | 2107 | /** @description Sets the name property of the linkEntity attribute 2108 | * @param {string} name The name value to apply to the linkEntity 2109 | * @returns {Sdk.FetchXml.linkEntity} 2110 | */ 2111 | public setName(name) { 2112 | this.name = name; 2113 | return this; 2114 | } 2115 | 2116 | /** @description Sets the to property of the linkEntity attribute 2117 | * @param {string} to The to value to apply to the linkEntity 2118 | * @returns {Sdk.FetchXml.linkEntity} 2119 | */ 2120 | public setTo(to) { 2121 | this.to = to; 2122 | return this; 2123 | } 2124 | 2125 | /** @description Sets the visible property of the linkEntity attribute 2126 | * @param {boolean | null} visible The visible value to apply to the linkEntity 2127 | * @returns {Sdk.FetchXml.linkEntity} 2128 | */ 2129 | public setVisible(visible) { 2130 | this.visible = visible; 2131 | return this; 2132 | } 2133 | 2134 | /** @description Sets the allAttributes property of the linkEntity attribute 2135 | * @param {boolean} allAttributes The allAttributes value to apply to the linkEntity 2136 | * @returns {Sdk.FetchXml.linkEntity} 2137 | */ 2138 | public setAllAttributes(allAttributes) { 2139 | this.allAttributes = allAttributes; 2140 | return this; 2141 | } 2142 | 2143 | /** @description Adds an linkEntity to the linkEntities collection 2144 | * @param {Sdk.FetchXml.linkEntity} linkEntity The linkEntity to add to the linkEntities collection 2145 | * @returns {Sdk.FetchXml.linkEntity} 2146 | */ 2147 | public addLinkEntity(linkEntity) { 2148 | if (Util.isLinkEntity(linkEntity)) { 2149 | this.linkEntities.push(linkEntity); 2150 | return this; 2151 | } 2152 | throw new Error("Sdk.FetchXml.linkEntity addLinkEntity method linkEntity parameter must be a Sdk.FetchXml.linkEntity value.") 2153 | 2154 | return this; 2155 | } 2156 | 2157 | /** @description Removes a linkEntity from the linkEntities collection by reference 2158 | * @param {Sdk.FetchXml.linkEntity} linkEntity The linkEntity to remove from the linkEntities collection 2159 | * @returns {Sdk.FetchXml.linkEntity} 2160 | */ 2161 | public removeLinkEntityByRef(linkEntity) { 2162 | if (!Util.isLinkEntity(linkEntity)) { 2163 | throw new Error("Sdk.FetchXml.linkEntity removeLinkEntityByRef method linkEntity parameter must be an Sdk.FetchXml.linkEntity.") 2164 | } 2165 | Util.removeCollectionValueByRef(this.linkEntities, linkEntity); 2166 | 2167 | return this; 2168 | } 2169 | 2170 | /** @description Removes a linkEntity from the linkEntities collection by value 2171 | * @param {Sdk.FetchXml.linkEntity} linkEntity The linkEntity to remove from the linkEntities collection 2172 | * @returns {Sdk.FetchXml.linkEntity} 2173 | */ 2174 | public removeLinkEntity(linkEntity) { 2175 | if (!Util.isLinkEntity(linkEntity)) { 2176 | throw new Error("Sdk.FetchXml.linkEntity removeLinkEntity method linkEntity parameter must be an Sdk.FetchXml.linkEntity.") 2177 | } 2178 | Util.removeCollectionValue(this.linkEntities, linkEntity); 2179 | 2180 | return this; 2181 | } 2182 | 2183 | /** @description Adds an attribute to the attributes collection 2184 | * @param {Sdk.FetchXml.attribute | string} attribute The attribute to add to the attributes collectio 2185 | * @returns {Sdk.FetchXml.linkEntity} 2186 | */ 2187 | public addAttribute(attribute) { 2188 | if (Util.isAttribute(attribute)) { 2189 | this.attributes.push(attribute); 2190 | return this; 2191 | } 2192 | if (Util.isString(attribute)) { 2193 | this.attributes.push(new attribute(attribute)); 2194 | return this; 2195 | } 2196 | throw new Error("Sdk.FetchXml.linkEntity addAttribute method attribute parameter must be a Sdk.FetchXml.attribute value or a string.") 2197 | 2198 | return this; 2199 | } 2200 | 2201 | /** @description Removes a attribute from the attributes collection by reference 2202 | * @param {Sdk.FetchXml.attribute} attribute The attribute to remove from the attributes collection 2203 | * @returns {Sdk.FetchXml.linkEntity} 2204 | */ 2205 | public removeAttributeByRef(attribute) { 2206 | if (!Util.isAttribute(attribute)) { 2207 | throw new Error("Sdk.FetchXml.linkEntity removeAttributeByRef method attribute parameter must be an Sdk.FetchXml.attribute.") 2208 | } 2209 | Util.removeCollectionValueByRef(this.attributes, attribute); 2210 | 2211 | return this; 2212 | } 2213 | 2214 | /** @description Removes a attribute from the attributes collection by value 2215 | * @param {Sdk.FetchXml.attribute} attribute The attribute to remove from the attributes collection 2216 | * @returns {Sdk.FetchXml.linkEntity} 2217 | */ 2218 | public removeAttribute(attribute) { 2219 | if (!Util.isAttribute(attribute)) { 2220 | throw new Error("Sdk.FetchXml.linkEntity removeAttribute method attribute parameter must be an Sdk.FetchXml.attribute.") 2221 | } 2222 | Util.removeCollectionValue(this.attributes, attribute); 2223 | 2224 | return this; 2225 | } 2226 | 2227 | /** @description Removes a attribute from the attributes collection by name 2228 | * @param {string} attributeName Name of the attribute to remove from the attributes collection 2229 | * @returns {Sdk.FetchXml.linkEntity} 2230 | */ 2231 | public removeAttributeByName(attributeName) { 2232 | if (!Util.isString(attributeName)) { 2233 | throw new Error("Sdk.FetchXml.linkEntity removeAttributeByName method attributeName parameter must be a string.") 2234 | } 2235 | Util.removeCollectionValueByProperty(this.attributes, "name", attributeName) 2236 | return this; 2237 | } 2238 | 2239 | /** @description Adds an order to the orders collection 2240 | * @param {Sdk.FetchXml.order | string} orderOrAttribute The order to add to the attributes collection or the Attribute property of a new order to create 2241 | * @param {boolean} [descending] Whether the order is descending. True if descending, otherwise false 2242 | * @param {string} [alias] The alias to set for the order 2243 | * @returns {Sdk.FetchXml.linkEntity} 2244 | */ 2245 | public addOrder(orderOrAttribute: any, descending?, alias?) { 2246 | if (Util.isOrder(orderOrAttribute)) { 2247 | this.orders.push(orderOrAttribute); 2248 | return this; 2249 | } 2250 | if (Util.isString(orderOrAttribute)) { 2251 | this.orders.push(new order(orderOrAttribute, descending, alias)); 2252 | return this; 2253 | } 2254 | throw new Error("Sdk.FetchXml.linkEntity addOrder method orderOrAttribute parameter must be a Sdk.FetchXml.order value or a string.") 2255 | 2256 | return this; 2257 | } 2258 | 2259 | /** @description Removes a order from the orders collection by reference 2260 | * @param {Sdk.FetchXml.order} order The order to remove from the orders collection 2261 | * @returns {Sdk.FetchXml.linkEntity} 2262 | */ 2263 | public removeOrderByRef(order) { 2264 | if (!Util.isOrder(order)) { 2265 | throw new Error("Sdk.FetchXml.linkEntity removeOrderByRef method order parameter must be an Sdk.FetchXml.order.") 2266 | } 2267 | Util.removeCollectionValueByRef(this.orders, order); 2268 | return this; 2269 | } 2270 | 2271 | /** @description Removes a order from the orders collection by value 2272 | * @param {Sdk.FetchXml.order} order The order to remove from the orders collection 2273 | * @returns {Sdk.FetchXml.linkEntity} 2274 | */ 2275 | public removeOrder(order) { 2276 | if (!Util.isOrder(order)) { 2277 | throw new Error("Sdk.FetchXml.linkEntity removeOrder method order parameter must be an Sdk.FetchXml.order.") 2278 | } 2279 | Util.removeCollectionValue(this.orders, order); 2280 | return this; 2281 | } 2282 | 2283 | /** @description Adds an filter to the filters collection 2284 | * @param {Sdk.FetchXml.filter} filter The filter to add to the filters collection 2285 | * @returns {Sdk.FetchXml.linkEntity} 2286 | */ 2287 | public addFilter(filter) { 2288 | if (Util.isFilter(filter)) { 2289 | this.filters.push(filter); 2290 | return this; 2291 | } 2292 | 2293 | throw new Error("Sdk.FetchXml.linkEntity addFilter method filter parameter must be a Sdk.FetchXml.filter value.") 2294 | 2295 | return this; 2296 | } 2297 | 2298 | /** @description Removes a filter from the filters collection by reference 2299 | * @param {Sdk.FetchXml.filter} filter The filter to remove from the filters collection 2300 | * @returns {Sdk.FetchXml.linkEntity} 2301 | */ 2302 | public removeFilterByRef(filter) { 2303 | if (!Util.isFilter(filter)) { 2304 | throw new Error("Sdk.FetchXml.linkEntity removeFilterByRef method filter parameter must be an Sdk.FetchXml.filter.") 2305 | } 2306 | Util.removeCollectionValueByRef(this.filters, filter); 2307 | 2308 | return this; 2309 | } 2310 | 2311 | /** @description Removes a filter from the filters collection by value 2312 | * @param {Sdk.FetchXml.filter} filter The filter to remove from the filters collection 2313 | * @returns {Sdk.FetchXml.linkEntity} 2314 | */ 2315 | public removeFilter(filter) { 2316 | if (!Util.isFilter(filter)) { 2317 | throw new Error("Sdk.FetchXml.linkEntity removeFilter method filter parameter must be an Sdk.FetchXml.filter.") 2318 | } 2319 | Util.removeCollectionValue(this.filters, filter); 2320 | 2321 | return this; 2322 | } 2323 | 2324 | //Internal use only 2325 | toXml(doc: XMLDocument): Node { 2326 | 2327 | var leNode = doc.createElement("link-entity"); 2328 | if (this.alias) { 2329 | leNode.setAttribute("alias", this.alias) 2330 | } 2331 | if (this.allAttributes) { 2332 | leNode.appendChild(doc.createElement("all-attributes")); 2333 | } 2334 | if (this.from) { 2335 | leNode.setAttribute("from", this.from) 2336 | } 2337 | if (Util.isBoolean(this.intersect)) { 2338 | leNode.setAttribute("intersect", this.intersect.toString()) 2339 | } 2340 | if (this.linktype) { 2341 | leNode.setAttribute("link-type", this.linktype) 2342 | } 2343 | if (this.name) { 2344 | leNode.setAttribute("name", this.name) 2345 | } 2346 | if (this.to) { 2347 | leNode.setAttribute("to", this.to) 2348 | } 2349 | if (Util.isBoolean(this.visible)) { 2350 | leNode.setAttribute("visible", this.visible.toString()) 2351 | } 2352 | this.attributes.forEach(function (a) { 2353 | leNode.appendChild(a.toXml(doc)); 2354 | }) 2355 | this.orders.forEach(function (o) { 2356 | leNode.appendChild(o.toXml(doc)); 2357 | }) 2358 | this.linkEntities.forEach(function (l) { 2359 | leNode.appendChild(l.toXml(doc)); 2360 | }) 2361 | this.filters.forEach(function (f) { 2362 | leNode.appendChild(f.toXml(doc)); 2363 | }) 2364 | 2365 | return leNode; 2366 | } 2367 | 2368 | static linkEntityFromXml(xml) { 2369 | var name = xml.attributes.getNamedItem("name").nodeValue; 2370 | var linkEntityObj = new linkEntity(name); 2371 | linkEntityObj.allAttributes = (xml.getElementsByTagName("all-attributes").length == 1); 2372 | 2373 | Util.parseAttributes(xml, linkEntityObj, (linkEntityObj, name, value) => { 2374 | switch (name) { 2375 | case "to": 2376 | case "from": 2377 | case "alias": 2378 | linkEntityObj[name] = value; 2379 | break; 2380 | case "link-type": 2381 | linkEntityObj.linktype = value; 2382 | break; 2383 | case "visible": 2384 | case "intersect": 2385 | linkEntityObj[name] = (value == "true") ? true : false; 2386 | break; 2387 | default: 2388 | break; 2389 | } 2390 | }); 2391 | 2392 | for (var i = 0; i < xml.childNodes.length; i++) { 2393 | 2394 | if (xml.childNodes[i].nodeName == "attribute") { 2395 | linkEntityObj.addAttribute(attribute.attributeFromXml(xml.childNodes[i])); 2396 | } 2397 | 2398 | if (xml.childNodes[i].nodeName == "order") { 2399 | linkEntityObj.addOrder(order.orderFromXml(xml.childNodes[i])); 2400 | } 2401 | 2402 | if (xml.childNodes[i].nodeName == "filter") { 2403 | linkEntityObj.addFilter(filter.filterFromXml(xml.childNodes[i])); 2404 | } 2405 | 2406 | if (xml.childNodes[i].nodeName == "link-entity") { 2407 | linkEntityObj.addLinkEntity(linkEntity.linkEntityFromXml(xml.childNodes[i])); 2408 | } 2409 | } 2410 | 2411 | return linkEntityObj; 2412 | } 2413 | 2414 | 2415 | } 2416 | @sealed 2417 | export class order { 2418 | /** 2419 | * Contains the data for a fetchXml order element. 2420 | * @param attribute The logical name of the attribute 2421 | * @param descending Whether the order is decending. Default is false 2422 | * @param alias The alias to apply to the order 2423 | */ 2424 | constructor(attribute?: string, descending?: boolean, alias?: string) { 2425 | // new keyword not required in JS 2426 | if (!(this instanceof order)) 2427 | { return new order(attribute, descending, alias) } 2428 | 2429 | if (attribute) 2430 | this.attribute = attribute; 2431 | if (descending) 2432 | this.descending = descending; 2433 | if (alias) 2434 | this.alias = alias; 2435 | } 2436 | 2437 | private _attribute: string = null; 2438 | private _descending: boolean = null; 2439 | private _alias: string = null; 2440 | 2441 | /** 2442 | * Gets or sets logical name of the attribute 2443 | */ 2444 | public get attribute(): string { 2445 | return this._attribute; 2446 | } 2447 | public set attribute(value: string) { 2448 | this._attribute = value; 2449 | } 2450 | /** 2451 | *Gets or sets whether the order is descending. Default is false 2452 | */ 2453 | public get descending(): boolean { 2454 | return this._descending; 2455 | } 2456 | public set descending(value: boolean) { 2457 | this._descending = value; 2458 | } 2459 | /** 2460 | * Gets or sets the alias property of the order 2461 | */ 2462 | public get alias(): string { 2463 | return this._alias; 2464 | } 2465 | public set alias(value: string) { 2466 | this._alias = value; 2467 | } 2468 | //Internal use only 2469 | public get hash(): string { 2470 | var s = "".concat( 2471 | (this._attribute ? this._attribute : ""), 2472 | (this._alias ? this._alias : ""), 2473 | this._descending.toString()); 2474 | return s.hashCode(); 2475 | } 2476 | 2477 | /** @description Sets the attribute property of the order attribute 2478 | * @param {string} attribute The attribute value to apply to the order 2479 | * @returns {Sdk.FetchXml.order} 2480 | */ 2481 | public setAttribute(attribute) { 2482 | this.attribute = attribute; 2483 | return this; 2484 | } 2485 | 2486 | /** @description Sets the alias property of the order attribute 2487 | * @param {string} alias The alias value to apply to the order 2488 | * @returns {Sdk.FetchXml.order} 2489 | */ 2490 | public setAlias(alias) { 2491 | this.alias = alias; 2492 | return this; 2493 | } 2494 | 2495 | /** @description Sets the descending property of the order attribute 2496 | * @param {boolean | null} descending The descending value to apply to the order 2497 | * @returns {Sdk.FetchXml.order} 2498 | */ 2499 | public setDescending(descending) { 2500 | this.descending = descending; 2501 | return this; 2502 | } 2503 | 2504 | //Internal use only 2505 | toXml(doc: XMLDocument): Node { 2506 | var orderNode = doc.createElement("order"); 2507 | if (this.attribute) { 2508 | orderNode.setAttribute("attribute", this.attribute) 2509 | } 2510 | if (this.alias) { 2511 | orderNode.setAttribute("alias", this.alias) 2512 | } 2513 | if (!Util.isNullOrUndefined(this.descending)) { 2514 | orderNode.setAttribute("descending", this.descending.toString()) 2515 | } 2516 | return orderNode; 2517 | } 2518 | 2519 | 2520 | static orderFromXml(xml) { 2521 | var orderObj = new order(); 2522 | Util.parseAttributes(xml, orderObj, (orderObj, name, value) => { 2523 | switch (name) { 2524 | case "attribute": 2525 | orderObj.attribute = value; 2526 | break; 2527 | case "alias": 2528 | orderObj.alias = value; 2529 | break; 2530 | case "descending": 2531 | orderObj.descending = (value == "true") ? true : false; 2532 | break; 2533 | default: 2534 | break; 2535 | } 2536 | }); 2537 | return orderObj; 2538 | } 2539 | } 2540 | @sealed 2541 | export class value { 2542 | /** 2543 | * Contains the data for a fetchXml value element. 2544 | * @param value The the value of the value 2545 | * @param [uiname] The uiname for the value 2546 | * @param [uitype] The uitype for the value 2547 | */ 2548 | constructor(value: any, uiname?: string, uitype?: string) { 2549 | //New keyword not required in JS 2550 | if (!(this instanceof Sdk.FetchXml.value)) 2551 | { return new value(value, uiname, uitype) } 2552 | 2553 | if (value) 2554 | this.value = value; 2555 | if (uiname) 2556 | this.uiname = uiname; 2557 | if (uitype) 2558 | this.uitype = uitype; 2559 | } 2560 | 2561 | private _value: any = null; 2562 | private _uiname: string = null; 2563 | private _uitype: string = null; 2564 | 2565 | 2566 | /** 2567 | * Gets or sets the value for the value. 2568 | */ 2569 | public get value(): any { 2570 | return this._value; 2571 | } 2572 | public set value(value: any) { 2573 | this._value = value; 2574 | } 2575 | /** 2576 | * Gets or sets the uiname to apply to the value 2577 | */ 2578 | public get uiname(): string { 2579 | return this._uiname; 2580 | } 2581 | public set uiname(value: string) { 2582 | this._uiname = value; 2583 | } 2584 | /** 2585 | * Gets or sets the uitype to apply to the value 2586 | */ 2587 | public get uitype(): string { 2588 | return this._uitype; 2589 | } 2590 | public set uitype(value: string) { 2591 | this._uitype = value; 2592 | } 2593 | 2594 | /** @description Sets the value to apply in the value 2595 | * @param {string} value The value to apply in the value 2596 | * @returns {Sdk.FetchXml.value} 2597 | */ 2598 | public setValue(value) { 2599 | this.value = value; 2600 | return this; 2601 | } 2602 | 2603 | /** @description Sets the uiname to apply in the value 2604 | * @param {string} uiname The uiname to apply in the value 2605 | * @returns {Sdk.FetchXml.value} 2606 | */ 2607 | public setUIname(value) { 2608 | this.uiname = value; 2609 | return this; 2610 | } 2611 | 2612 | /** @description Sets the uitype to apply in the value 2613 | * @param {string} uitype The uitype to apply in the value 2614 | * @returns {Sdk.FetchXml.value} 2615 | */ 2616 | public setUItype(value) { 2617 | this.uitype = value; 2618 | return this; 2619 | } 2620 | 2621 | //Internal use only 2622 | toXml(doc: XMLDocument): Node { 2623 | 2624 | var vNode = doc.createElement("value"); 2625 | if (this.uitype) { 2626 | vNode.setAttribute("uitype", this.uitype) 2627 | } 2628 | if (this.uiname) { 2629 | vNode.setAttribute("uiname", this.uiname) 2630 | } 2631 | vNode.appendChild(doc.createTextNode(this.value)); 2632 | return vNode; 2633 | } 2634 | 2635 | static valueFromXml(xml) { 2636 | 2637 | var valueObj = new value(xml.textContent); 2638 | Util.parseAttributes(xml, valueObj, (object, name, value) => { 2639 | switch (name) { 2640 | case "uiname": 2641 | case "uitype": 2642 | object[name] = value; 2643 | break; 2644 | } 2645 | }); 2646 | 2647 | return valueObj; 2648 | } 2649 | 2650 | } 2651 | export class Util { 2652 | public static isBoolean(obj) { 2653 | return (typeof obj === "boolean"); 2654 | } 2655 | public static isBooleanOrNull(obj) { 2656 | return (Util.isNull(obj) || Util.isBoolean(obj)) 2657 | } 2658 | public static isNumber(obj) { 2659 | return (typeof (obj) === "number"); 2660 | } 2661 | public static isNumberOrNull(obj) { 2662 | return (Util.isNull(obj) || Util.isNumber(obj)) 2663 | } 2664 | public static isNull(obj) { 2665 | return (obj === null); 2666 | } 2667 | public static isNullOrUndefined(obj) { 2668 | return (obj === null || typeof obj == "undefined"); 2669 | } 2670 | public static isEnumMember(enumType, obj) { 2671 | for (var i in enumType) { 2672 | if (obj === enumType[i]) { 2673 | return true; 2674 | } 2675 | } 2676 | return false; 2677 | } 2678 | public static isEnumMemberOrNull(enumType, obj) { 2679 | return (Util.isNull(obj) || Util.isEnumMember(enumType, obj)); 2680 | } 2681 | public static isString(obj) { 2682 | return (typeof obj === "string"); 2683 | } 2684 | public static isStringOrNull(obj) { 2685 | return (Util.isNull(obj) || Util.isString(obj)); 2686 | } 2687 | public static isOrder(obj) { 2688 | return (obj instanceof order) 2689 | } 2690 | public static isOrderOrNull(obj) { 2691 | return (Util.isNull(obj) || Util.isOrder(obj)); 2692 | } 2693 | public static isOrderArray(obj) { 2694 | if (Array.isArray(obj)) { 2695 | obj.forEach(function (item) { 2696 | if (!Util.isOrder(item)) { 2697 | return false; 2698 | } 2699 | }) 2700 | return true; 2701 | } 2702 | return false; 2703 | } 2704 | public static isOrderArrayOrNull(obj) { 2705 | return (Util.isNull(obj) || Util.isOrderArray(obj)); 2706 | } 2707 | public static isEntity(obj) { 2708 | return (obj instanceof entity) 2709 | } 2710 | public static isAttribute(obj) { 2711 | return (obj instanceof attribute) 2712 | } 2713 | public static isAttributeArray(obj) { 2714 | if (Array.isArray(obj)) { 2715 | obj.forEach(function (item) { 2716 | if (!Util.isAttribute(item)) { 2717 | return false; 2718 | } 2719 | }) 2720 | return true; 2721 | } 2722 | return false; 2723 | } 2724 | public static isAttributeArrayOrNull(obj) { 2725 | return (Util.isNull(obj) || Util.isAttributeArray(obj)); 2726 | } 2727 | public static isLinkEntity(obj) { 2728 | return (obj instanceof linkEntity) 2729 | } 2730 | public static isLinkEntityOrNull(obj) { 2731 | return (Util.isNull(obj) || Util.isLinkEntity(obj)); 2732 | } 2733 | public static isLinkEntityArray(obj) { 2734 | if (Array.isArray(obj)) { 2735 | obj.forEach(function (item) { 2736 | if (!Util.isLinkEntity(item)) { 2737 | return false; 2738 | } 2739 | }) 2740 | return true; 2741 | } 2742 | return false; 2743 | } 2744 | public static isLinkEntityArrayOrNull(obj) { 2745 | return (Util.isNull(obj) || Util.isLinkEntityArray(obj)); 2746 | } 2747 | public static isFilter(obj) { 2748 | return (obj instanceof filter) 2749 | } 2750 | public static isFilterOrNull(obj) { 2751 | return (Util.isNull(obj) || Util.isFilter(obj)); 2752 | } 2753 | public static isFilterArray(obj) { 2754 | if (Array.isArray(obj)) { 2755 | obj.forEach(function (item) { 2756 | if (!Util.isFilter(item)) { 2757 | return false; 2758 | } 2759 | }) 2760 | return true; 2761 | } 2762 | return false; 2763 | } 2764 | public static isFilterArrayOrNull(obj) { 2765 | return (Util.isNull(obj) || Util.isFilterArray(obj)); 2766 | } 2767 | public static isCondition(obj) { 2768 | return (obj instanceof condition) 2769 | } 2770 | public static isConditionOrNull(obj) { 2771 | return (Util.isNull(obj) || Util.isCondition(obj)); 2772 | } 2773 | public static isConditionArray(obj) { 2774 | if (Array.isArray(obj)) { 2775 | obj.forEach(function (item) { 2776 | if (!Util.isCondition(item)) { 2777 | return false; 2778 | } 2779 | }) 2780 | return true; 2781 | } 2782 | return false; 2783 | } 2784 | public static isConditionArrayOrNull(obj) { 2785 | return (Util.isNull(obj) || Util.isConditionArray(obj)); 2786 | } 2787 | public static isValue(obj) { 2788 | return (obj instanceof value) 2789 | } 2790 | public static isValueOrNull(obj) { 2791 | return (Util.isNull(obj) || Util.isValue(obj)); 2792 | } 2793 | public static isValueArray(obj) { 2794 | if (Array.isArray(obj)) { 2795 | var returnValue = true; 2796 | obj.forEach(function (item) { 2797 | if (!Util.isValue(item)) { 2798 | returnValue = false; 2799 | } 2800 | }) 2801 | return returnValue; 2802 | } 2803 | return false; 2804 | } 2805 | public static isValueArrayOrNull(obj) { 2806 | return (Util.isNull(obj) || Util.isValueArray(obj)); 2807 | } 2808 | public static getEnumNameFromValue(enumtype, value) { 2809 | for (var i in enumtype) { 2810 | if (enumtype[i] == value) { 2811 | return i; 2812 | } 2813 | } 2814 | } 2815 | public static getCollectionHash(collection) { 2816 | var ch = []; 2817 | collection.forEach(function (c) { 2818 | ch.push(c.hash) 2819 | }); 2820 | return ch.join(); 2821 | } 2822 | public static removeCollectionValue(collection, value) { 2823 | Util.removeCollectionValueByProperty(collection, "hash", value) 2824 | } 2825 | public static removeCollectionValueByProperty(collection, propertyName, value) { 2826 | var matches = []; 2827 | collection.forEach(function (b, i) { 2828 | //Check if same values 2829 | if (b[propertyName] == value[propertyName]) { 2830 | matches.push(b); 2831 | } 2832 | }); 2833 | matches.forEach(function (m) { 2834 | Util.removeCollectionValueByRef(collection, m); 2835 | }); 2836 | 2837 | } 2838 | public static removeCollectionValueByRef(collection, value) { 2839 | var indexes = []; 2840 | collection.forEach(function (a, i) { 2841 | //check if same object 2842 | if (a === value) { 2843 | indexes.push(i); 2844 | } 2845 | }); 2846 | if (indexes.length > 0) { 2847 | //Removing in reverse order 2848 | for (var i = indexes.length - 1; i >= 0; i--) { 2849 | collection.splice(indexes[i], 1); 2850 | } 2851 | } 2852 | } 2853 | public static convertFetchBoolType(value) { 2854 | switch (value) { 2855 | case "true": 2856 | case "1": 2857 | return true; 2858 | case "false": 2859 | case "0": 2860 | return false; 2861 | default: 2862 | throw new Error("Unexpected FetchBoolType value"); 2863 | break; 2864 | } 2865 | } 2866 | public static parseAttributes(xml: Node, object: Object, switchFunction: Function) { 2867 | var atts = xml.attributes; 2868 | for (var i = 0; i < atts.length; i++) { 2869 | var name = atts[i].nodeName; 2870 | var value = atts[i].nodeValue; 2871 | switchFunction(object, name, value) 2872 | } 2873 | } 2874 | } 2875 | @frozen 2876 | export class Mapping { 2877 | static Internal = "internal"; 2878 | static Logical = "logical"; 2879 | } 2880 | @frozen 2881 | export class OutputFormat { 2882 | static Ado = "xml-ado"; 2883 | static Auto = "xml-auto"; 2884 | static Elements = "xml-elements"; 2885 | static Raw = "xml-raw"; 2886 | static Platform = "xml-platform"; 2887 | } 2888 | @frozen 2889 | export class Build { 2890 | 2891 | static OnePoint504021 = "1.504021"; 2892 | static OnePoint003017 = "1.003017"; 2893 | } 2894 | @frozen 2895 | export class Aggregate { 2896 | static Count = "count"; 2897 | static CountColumn = "countcolumn"; 2898 | static Sum = "sum"; 2899 | static Avg = "avg"; 2900 | static Min = "min"; 2901 | static Max = "max"; 2902 | } 2903 | @frozen 2904 | export class RowAggregate { 2905 | static Countchildren = "countchildren"; 2906 | } 2907 | @frozen 2908 | export class DateGrouping { 2909 | static Day = "day"; 2910 | static Week = "week"; 2911 | static Month = "month"; 2912 | static Quarter = "quarter"; 2913 | static Year = "year"; 2914 | static FiscalPeriod = "fiscal-period"; 2915 | static FiscalYear = "fiscal-year"; 2916 | } 2917 | @frozen 2918 | export class Operator { 2919 | /** Returns all records in referenced record's hierarchical ancestry line.*/ 2920 | static Above = "above"; 2921 | /** The string occurs at the beginning of another string.*/ 2922 | static BeginsWith = "begins-with"; 2923 | /** The value is between two values.*/ 2924 | static Between = "between"; 2925 | /** The string ends with another string.*/ 2926 | static EndsWith = "ends-with"; 2927 | /** The values are compared for equality. */ 2928 | static Equal = "eq"; 2929 | /** The value is equal to the specified business ID. */ 2930 | static EqualBusinessId = "eq-businessid"; 2931 | /** Returns the referenced record and all records above it in the hierarchy.*/ 2932 | static EqualOrAbove = "eq-or-above"; 2933 | /** Returns the referenced record and all records below it in the hierarchy.*/ 2934 | static EqualOrUnder = "eq-or-under"; 2935 | /** The value is equal to the specified user ID.*/ 2936 | static EqualUserId = "eq-userid"; 2937 | /** The value is equal to the language for the user. */ 2938 | static EqualUserLanguage = "eq-userlanguage"; 2939 | /** When hierarchical security models are used; Equals current user or his reporting hierarchy*/ 2940 | static EqualUserOrUserHierarchy = "eq-useroruserhierarchy"; 2941 | /** When hierarchical security models are used; Equals current user and his teams or his reporting hierarchy and their teams*/ 2942 | static EqualUserOrUserHierarchyAndTeams = "eq-useroruserhierarchyandteams"; 2943 | /** The record is owned by a user or teams that the user is a member of.*/ 2944 | static EqualUserOrUserTeams = "eq-useroruserteams"; 2945 | /** The record is owned by teams that the user is a member of.*/ 2946 | static EqualUserTeams = "eq-userteams"; 2947 | /** The value is greater than or equal to the compared value.*/ 2948 | static GreaterOrEqual = "ge"; 2949 | /** The value is greater than the compared value.*/ 2950 | static GreaterThan = "gt"; 2951 | /** The value exists in a list of values.*/ 2952 | static In = "in"; 2953 | /** The value is within the specified fiscal period.*/ 2954 | static InFiscalPeriod = "in-fiscal-period"; 2955 | /** The value is within the specified fiscal period and year.*/ 2956 | static InFiscalPeriodAndYear = "in-fiscal-period-and-year"; 2957 | /** The value is within the specified year.*/ 2958 | static InFiscalYear = "in-fiscal-year"; 2959 | /** The value is within or after the specified fiscal period and year.*/ 2960 | static InOrAfterFiscalPeriodAndYear = "in-or-after-fiscal-period-and-year"; 2961 | /** The value is within or before the specified fiscal period and year.*/ 2962 | static InOrBeforeFiscalPeriodAndYear = "in-or-before-fiscal-period-and-year"; 2963 | /** The value is within the last fiscal period.*/ 2964 | static LastFiscalPeriod = "last-fiscal-period"; 2965 | /** The value is within the last fiscal year.*/ 2966 | static LastFiscalYear = "last-fiscal-year"; 2967 | /** The value is within the last month*/ 2968 | static LastMonth = "last-month"; 2969 | /** The value is within last seven days.*/ 2970 | static LastSevenDays = "last-seven-days"; 2971 | /** The value is within the previous week*/ 2972 | static LastWeek = "last-week"; 2973 | /** The value is within last X days.*/ 2974 | static LastXDays = "last-x-days"; 2975 | /** The value is within the last X fiscal periods.*/ 2976 | static LastXFiscalPeriods = "last-x-fiscal-periods"; 2977 | /** The value is within the last X fiscal years.*/ 2978 | static LastXFiscalYears = "last-x-fiscal-years"; 2979 | /** The value is within the last X hours.*/ 2980 | static LastXHours = "last-x-hours"; 2981 | /** The value is within the last X months.*/ 2982 | static LastXMonths = "last-x-months"; 2983 | /** The value is within the last X weeks.*/ 2984 | static LastXWeeks = "last-x-weeks"; 2985 | /** The value is within the last X years.*/ 2986 | static LastXYears = "last-x-years"; 2987 | /** The value is within the last year.*/ 2988 | static LastYear = "last-year"; 2989 | /** The value is less than or equal to the compared value.*/ 2990 | static LessOrEqual = "le"; 2991 | /** The character string is matched to the specified pattern.*/ 2992 | static Like = "like"; 2993 | /** The value is less than the compared value.*/ 2994 | static LessThan = "lt"; 2995 | /** The two values are not equal.*/ 2996 | static NotEqual = "ne"; 2997 | /** The value is not equal to the specified business ID.*/ 2998 | static NotEqualBusinessId = "ne-businessid"; 2999 | /** The value is not equal to the specified user ID.*/ 3000 | static NotEqualUserId = "ne-userid"; 3001 | /** Not Equal To*/ 3002 | static Neq = "neq"; //Is this the same as 'ne'? 3003 | /** The value is within the next fiscal period.*/ 3004 | static NextFiscalPeriod = "next-fiscal-period"; 3005 | /** The value is within the next fiscal year.*/ 3006 | static NextFiscalYear = "next-fiscal-year"; 3007 | /** The value is within the next month.*/ 3008 | static NextMonth = "next-month"; 3009 | /** The value is within the next seven days.*/ 3010 | static NextSevenDays = "next-seven-days"; 3011 | /** The value is within the next week.*/ 3012 | static NextWeek = "next-week"; 3013 | /** The value is within the X days.*/ 3014 | static NextXDays = "next-x-days"; 3015 | /** The value is within the next X fiscal periods.*/ 3016 | static NextXFiscalPeriods = "next-x-fiscal-periods"; 3017 | /** The value is within the next X fiscal years.*/ 3018 | static NextXFiscalYears = "next-x-fiscal-years"; 3019 | /** The value is within the next X hours.*/ 3020 | static NextXHours = "next-x-hours"; 3021 | /** The value is within the next X nonths.*/ 3022 | static NextXMonths = "next-x-months"; 3023 | /** The value is within the next X weeks.*/ 3024 | static NextXWeeks = "next-x-weeks"; 3025 | /** The value is within the next X years.*/ 3026 | static NextXYears = "next-x-years"; 3027 | /** The value is within the next year.*/ 3028 | static NextYear = "next-year"; 3029 | /** The string does not begin with another string.*/ 3030 | static NotBeginWith = "not-begin-with"; 3031 | /** The value is not between two values.*/ 3032 | static NotBetween = "not-between"; 3033 | /** The string does not end with another string.*/ 3034 | static NotEndWith = "not-end-with"; 3035 | /** The given value is not matched to a value in a subquery or a list.*/ 3036 | static NotIn = "not-in"; 3037 | /** The character string does not match the specified pattern.*/ 3038 | static NotLike = "not-like"; 3039 | /** The value is not null.*/ 3040 | static NotNull = "not-null"; 3041 | /** Returns all records not below the referenced record in the hierarchy*/ 3042 | static NotUnder = "not-under"; 3043 | /** The value is null.*/ 3044 | static Null = "null"; 3045 | /** The value is older than the specified number of days. */ 3046 | static OlderThanXDays = "olderthan-x-days"; 3047 | /** The value is older than the specified number of hours. */ 3048 | static OlderThanXHours = "olderthan-x-hours"; 3049 | /** The value is older than the specified number of minutes. */ 3050 | static OlderThanXMinutes = "olderthan-x-minutes"; 3051 | /** The value is older than the specified number of months. */ 3052 | static OlderThanXMonths = "olderthan-x-months"; 3053 | /** The value is older than the specified number of weeks. */ 3054 | static OlderThanXWeeks = "olderthan-x-weeks"; 3055 | /** The value is older than the specified number of years. */ 3056 | static OlderThanXYears = "olderthan-x-years"; 3057 | /** The value is on a specified date.*/ 3058 | static On = "on"; 3059 | /** The value is on or after a specified date.*/ 3060 | static OnOrAfter = "on-or-after"; 3061 | /** The value is on or before a specified date.*/ 3062 | static OnOrBefore = "on-or-before"; 3063 | /** The value is within the current fiscal period.*/ 3064 | static ThisFiscalPeriod = "this-fiscal-period"; 3065 | /** The value is within the current fiscal year.*/ 3066 | static ThisFiscalYear = "this-fiscal-year"; 3067 | /** The value is within the current month.*/ 3068 | static ThisMonth = "this-month"; 3069 | /** The value is within the current week.*/ 3070 | static ThisWeek = "this-week"; 3071 | /** The value is within the current year.*/ 3072 | static ThisYear = "this-year"; 3073 | /** The value equals today’s date.*/ 3074 | static Today = "today"; 3075 | /** The value equals tomorrow’s date.*/ 3076 | static Tomorrow = "tomorrow"; 3077 | /** Returns all child records below the referenced record in the hierarchy*/ 3078 | static Under = "under"; 3079 | /** The value equals yesterday’s date.*/ 3080 | static Yesterday = "yesterday"; 3081 | } 3082 | @frozen 3083 | export class FilterType { 3084 | static And = "and"; 3085 | static Or = "or"; 3086 | } 3087 | } 3088 | 3089 | function sealed(constructor: Function) { 3090 | Object.seal(constructor); 3091 | Object.seal(constructor.prototype); 3092 | } 3093 | function frozen(constructor: Function) { 3094 | Object.freeze(constructor); 3095 | Object.freeze(constructor.prototype); 3096 | } 3097 | 3098 | /* 3099 | Hash Generator modified from 3100 | http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery 3101 | http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/ 3102 | */ 3103 | 3104 | interface String { 3105 | hashCode: () => string; 3106 | } 3107 | 3108 | String.prototype.hashCode = function (): string { 3109 | let hash = 0; 3110 | if (this.length == 0) return hash.toString(); 3111 | for (let i = 0; i < this.length; i++) { 3112 | let char = this.charCodeAt(i); 3113 | hash = ((hash << 5) - hash) + char; 3114 | hash = hash & hash; // Convert to 32bit integer 3115 | } 3116 | return hash.toString(); 3117 | } --------------------------------------------------------------------------------