@adobe/acc-js-sdk 1.0.3 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /*
3
2
  Copyright 2020 Adobe. All rights reserved.
4
3
  This file is licensed to you under the Apache License, Version 2.0 (the "License");
@@ -10,7 +9,8 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
10
9
  OF ANY KIND, either express or implied. See the License for the specific language
11
10
  governing permissions and limitations under the License.
12
11
  */
13
-
12
+ (function() {
13
+ "use strict";
14
14
 
15
15
  /**********************************************************************************
16
16
  *
@@ -18,6 +18,8 @@ governing permissions and limitations under the License.
18
18
  *
19
19
  *********************************************************************************/
20
20
  const XtkCaster = require('./xtkCaster.js').XtkCaster;
21
+ const { Cache } = require('./cache.js');
22
+
21
23
 
22
24
  /**
23
25
  * @namespace Campaign
@@ -31,23 +33,40 @@ const XtkCaster = require('./xtkCaster.js').XtkCaster;
31
33
 
32
34
 
33
35
  /**
34
- * A in-memory cache for xtk option values. Not intended to be used directly,
35
- * but an internal cache for the Campaign.Client object
36
- *
37
36
  * @private
38
37
  * @class
39
38
  * @constructor
40
39
  * @memberof Campaign
41
40
  */
42
- class OptionCache {
41
+ class OptionCache extends Cache {
43
42
 
44
- constructor() {
45
- /**
46
- * The option values, by option name
47
- * @private
48
- * @type {Object<string,Campaign.XtkOption>}
49
- */
50
- this._optionsByName = {};
43
+ /**
44
+ * A in-memory cache for xtk option values. Not intended to be used directly,
45
+ * but an internal cache for the Campaign.Client object
46
+ *
47
+ * Cached object are made of
48
+ * - the key is the option name
49
+ * - the value is the option, a JSON object made of value, type, and rawValue properties
50
+ *
51
+ * @param {Storage} storage is an optional Storage object, such as localStorage or sessionStorage
52
+ * @param {string} rootKey is an optional root key to use for the storage object
53
+ * @param {number} ttl is the TTL for objects in ms. Defaults to 5 mins
54
+ */
55
+ constructor(storage, rootKey, ttl) {
56
+ super(storage, rootKey, ttl);
57
+ }
58
+
59
+ /**
60
+ * Cache an option and its value
61
+ * For backward compatibility purpose. Use "put" instead
62
+ *
63
+ * @deprecated
64
+ * @param {string} name is the option name
65
+ * @param {Array} rawValueAndtype a 2 elements array, whose first element is the raw option value (text serialized) and the second element
66
+ * is the data type of the option. Such an array is returned by the xtk:session#GetOption method
67
+ */
68
+ cache(schemaId, methodName) {
69
+ return this.put(schemaId, methodName);
51
70
  }
52
71
 
53
72
  /**
@@ -57,16 +76,16 @@ class OptionCache {
57
76
  * @param {Array} rawValueAndtype a 2 elements array, whose first element is the raw option value (text serialized) and the second element
58
77
  * is the data type of the option. Such an array is returned by the xtk:session#GetOption method
59
78
  */
60
- cache(name, rawValueAndtype) {
79
+ put(name, rawValueAndtype) {
61
80
  var value = null;
62
81
  var type = 0;
63
- var rawValue = undefined;
82
+ var rawValue;
64
83
  if (rawValueAndtype && rawValueAndtype[1] != 0) {
65
84
  rawValue = rawValueAndtype[0];
66
85
  type = rawValueAndtype[1];
67
86
  value = XtkCaster.as(rawValue, type);
68
87
  }
69
- this._optionsByName[name] = { value:value, type:type, rawValue:rawValue };
88
+ super.put(name, { value:value, type:type, rawValue:rawValue });
70
89
  return value;
71
90
  }
72
91
 
@@ -77,7 +96,7 @@ class OptionCache {
77
96
  * @returns {*} the option value
78
97
  */
79
98
  get(name) {
80
- const option = this._optionsByName[name];
99
+ const option = super.get(name);
81
100
  return option ? option.value : undefined;
82
101
  }
83
102
 
@@ -88,19 +107,12 @@ class OptionCache {
88
107
  * @returns {Campaign.XtkOption} the option
89
108
  */
90
109
  getOption(name) {
91
- const option = this._optionsByName[name];
92
- return option;
110
+ return super.get(name);
93
111
  }
94
-
95
- /**
96
- * Clears the cache
97
- */
98
- clear() {
99
- this._optionsByName = {};
100
- }
101
-
102
112
  }
103
113
 
104
114
 
105
115
  // Public exports
106
- exports.OptionCache = OptionCache;
116
+ exports.OptionCache = OptionCache;
117
+
118
+ })();
package/src/soap.js CHANGED
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /*
3
2
  Copyright 2020 Adobe. All rights reserved.
4
3
  This file is licensed to you under the Apache License, Version 2.0 (the "License");
@@ -10,7 +9,9 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
10
9
  OF ANY KIND, either express or implied. See the License for the specific language
11
10
  governing permissions and limitations under the License.
12
11
  */
13
-
12
+ (function() {
13
+ "use strict";
14
+
14
15
 
15
16
  /**********************************************************************************
16
17
  *
@@ -92,6 +93,8 @@ class SoapMethodCall {
92
93
  // Soap calls marked as internal are calls performed by the framework internally
93
94
  // (such as GetEntityIfMoreRecent calls needed to lookup schemas)
94
95
  this.internal = false;
96
+ // Enable soap retry
97
+ this.retry = true;
95
98
 
96
99
  this._sessionToken = sessionToken || "";
97
100
  this._securityToken = securityToken || "";
@@ -118,7 +121,8 @@ class SoapMethodCall {
118
121
  * @returns {boolean} indicates if the call requires a Logon first
119
122
  */
120
123
  requiresLogon() {
121
- const requiresLogon = !(this.urn === "xtk:session" && this.methodName === "Logon");
124
+ const requiresLogon = !(this.urn === "xtk:session" &&
125
+ (this.methodName === "Logon" || this.methodName === "BearerTokenLogon") ) ;
122
126
  return requiresLogon;
123
127
  }
124
128
 
@@ -149,22 +153,6 @@ class SoapMethodCall {
149
153
  this._method.setAttribute(`xmlns:m`, urnPath);
150
154
  this._method.setAttribute(`SOAP-ENV:encodingStyle`, encoding);
151
155
  this._data.appendChild(this._method);
152
-
153
- if (this._sessionToken) {
154
- const cookieHeader = this._doc.createElement("Cookie");
155
- cookieHeader.textContent = `__sessiontoken=${this._sessionToken}`;
156
- this._header.appendChild(cookieHeader);
157
- }
158
-
159
- const securityTokenHeader = this._doc.createElement("X-Security-Token");
160
- securityTokenHeader.textContent = this._securityToken;
161
- this._header.appendChild(securityTokenHeader);
162
-
163
- // Always write a sessiontoken element as the first parameter. Even when using SecurityToken authentication
164
- // and when the session token is actually passed implicitely as a cookie, one must write a sessiontoken
165
- // element. If not, authentication will fail because the first parameter is interpreted as the "authentication mode"
166
- // and eventually passed as the first parameter of CXtkLocalSessionPart::GetXtkSecurity
167
- this.writeString("sessiontoken", this._sessionToken);
168
156
  }
169
157
 
170
158
  /**
@@ -514,7 +502,7 @@ class SoapMethodCall {
514
502
  * @returns a boolean set to true if ther are no more response args to read
515
503
  */
516
504
  checkNoMoreArgs() {
517
- return !this.elemCurrent
505
+ return !this.elemCurrent;
518
506
  }
519
507
 
520
508
  /**
@@ -535,17 +523,55 @@ class SoapMethodCall {
535
523
  data: DomUtil.toXMLString(this._doc)
536
524
  };
537
525
  if (this._sessionToken)
538
- options.headers['Cookie'] = '__sessiontoken=' + this._sessionToken;
526
+ options.headers.Cookie = '__sessiontoken=' + this._sessionToken;
539
527
  if (this._userAgentString)
540
528
  options.headers['User-Agent'] = this._userAgentString;
541
529
  return options;
542
530
  }
543
-
531
+
544
532
  /**
545
533
  * Finalize a SOAP call just before sending
546
534
  * @param {string} url the endpoint (/nl/jsp/soaprouter.jsp)
535
+ * @param {client.Client} sdk client (optional)
547
536
  */
548
- finalize(url) {
537
+ finalize(url, client) {
538
+ if (client) {
539
+ this._sessionToken = client._sessionToken;
540
+ this._securityToken = client._securityToken;
541
+ }
542
+
543
+ var cookieHeader = DomUtil.findElement(this._header, "Cookie");
544
+ if (this._sessionToken) {
545
+ if (!cookieHeader) {
546
+ cookieHeader = this._doc.createElement("Cookie");
547
+ this._header.appendChild(cookieHeader);
548
+ }
549
+ cookieHeader.textContent = `__sessiontoken=${this._sessionToken}`;
550
+ } else if (cookieHeader) {
551
+ cookieHeader.remove();
552
+ }
553
+
554
+ var securityTokenHeader = DomUtil.findElement(this._header, "X-Security-Token");
555
+ if (!securityTokenHeader) {
556
+ securityTokenHeader = this._doc.createElement("X-Security-Token");
557
+ this._header.appendChild(securityTokenHeader);
558
+ }
559
+ securityTokenHeader.textContent = this._securityToken;
560
+
561
+ // Always write a sessiontoken element as the first parameter. Even when using SecurityToken authentication
562
+ // and when the session token is actually passed implicitely as a cookie, one must write a sessiontoken
563
+ // element. If not, authentication will fail because the first parameter is interpreted as the "authentication mode"
564
+ // and eventually passed as the first parameter of CXtkLocalSessionPart::GetXtkSecurity
565
+ var sessionTokenElem = DomUtil.findElement(this._method, "sessiontoken");
566
+ if (sessionTokenElem) {
567
+ sessionTokenElem.textContent = this._sessionToken;
568
+ } else {
569
+ sessionTokenElem = this._doc.createElement("sessiontoken");
570
+ sessionTokenElem.setAttribute("xsi:type", "xsd:string");
571
+ // sessionTokenElem.setAttribute("SOAP-ENV:encodingStyle", SOAP_ENCODING_NATIVE);
572
+ sessionTokenElem.textContent = this._sessionToken;
573
+ this._method.prepend(sessionTokenElem);
574
+ }
549
575
  const options = this._createHTTPRequest(url);
550
576
  // Prepare request and empty response objects
551
577
  this.request = options;
@@ -563,6 +589,8 @@ class SoapMethodCall {
563
589
  const that = this;
564
590
  const promise = this._transport(this.request);
565
591
  return promise.then(function(body) {
592
+ if (body.indexOf(`XSV-350008`) != -1)
593
+ throw CampaignException.SESSION_EXPIRED();
566
594
  that.response = body;
567
595
  // Response is a serialized XML document with the following structure
568
596
  //
@@ -636,3 +664,5 @@ class SoapMethodCall {
636
664
 
637
665
  // Public exports
638
666
  exports.SoapMethodCall = SoapMethodCall;
667
+
668
+ })();
package/src/transport.js CHANGED
@@ -9,6 +9,8 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
9
9
  OF ANY KIND, either express or implied. See the License for the specific language
10
10
  governing permissions and limitations under the License.
11
11
  */
12
+ (function() {
13
+ "use strict";
12
14
 
13
15
  const { Util } = require('./util.js');
14
16
 
@@ -70,9 +72,8 @@ if (!Util.isBrowser()) {
70
72
  return Promise.reject(new HttpError(500, error ? error.toString() : undefined));
71
73
  // HTTP errors (400, 404, 500, etc.) are returned here
72
74
  return Promise.reject(new HttpError(response.status, response.statusText, response.data));
73
- })
74
- }
75
-
75
+ });
76
+ };
76
77
 
77
78
  exports.request = request;
78
79
  exports.HttpError = HttpError;
@@ -107,13 +108,16 @@ if (!Util.isBrowser()) {
107
108
  return blob.text();
108
109
  });
109
110
  }).catch((ex) => {
110
- if (ex.__proto__.constructor.name == "HttpError")
111
+ const proto = Object.getPrototypeOf(ex);
112
+ if (proto.constructor.name == "HttpError")
111
113
  throw ex;
112
114
  throw new HttpError(ex.status, ex.statusText);
113
- })
115
+ });
114
116
  return p;
115
- }
117
+ };
116
118
 
117
119
  module.exports.request = request;
118
120
 
119
- }
121
+ }
122
+
123
+ })();
package/src/util.js CHANGED
@@ -1,5 +1,3 @@
1
- "use strict";
2
-
3
1
  /*
4
2
  Copyright 2020 Adobe. All rights reserved.
5
3
  This file is licensed to you under the Apache License, Version 2.0 (the "License");
@@ -11,7 +9,9 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
11
9
  OF ANY KIND, either express or implied. See the License for the specific language
12
10
  governing permissions and limitations under the License.
13
11
  */
