@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.
- package/.github/workflows/codeql-analysis.yml +70 -0
- package/.vscode/launch.json +0 -1
- package/CHANGELOG.md +37 -1
- package/README.md +63 -3
- package/compile.js +2 -0
- package/package-lock.json +2438 -3367
- package/package.json +10 -7
- package/samples/002 - basics - schemas.js +3 -3
- package/samples/020 - encryption.js +5 -5
- package/src/application.js +66 -5
- package/src/cache.js +275 -0
- package/src/campaign.js +35 -22
- package/src/client.js +246 -125
- package/src/crypto.js +5 -2
- package/src/domUtil.js +53 -20
- package/src/entityAccessor.js +4 -2
- package/src/index.js +107 -105
- package/src/methodCache.js +55 -46
- package/src/optionCache.js +40 -28
- package/src/soap.js +53 -23
- package/src/transport.js +11 -7
- package/src/util.js +103 -64
- package/src/xtkCaster.js +66 -11
- package/src/xtkEntityCache.js +42 -24
- package/test/application.test.js +40 -1
- package/test/caches.test.js +214 -14
- package/test/client.test.js +485 -30
- package/test/crypto.test.js +16 -12
- package/test/domUtil.test.js +23 -0
- package/test/mock.js +52 -10
- package/test/soap.test.js +13 -6
- package/test/util.test.js +151 -1
- package/test/xtkCaster.test.js +97 -0
package/src/crypto.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
|
const { Util } = require('./util.js');
|
|
15
16
|
|
|
16
17
|
|
|
@@ -128,3 +129,5 @@ if (!Util.isBrowser()) {
|
|
|
128
129
|
exports.Cipher = Cipher;
|
|
129
130
|
}
|
|
130
131
|
|
|
132
|
+
|
|
133
|
+
})();
|
package/src/domUtil.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,11 +9,13 @@ 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
|
const XtkCaster = require('./xtkCaster.js').XtkCaster;
|
|
15
16
|
const { Util } = require("./util.js");
|
|
16
17
|
|
|
17
|
-
var JSDOM
|
|
18
|
+
var JSDOM;
|
|
18
19
|
|
|
19
20
|
/* istanbul ignore else */
|
|
20
21
|
if (!Util.isBrowser()) {
|
|
@@ -34,11 +35,11 @@ else {
|
|
|
34
35
|
var dom = parser.parseFromString(text, "application/xml");
|
|
35
36
|
this.window = {
|
|
36
37
|
document: dom
|
|
37
|
-
}
|
|
38
|
+
};
|
|
38
39
|
this.serialize = function() {
|
|
39
40
|
return new XMLSerializer().serializeToString(dom);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
41
|
+
};
|
|
42
|
+
};
|
|
42
43
|
|
|
43
44
|
JSDOM = jsdom;
|
|
44
45
|
}
|
|
@@ -90,12 +91,17 @@ class DomException {
|
|
|
90
91
|
|
|
91
92
|
|
|
92
93
|
/**
|
|
93
|
-
* Helpers for common manipulation of DOM documents
|
|
94
94
|
* @memberof XML
|
|
95
95
|
* @class
|
|
96
96
|
* @constructor
|
|
97
97
|
*/
|
|
98
98
|
class DomUtil {
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Helpers for common manipulation of DOM documents. Al functions are static, it is not necessary to create new instances of this object
|
|
102
|
+
*/
|
|
103
|
+
constructor() {
|
|
104
|
+
}
|
|
99
105
|
|
|
100
106
|
/**
|
|
101
107
|
* Parse an XML string as a DOM Document
|
|
@@ -377,6 +383,15 @@ class DomUtil {
|
|
|
377
383
|
return doc;
|
|
378
384
|
}
|
|
379
385
|
|
|
386
|
+
static _getTextIfTextNode(xml) {
|
|
387
|
+
const child = xml.firstChild;
|
|
388
|
+
if (!child) return null; // no children
|
|
389
|
+
if (child.nextSibling) return null; // more than 1 child
|
|
390
|
+
if (child.nodeType !== 3 && child.nodeType !== 4) return null;
|
|
391
|
+
const text = child.nodeValue;
|
|
392
|
+
return text;
|
|
393
|
+
}
|
|
394
|
+
|
|
380
395
|
/**
|
|
381
396
|
* Internal recursive method to convert an XML element to a object literal (JSON)
|
|
382
397
|
* This function does not return anything. Instead it creates children elements in the passed 'json' object
|
|
@@ -408,20 +423,36 @@ class DomUtil {
|
|
|
408
423
|
if (isArray && !Util.isArray(json[childName]))
|
|
409
424
|
json[childName] = [ json[childName] ];
|
|
410
425
|
if (child.nodeType == 1) { // element
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
426
|
+
// In SimpleJson representation, ensure we have proper transformation
|
|
427
|
+
// of text and CDATA nodes. For instance, the following
|
|
428
|
+
// <workflow><desc>Hello</desc></workflow>
|
|
429
|
+
// should be transformed into { "$desc": "Hello" }
|
|
430
|
+
// Note that an empty element such as
|
|
431
|
+
// <workflow><desc></desc></workflow>
|
|
432
|
+
// will be transformed into { "desc": {} }
|
|
433
|
+
// because there is an ambiguity and, unless we have information
|
|
434
|
+
// from the schema, we cannot know if <desc></desc> should be
|
|
435
|
+
// transformed into "$desc": "" or into "desc": {}
|
|
436
|
+
const text = this._getTextIfTextNode(child);
|
|
437
|
+
if (text !== null && flavor == "SimpleJson") {
|
|
438
|
+
json[`$${childName}`] = text;
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
const jsonChild = flavor == "BadgerFish" ? new BadgerFishObject() : {};
|
|
442
|
+
this._toJSON(child, jsonChild, flavor);
|
|
443
|
+
if (isArray)
|
|
444
|
+
json[childName].push(jsonChild);
|
|
445
|
+
else
|
|
446
|
+
json[childName] = jsonChild;
|
|
447
|
+
}
|
|
417
448
|
}
|
|
418
449
|
else if (child.nodeType === 3 || child.nodeType === 4) { // text and CDATA
|
|
419
450
|
if (flavor == "BadgerFish") {
|
|
420
|
-
|
|
421
|
-
if (json
|
|
422
|
-
json
|
|
451
|
+
const text = child.nodeValue;
|
|
452
|
+
if (json.$ === undefined)
|
|
453
|
+
json.$ = text;
|
|
423
454
|
else
|
|
424
|
-
json
|
|
455
|
+
json.$ = json.$ + text;
|
|
425
456
|
}
|
|
426
457
|
}
|
|
427
458
|
child = child.nextSibling;
|
|
@@ -442,9 +473,9 @@ class DomUtil {
|
|
|
442
473
|
throw new DomException(`Invalid JSON flavor '${flavor}'. Should be 'SimpleJson' or 'BadgerFish'`);
|
|
443
474
|
if (xml.nodeType == 9)
|
|
444
475
|
xml = xml.documentElement;
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
476
|
+
var json = flavor == "BadgerFish" ? new BadgerFishObject() : {};
|
|
477
|
+
this._toJSON(xml, json, flavor);
|
|
478
|
+
return json;
|
|
448
479
|
}
|
|
449
480
|
|
|
450
481
|
}
|
|
@@ -613,3 +644,5 @@ exports.DomException = DomException;
|
|
|
613
644
|
exports.BadgerFishObject = BadgerFishObject;
|
|
614
645
|
exports.XPath = XPath;
|
|
615
646
|
exports.XPathElement = XPathElement;
|
|
647
|
+
|
|
648
|
+
})();
|
package/src/entityAccessor.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,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
|
*
|
|
@@ -204,3 +204,5 @@ class EntityAccessor {
|
|
|
204
204
|
|
|
205
205
|
// Public exports
|
|
206
206
|
exports.EntityAccessor = EntityAccessor;
|
|
207
|
+
|
|
208
|
+
})();
|
package/src/index.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,16 +9,15 @@ 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
|
-
|
|
14
|
-
|
|
12
|
+
(function() {
|
|
13
|
+
"use strict";
|
|
14
|
+
|
|
15
15
|
/**********************************************************************************
|
|
16
16
|
*
|
|
17
17
|
* Adobe Campaign Classic Core SDK
|
|
18
18
|
*
|
|
19
19
|
*********************************************************************************/
|
|
20
20
|
|
|
21
|
-
'use strict'
|
|
22
|
-
|
|
23
21
|
const pjson = require('../package.json');
|
|
24
22
|
const DomUtil = require('./domUtil.js').DomUtil;
|
|
25
23
|
const XtkCaster = require('./xtkCaster.js').XtkCaster;
|
|
@@ -42,119 +40,123 @@ const request = require('./transport.js').request;
|
|
|
42
40
|
*/
|
|
43
41
|
|
|
44
42
|
var transport = request;
|
|
45
|
-
function _transport(t) {
|
|
46
|
-
if (t) {
|
|
47
|
-
const old = transport;
|
|
48
|
-
transport = t;
|
|
49
|
-
return old;
|
|
50
|
-
}
|
|
51
|
-
return transport;
|
|
52
|
-
}
|
|
53
43
|
|
|
54
44
|
/**
|
|
55
45
|
* @namespace Campaign
|
|
56
46
|
*/
|
|
47
|
+
class SDK {
|
|
57
48
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
*
|
|
61
|
-
* @memberof Campaign
|
|
62
|
-
* @param {ConnectionParameters} connectionParameters. Use ConnectionParameters.ofUserAndPassword for example
|
|
63
|
-
* @return {Promise<Client>} an ACC client object
|
|
64
|
-
*/
|
|
65
|
-
async function init (connectionParameters) {
|
|
66
|
-
const client = new Client(this, connectionParameters);
|
|
67
|
-
return client;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* @typedef {Object} SDKVersion
|
|
72
|
-
* @property {string} version - the version of the SDK (example: "1.0.0")
|
|
73
|
-
* @property {string} name - the name of the npm package ("@adobe/acc-js-sdk")
|
|
74
|
-
* @property {string} description - the version of the SDK (example: "ACC JavaScript SDK")
|
|
75
|
-
* @memberOf Campaign
|
|
76
|
-
*/
|
|
49
|
+
constructor() {
|
|
50
|
+
}
|
|
77
51
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
52
|
+
_transport(t) {
|
|
53
|
+
if (t) {
|
|
54
|
+
const old = transport;
|
|
55
|
+
transport = t;
|
|
56
|
+
return old;
|
|
57
|
+
}
|
|
58
|
+
return transport;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Returns a Client interface which allows you to logon on to an ACC instance and call SOAP methods
|
|
63
|
+
*
|
|
64
|
+
* @memberof Campaign
|
|
65
|
+
* @param {ConnectionParameters} connectionParameters. Use ConnectionParameters.ofUserAndPassword for example
|
|
66
|
+
* @return {Promise<Client>} an ACC client object
|
|
67
|
+
*/
|
|
68
|
+
async init (connectionParameters) {
|
|
69
|
+
const client = new Client(this, connectionParameters);
|
|
70
|
+
return client;
|
|
88
71
|
}
|
|
89
|
-
}
|
|
90
72
|
|
|
91
|
-
/**
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
73
|
+
/**
|
|
74
|
+
* @typedef {Object} SDKVersion
|
|
75
|
+
* @property {string} version - the version of the SDK (example: "1.0.0")
|
|
76
|
+
* @property {string} name - the name of the npm package ("@adobe/acc-js-sdk")
|
|
77
|
+
* @property {string} description - the version of the SDK (example: "ACC JavaScript SDK")
|
|
78
|
+
* @memberOf Campaign
|
|
79
|
+
*/
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get client SDK version
|
|
83
|
+
* @memberof Campaign
|
|
84
|
+
* @returns {Campaign.SDKVersion} an object containing information about the SDK, such as it's name, version, etc.
|
|
85
|
+
*/
|
|
86
|
+
getSDKVersion() {
|
|
87
|
+
return {
|
|
88
|
+
version: pjson.version,
|
|
89
|
+
name: pjson.name,
|
|
90
|
+
description: pjson.description
|
|
91
|
+
};
|
|
92
|
+
}
|
|
100
93
|
|
|
101
|
-
/**
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
* <li> the first one takes one single parameter which is a string and returns the escaped, quoted string
|
|
110
|
-
* <li> the second one takes 2 array of strings and is called when using the function in tagged string litterals. The first array is the constant parts
|
|
111
|
-
* of the string litteral, and the second array contains the variable parts. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
|
|
112
|
-
* </ul>
|
|
113
|
-
* <p>
|
|
114
|
-
* The function can be used in a tagged string litterals like this: "var expr = escapeXtk`@name=${hello}`"
|
|
115
|
-
* <p>
|
|
116
|
-
* @memberof Campaign
|
|
117
|
-
* @param {string|string[]} p1 is the text to escape. If the text is null or undefined, it will be handled as an empty string. when using the escapeXtk for a tagged string litteral, this parameter is the array of constant values in the template.
|
|
118
|
-
* @param {undefined|string[]} p2 when using the escapeXtk for a tagged string litteral, this parameter is the array of expression values in the template.
|
|
119
|
-
* @returns {string} the escaped and quoted (simple quotes) text.
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* expect(sdk.escapeXtk("Rock 'n' Roll")).toBe("'Rock \\'n\\' Roll'");
|
|
123
|
-
*
|
|
124
|
-
* @example
|
|
125
|
-
* expect(sdk.escapeXtk`@name=${"Rock 'n' Roll"}`).toBe("@name='Rock \\'n\\' Roll'");
|
|
126
|
-
*/
|
|
127
|
-
function escapeXtk(p1, ...p2)
|
|
128
|
-
{
|
|
129
|
-
// first syntax: only one parameter which is a string => returns the escaped string.
|
|
130
|
-
// that's how the Campaign function in common.js behaves
|
|
131
|
-
if (p1 === undefined || p1 === null)
|
|
132
|
-
return "''";
|
|
133
|
-
if (typeof p1 === 'string') {
|
|
134
|
-
return "'" + String(p1).replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'";
|
|
94
|
+
/**
|
|
95
|
+
* Get the outbound IP address (https://api.db-ip.com/v2/free/self)
|
|
96
|
+
* Can be useful to troubleshoot IP whitelisting issues
|
|
97
|
+
*/
|
|
98
|
+
async ip() {
|
|
99
|
+
const transport = this._transport();
|
|
100
|
+
const ip = await transport({ url: "https://api.db-ip.com/v2/free/self" });
|
|
101
|
+
return ip;
|
|
135
102
|
}
|
|
136
103
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Escapes and quotes string contained in Xtk expressions. It's common to build xtk expressions such as "@name='Hello'". If 'Hello' is a variable, it's
|
|
106
|
+
* tempting to write "@name='" + hello + "'", or `@name='${hello}'`. The issue is that if the hello variable contains characters such as a
|
|
107
|
+
* simple quote, there can be security concerns (xtk injections). The escapeXtk function ensure proper escaping in this case. In addition, it will also
|
|
108
|
+
* surround the string with quotes, so you can write `@name=${escapeXtk(hello)}`.
|
|
109
|
+
* <p>
|
|
110
|
+
* There are 2 alternate signatures for this function
|
|
111
|
+
* <ul>
|
|
112
|
+
* <li> the first one takes one single parameter which is a string and returns the escaped, quoted string
|
|
113
|
+
* <li> the second one takes 2 array of strings and is called when using the function in tagged string litterals. The first array is the constant parts
|
|
114
|
+
* of the string litteral, and the second array contains the variable parts. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
|
|
115
|
+
* </ul>
|
|
116
|
+
* <p>
|
|
117
|
+
* The function can be used in a tagged string litterals like this: "var expr = escapeXtk`@name=${hello}`"
|
|
118
|
+
* <p>
|
|
119
|
+
* @memberof Campaign
|
|
120
|
+
* @param {string|string[]} p1 is the text to escape. If the text is null or undefined, it will be handled as an empty string. when using the escapeXtk for a tagged string litteral, this parameter is the array of constant values in the template.
|
|
121
|
+
* @param {undefined|string[]} p2 when using the escapeXtk for a tagged string litteral, this parameter is the array of expression values in the template.
|
|
122
|
+
* @returns {string} the escaped and quoted (simple quotes) text.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* expect(sdk.escapeXtk("Rock 'n' Roll")).toBe("'Rock \\'n\\' Roll'");
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* expect(sdk.escapeXtk`@name=${"Rock 'n' Roll"}`).toBe("@name='Rock \\'n\\' Roll'");
|
|
129
|
+
*/
|
|
130
|
+
escapeXtk(p1, ...p2)
|
|
131
|
+
{
|
|
132
|
+
// first syntax: only one parameter which is a string => returns the escaped string.
|
|
133
|
+
// that's how the Campaign function in common.js behaves
|
|
134
|
+
if (p1 === undefined || p1 === null)
|
|
135
|
+
return "''";
|
|
136
|
+
if (typeof p1 === 'string') {
|
|
137
|
+
return "'" + String(p1).replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'";
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Second syntax: for use in tagged template litterals
|
|
141
|
+
// instead of writing: { expr: "@name = " + escapeXtk(userName) }
|
|
142
|
+
// you write { expr: escapeXtk`@name = {userName}` }
|
|
143
|
+
if (p1.length == 0) return "''";
|
|
144
|
+
var str = p1[0];
|
|
145
|
+
for (var i=1; i<p1.length; i++) {
|
|
146
|
+
str = str + this.escapeXtk(p2[i-1]) + p1[i];
|
|
147
|
+
}
|
|
148
|
+
return str;
|
|
144
149
|
}
|
|
145
|
-
return str;
|
|
146
150
|
}
|
|
147
151
|
|
|
152
|
+
const sdk = new SDK();
|
|
153
|
+
sdk.XtkCaster = XtkCaster;
|
|
154
|
+
sdk.Credentials = Credentials;
|
|
155
|
+
sdk.DomUtil = DomUtil;
|
|
156
|
+
sdk.ConnectionParameters = ConnectionParameters;
|
|
157
|
+
|
|
148
158
|
// Public exports
|
|
149
|
-
module.exports =
|
|
150
|
-
|
|
151
|
-
getSDKVersion: getSDKVersion,
|
|
152
|
-
ip: ip,
|
|
153
|
-
escapeXtk: escapeXtk,
|
|
154
|
-
XtkCaster: XtkCaster,
|
|
155
|
-
DomUtil: DomUtil,
|
|
156
|
-
Credentials: Credentials,
|
|
157
|
-
ConnectionParameters: ConnectionParameters,
|
|
158
|
-
_transport: _transport
|
|
159
|
-
};
|
|
159
|
+
module.exports = sdk;
|
|
160
|
+
|
|
160
161
|
|
|
162
|
+
})();
|
package/src/methodCache.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
|
*
|
|
@@ -19,6 +20,7 @@ governing permissions and limitations under the License.
|
|
|
19
20
|
*********************************************************************************/
|
|
20
21
|
|
|
21
22
|
const DomUtil = require('./domUtil.js').DomUtil;
|
|
23
|
+
const { Cache } = require('./cache.js');
|
|
22
24
|
|
|
23
25
|
/**
|
|
24
26
|
* @namespace Campaign
|
|
@@ -28,39 +30,61 @@ const DomUtil = require('./domUtil.js').DomUtil;
|
|
|
28
30
|
*/
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
|
-
* A in-memory cache for SOAP call method definitions. Not intended to be used directly,
|
|
32
|
-
* but an internal cache for the Campaign.Client object
|
|
33
|
-
*
|
|
34
33
|
* @private
|
|
35
34
|
* @class
|
|
36
35
|
* @constructor
|
|
37
36
|
* @memberof Campaign
|
|
38
37
|
*/
|
|
39
|
-
class MethodCache {
|
|
40
|
-
|
|
41
|
-
constructor() {
|
|
42
|
-
/**
|
|
43
|
-
* Method definitions, keyed but schema id. Value is a map whose key is a method name. Value is the DOM element
|
|
44
|
-
* corresponding to a method
|
|
45
|
-
* @type {Object<string, Object<string, Campaign.SoapMethodDefinition>>}
|
|
46
|
-
*/
|
|
47
|
-
this.methodsBySchema = {};
|
|
38
|
+
class MethodCache extends Cache {
|
|
48
39
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
40
|
+
/**
|
|
41
|
+
* A in-memory cache for SOAP call method definitions. Not intended to be used directly,
|
|
42
|
+
* but an internal cache for the Campaign.Client object
|
|
43
|
+
*
|
|
44
|
+
* Cached object are made of
|
|
45
|
+
* - the key is a string in the form <schemaId>#<methodName>, such as "xtk:session#GetServerTime"
|
|
46
|
+
* - the value is a JSON object made of two attributes:
|
|
47
|
+
* - the "urn" attribute, such as "xtk:persist", which is the URN to use to make the SOAP call
|
|
48
|
+
* - the "method" attribute, a DOM element corresponding to the method XML element
|
|
49
|
+
*
|
|
50
|
+
* @param {Storage} storage is an optional Storage object, such as localStorage or sessionStorage
|
|
51
|
+
* @param {string} rootKey is an optional root key to use for the storage object
|
|
52
|
+
* @param {number} ttl is the TTL for objects in ms. Defaults to 5 mins
|
|
53
|
+
*/
|
|
54
|
+
constructor(storage, rootKey, ttl) {
|
|
55
|
+
super(storage, rootKey, ttl, ((schemaId, methodName) => schemaId + "#" + methodName ), (item, serDeser) => {
|
|
56
|
+
if (serDeser) {
|
|
57
|
+
if (!item || !item.value || !item.value.method) throw Error(`Cannot serialize falsy cached item`);
|
|
58
|
+
const value = Object.assign({}, item); // shallow copy
|
|
59
|
+
value.value = Object.assign({}, value.value); // dummy deep copy
|
|
60
|
+
value.value.method = DomUtil.toXMLString(item.value.method);
|
|
61
|
+
return JSON.stringify(value);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const json = JSON.parse(item);
|
|
65
|
+
json.value.method = DomUtil.parse(json.value.method).documentElement;
|
|
66
|
+
return json;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
56
69
|
}
|
|
57
70
|
|
|
58
71
|
/**
|
|
59
72
|
* Caches all methods of a schema
|
|
73
|
+
* For backward compatibility purpose. Use "put" instead
|
|
60
74
|
*
|
|
75
|
+
* @deprecated
|
|
61
76
|
* @param {Element} schema DOM document node represening the schema
|
|
62
77
|
*/
|
|
63
78
|
cache(schema) {
|
|
79
|
+
return this.put(schema);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Caches all methods of a schema
|
|
84
|
+
*
|
|
85
|
+
* @param {Element} schema DOM document node represening the schema
|
|
86
|
+
*/
|
|
87
|
+
put(schema) {
|
|
64
88
|
var namespace = DomUtil.getAttributeAsString(schema, "namespace");
|
|
65
89
|
var name = DomUtil.getAttributeAsString(schema, "name");
|
|
66
90
|
var impls = DomUtil.getAttributeAsString(schema, "implements");
|
|
@@ -82,17 +106,12 @@ class MethodCache {
|
|
|
82
106
|
}
|
|
83
107
|
|
|
84
108
|
if (schemaId) {
|
|
85
|
-
this.methodsBySchema[schemaId] = this.methodsBySchema[schemaId] || {};
|
|
86
|
-
this.methodsBySchema[soapUrn] = this.methodsBySchema[soapUrn] || {};
|
|
87
|
-
this.soapUrns[schemaId] = this.soapUrns[schemaId] || {};
|
|
88
|
-
this.soapUrns[soapUrn] = this.soapUrns[soapUrn] || {};
|
|
89
109
|
var child = DomUtil.getFirstChildElement(root, "method");
|
|
90
110
|
while (child) {
|
|
91
111
|
const methodName = DomUtil.getAttributeAsString(child, "name");
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this.soapUrns[soapUrn][methodName] = soapUrn;
|
|
112
|
+
const cached = { method: child, urn: soapUrn };
|
|
113
|
+
super.put(schemaId, methodName, cached);
|
|
114
|
+
super.put(soapUrn, methodName, cached); /// version 0.1.23: cache the method in both the schema id and interface id form compatibility reasons
|
|
96
115
|
child = DomUtil.getNextSiblingElement(child, "method");
|
|
97
116
|
}
|
|
98
117
|
}
|
|
@@ -108,10 +127,8 @@ class MethodCache {
|
|
|
108
127
|
* @returns {Campaign.SoapMethodDefinition} the method definition, or undefined if the schema or the method is not found
|
|
109
128
|
*/
|
|
110
129
|
get(schemaId, methodName) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
dict = dict[methodName];
|
|
114
|
-
return dict;
|
|
130
|
+
const cached = super.get(schemaId, methodName);
|
|
131
|
+
return cached ? cached.method : undefined;
|
|
115
132
|
}
|
|
116
133
|
|
|
117
134
|
/**
|
|
@@ -122,21 +139,13 @@ class MethodCache {
|
|
|
122
139
|
* @returns {string} the URN (or Soap action header), or undefined if the schema or the method is not found
|
|
123
140
|
*/
|
|
124
141
|
getSoapUrn(schemaId, methodName) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
soapUrn = soapUrn[methodName];
|
|
128
|
-
return soapUrn;
|
|
142
|
+
const cached = super.get(schemaId, methodName);
|
|
143
|
+
return cached ? cached.urn : undefined;
|
|
129
144
|
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Clears the cache
|
|
133
|
-
*/
|
|
134
|
-
clear() {
|
|
135
|
-
this.methodsBySchema = {};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
145
|
}
|
|
139
146
|
|
|
140
147
|
|
|
141
148
|
// Public exports
|
|
142
|
-
exports.MethodCache = MethodCache;
|
|
149
|
+
exports.MethodCache = MethodCache;
|
|
150
|
+
|
|
151
|
+
})();
|