14
-
12
+ (function() {
13
+ "use strict";
14
+
15
15
 
16
16
  /**********************************************************************************
17
17
  *
@@ -20,83 +20,122 @@ governing permissions and limitations under the License.
20
20
  *********************************************************************************/
21
21
 
22
22
  /**
23
- * @namespace Campaign
23
+ * @namespace Utils
24
24
  */
25
25
 
26
26
  /**
27
- * Helpers for common manipulation of DOM documents
28
- * @memberof Campaign
27
+ * @memberof Utils
29
28
  * @class
30
29
  * @constructor
31
30
  */
32
31
  class Util {
33
32
 
34
- static isBrowser() {
35
- const browser = typeof window !== 'undefined';
36
- return browser;
37
- }
38
-
39
- static isArray(o) {
40
- if (o === null || o === undefined) return false;
41
- // JavaScript arrays are objects
42
- if (typeof o != "object") return false;
43
- // They also have a length property. But checking the length is not enough
44
- // since, it can also be an object litteral with a "length" property. Campaign
45
- // schema attributes typically have a "length" attribute and are not arrays
46
- if (o.length === undefined || o.length === null) return false;
47
- // So check for a "push" function
48
- if (o.push === undefined || o.push === null) return false;
49
- if (typeof o.push != "function")
50
- return false;
51
- return true;
52
- }
33
+ /**
34
+ * Generic helper functions available everywhere in the SDK. Al functions are static, it is not necessary to create new instances of this object
35
+ */
36
+ constructor() {
37
+ }
53
38
 
39
+ /**
40
+ * Indicates whether the SDK is running in a browser or not
41
+ * @returns {boolean} a boolean indicating if the SDK is running in a browser or not
42
+ */
43
+ static isBrowser() {
44
+ const browser = typeof window !== 'undefined';
45
+ return browser;
46
+ }
47
+
48
+ /**
49
+ * Tests if an object is a JavaScript array
50
+ * @param {*} obj the object to test, may be undefined
51
+ * @returns {boolean} true if the object is an array
52
+ */
53
+ static isArray(obj) {
54
+ if (obj === null || obj === undefined) return false;
55
+ // JavaScript arrays are objects
56
+ if (typeof obj != "object") return false;
57
+ // They also have a length property. But checking the length is not enough
58
+ // since, it can also be an object litteral with a "length" property. Campaign
59
+ // schema attributes typically have a "length" attribute and are not arrays
60
+ if (obj.length === undefined || obj.length === null) return false;
61
+ // So check for a "push" function
62
+ if (obj.push === undefined || obj.push === null) return false;
63
+ if (typeof obj.push != "function")
64
+ return false;
65
+ return true;
66
+ }
54
67
 
55
- static _removeBetween(text, from, to) {
56
- var index = 0;
57
- while (index < text.length) {
58
- index = text.indexOf(from, index);
59
- if (index == -1) break;
60
- const index2 = text.indexOf(to, index);
61
- if (index2 == -1) {
62
- break;
63
- }
64
- text = text.substring(0, index + from.length) + '***' + text.substring(index2);
65
- index = index2;
66
- }
67
- return text;
68
+ // Helper function for trim() to replace text between 2 indices
69
+ static _removeBetween(text, from, to) {
70
+ var index = 0;
71
+ while (index < text.length) {
72
+ index = text.indexOf(from, index);
73
+ if (index == -1) break;
74
+ const index2 = text.indexOf(to, index);
75
+ if (index2 == -1) {
76
+ break;
68
77
  }
69
-
70
- static trim(text) {
71
- if (text == null || text == undefined) return undefined;
72
- if (Util.isArray(text)) {
73
- const a = [];
74
- for (const p of text) {
75
- a.push(Util.trim(p));
76
- }
77
- return a;
78
- }
79
- if (typeof text == "object") {
80
- for (const p in text) {
81
- text[p] = Util.trim(text[p]);
78
+ text = text.substring(0, index + from.length) + '***' + text.substring(index2);
79
+ index = index2;
80
+ }
81
+ return text;
82
+ }
83
+
84
+ /**
85
+ * Trims a text, an object or an array and remove sensitive information, such as session tokens, passwords, etc.
86
+ *
87
+ * @param {string|Object|Array} obj is the object to trim
88
+ * @returns {string|Object|Array} the trimmed object
89
+ */
90
+ static trim(obj) {
91
+ if (obj == null || obj == undefined) return undefined;
92
+ if (Util.isArray(obj)) {
93
+ const a = [];
94
+ for (const p of obj) {
95
+ a.push(Util.trim(p));
96
+ }
97
+ return a;
98
+ }
99
+ if (typeof obj == "object") {
100
+ for (const p in obj) {
101
+ if (p.toLowerCase() === "x-security-token")
102
+ obj[p] = "***";
103
+ else if (p === "Cookie") {
104
+ var index = obj[p].toLowerCase().indexOf("__sessiontoken");
105
+ if (index !== -1) {
106
+ index = obj[p].indexOf("=", index);
107
+ if (index !== -1) {
108
+ index = index + 1;
109
+ const endIndex = obj[p].indexOf(";", index);
110
+ if (endIndex == -1)
111
+ obj[p] = obj[p].substring(0, index) + "***";
112
+ else
113
+ obj[p] = obj[p].substring(0, index) + "***" + obj[p].substring(endIndex);
114
+ }
82
115
  }
83
116
  }
84
- if (typeof text == "string") {
85
- // Remove trailing blanks
86
- while (text && (text.endsWith(' ') || text.endsWith('\n') || text.endsWith('\r') || text.endsWith('\t')))
87
- text = text.substring(0, text.length - 1);
88
-
89
- // Hide session tokens
90
- text = this._removeBetween(text, "<Cookie>__sessiontoken=", "</Cookie>");
91
- text = this._removeBetween(text, "<X-Security-Token>", "</X-Security-Token>");
92
- text = this._removeBetween(text, '<sessiontoken xsi:type="xsd:string">', '</sessiontoken>');
93
- text = this._removeBetween(text, "<pstrSessionToken xsi:type='xsd:string'>", "</pstrSessionToken>");
94
- text = this._removeBetween(text, "<pstrSecurityToken xsi:type='xsd:string'>", "</pstrSecurityToken>");
95
- }
96
- return text;
117
+ else
118
+ obj[p] = Util.trim(obj[p]);
97
119
  }
120
+ }
121
+ if (typeof obj == "string") {
122
+ // Remove trailing blanks
123
+ while (obj && (obj.endsWith(' ') || obj.endsWith('\n') || obj.endsWith('\r') || obj.endsWith('\t')))
124
+ obj = obj.substring(0, obj.length - 1);
98
125
 
126
+ // Hide session tokens
127
+ obj = this._removeBetween(obj, "<Cookie>__sessiontoken=", "</Cookie>");
128
+ obj = this._removeBetween(obj, "<X-Security-Token>", "</X-Security-Token>");
129
+ obj = this._removeBetween(obj, '<sessiontoken xsi:type="xsd:string">', '</sessiontoken>');
130
+ obj = this._removeBetween(obj, "<pstrSessionToken xsi:type='xsd:string'>", "</pstrSessionToken>");
131
+ obj = this._removeBetween(obj, "<pstrSecurityToken xsi:type='xsd:string'>", "</pstrSecurityToken>");
132
+ obj = this._removeBetween(obj, '<password xsi:type="xsd:string">', '</password>');
133
+ }
134
+ return obj;
135
+ }
99
136
  }
100
137
 
101
138
  // Public expots
102
139
  exports.Util = Util;
140
+
141
+ })();
package/src/xtkCaster.js CHANGED
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /*
3
2
  Copyright 2020 Adobe. All rights reserved.
4
3
  This file is licensed to you under the Apache License, Version 2.0 (the "License");
@@ -10,7 +9,10 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
10
9
  OF ANY KIND, either express or implied. See the License for the specific language
11
10
  governing permissions and limitations under the License.
12
11
  */
12
+ (function() {
13
+ "use strict";
13
14
 
15
+ const { Util } = require('./util.js');
14
16
 
15
17
  /**********************************************************************************
16
18
  *
@@ -37,11 +39,15 @@ governing permissions and limitations under the License.
37
39
  | Xtk type | | JS type | Comment |
38
40
  | ------------ |----|-------- | --- |
39
41
  | string | 6 | string | never null, defaults to "" |
40
- | memo | 12 | string |
41
- | CDATA | 13 | string |
42
+ | memo | 12 | string | large strings. Never null, defaults to ""
43
+ | CDATA | 13 | string | string in the CDATA section of an XML document. Never null, defaults to ""
44
+ | uuid | | string |
45
+ | blob | | string |
46
+ | html | | string |
42
47
  | byte | 1 | number | signed integer in the [-128, 128[ range. Never null, defaults to 0 |
43
48
  | short | 2 | number | signed 16 bits integer in the [-32768, 32768[ range. Never null, defaults to 0 |
44
49
  | long | 3 | number | signed 32 bits integer. Never null, defaults to 0 |
50
+ | int | | number | signed 32 bits integer. Never null, defaults to 0 |
45
51
  | int64 | | string | signed 64 bits integer. As JavaScript handles all numbers as doubles, it's not possible to properly represent an int64 as a number, and it's therefore represented as a string.
46
52
  | float | 4 | number | single-percision numeric value. Never null, defaults to 0 |
47
53
  | double | 5 | number | single-percision numeric value. Never null, defaults to 0 |
@@ -49,22 +55,24 @@ governing permissions and limitations under the License.
49
55
  | datetimetz | | | |
50
56
  | datetimenotz | | | |
51
57
  | date | 10 | Date | UTC timestamp with day precision. Can be null |
58
+ | timespan | 14 | number | A timespan, in seconds
52
59
  | boolean | 15 | boolean | boolean value, defaultint to false. Cannot be null |
53
- | timespan | | | |
60
+ | array | | Array | a array or a collection
54
61
 
55
- * @typedef {(0|''|6|'string'|'int64'|12|13|'memo'|'CDATA'|1|'byte'|2|'short'|3|'long'|15|'boolean'|4|5|'float'|'double'|7|'datetime'|'datetimetz'|'datetimenotz'|10|'date')} XtkType
62
+ * @typedef {(0|''|6|'string'|'int64'|12|13|'memo'|'CDATA'|1|'byte'|2|'short'|3|'long'|15|'boolean'|4|5|'float'|'double'|7|'datetime'|'datetimetz'|'datetimenotz'|10|'date'|14|'timespan'|'array')} XtkType
56
63
  * @memberof Campaign
57
64
  */
58
65
 
59
- /**
60
- * Helpers to convert between JavaScript data types and Campaign XTK data types
61
- *
66
+ /**
62
67
  * @memberof Campaign
63
68
  * @class
64
69
  * @constructor
65
70
  */
66
71
  class XtkCaster {
67
72
 
73
+ /**
74
+ * Helpers to convert between JavaScript data types and Campaign XTK data types
75
+ */
68
76
  constructor() {
69
77
  }
70
78
 
@@ -84,10 +92,13 @@ class XtkCaster {
84
92
  return null;
85
93
  case 6: // FIELD_SZ
86
94
  case "string":
95
+ case "uuid":
87
96
  case "int64":
88
97
  return "stringValue";
89
98
  case 12: // FIELD_MEMO
90
99
  case 13: // FIELD_MEMOSHORT
100
+ case "blob":
101
+ case "html":
91
102
  case "memo":
92
103
  case "CDATA":
93
104
  return "memoValue";
@@ -96,8 +107,10 @@ class XtkCaster {
96
107
  case 2: // FIELD_SHORT
97
108
  case "short":
98
109
  case 3: // FIELD_LONG
110
+ case "int":
99
111
  case "long":
100
- case 15: // FIELD_BOOLEAN
112
+ case "timespan":
113
+ case 15: // FIELD_BOOLEAN
101
114
  case "boolean":
102
115
  return "longValue";
103
116
  case 4: // FIELD_FLOAT
@@ -111,7 +124,7 @@ class XtkCaster {
111
124
  case "datetimenotz":
112
125
  case 10: // FIELD_DATE
113
126
  case "date":
114
- return "timeStampValue"
127
+ return "timeStampValue";
115
128
  default: {
116
129
  throw CampaignException.BAD_PARAMETER("type", type, `Cannot get variant storage attribute name for type '${type}'`);
117
130
  }
@@ -136,6 +149,9 @@ class XtkCaster {
136
149
  case 13: // FIELD_MEMOSHORT
137
150
  case "string":
138
151
  case "memo":
152
+ case "uuid":
153
+ case "blob":
154
+ case "html":
139
155
  case "CDATA": {
140
156
  return this.asString(value);
141
157
  }
@@ -148,6 +164,7 @@ class XtkCaster {
148
164
  return this.asShort(value);
149
165
  }
150
166
  case 3: // FIELD_LONG
167
+ case "int":
151
168
  case "long": {
152
169
  return this.asLong(value);
153
170
  }
@@ -174,6 +191,13 @@ class XtkCaster {
174
191
  case "date": {
175
192
  return this.asDate(value);
176
193
  }
194
+ case "array": {
195
+ return this.asArray(value);
196
+ }
197
+ case 14: // FIELD_TIMESPAN
198
+ case "timespan": {
199
+ return this.asTimespan(value);
200
+ }
177
201
  default: {
178
202
  throw CampaignException.BAD_PARAMETER("type", type, `Cannot convert value type='${type}', value='${value}'`);
179
203
  }
@@ -353,7 +377,7 @@ class XtkCaster {
353
377
  }
354
378
 
355
379
  /**
356
- * Convert a raw value into a date. This is a UTC timestamp where time fields are 0
380
+ * Convert a raw value into a date. This is a UTC timestamp where time fields are 0
357
381
  *
358
382
  * @param {*} value is the raw value to convert
359
383
  * @return {Date} a date
@@ -368,6 +392,37 @@ class XtkCaster {
368
392
  }
369
393
  return timestamp;
370
394
  }
395
+
396
+ /**
397
+ * Convert a raw value into an array (if it is not an array yet). Null and undefined will be
398
+ * converted into an empty array
399
+ *
400
+ * @param {*} value is the raw value to convert
401
+ * @return {Array} a array
402
+ */
403
+ static asArray(value) {
404
+ if (value === null || value === undefined) return [];
405
+ if (Util.isArray(value)) return value;
406
+ return [value];
407
+ }
408
+
409
+ /**
410
+ * Convert a raw value into a timespan, in seconds
411
+ * @param {*} value is the raw value to convert
412
+ * @returns is the time span, in seconds
413
+ */
414
+ static asTimespan(value) {
415
+ if (value === null || value === undefined) return 0;
416
+ if ((typeof value) == "string") value = value.trim();
417
+ if (value === "" || value === true || value === false) return 0;
418
+ if (value !== value || value === Number.POSITIVE_INFINITY || value === Number.NEGATIVE_INFINITY) return 0;
419
+ // Number to timespan -> Consider as number of seconds
420
+ var timespan = XtkCaster.asLong(value);
421
+ return timespan;
422
+ }
423
+
371
424
  }
372
425
 
373
426
  exports.XtkCaster = XtkCaster;
427
+
428
+ })();