@adobe/acc-js-sdk 1.0.2 → 1.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/acc-js-sdk",
3
- "version": "1.0.2",
3
+ "version": "1.0.6",
4
4
  "description": "ACC Javascript SDK",
5
5
  "main": "src/index.js",
6
6
  "homepage": "https://github.com/adobe/acc-js-sdk#readme",
@@ -16,15 +16,19 @@
16
16
  "devDependencies": {
17
17
  "docdash": "^1.2.0",
18
18
  "eslint": "^7.32.0",
19
- "jest": "^27.2.0",
20
- "jest-junit": "^12.2.0",
19
+ "jest": "^27.2.5",
20
+ "jest-junit": "^13.0.0",
21
21
  "jsdoc": "^3.6.7",
22
- "jsdoc-to-markdown": "^7.0.1"
22
+ "jsdoc-to-markdown": "^7.0.1",
23
+ "jshint": "^2.13.1"
23
24
  },
24
25
  "author": "",
25
26
  "scripts": {
26
27
  "publish:npm": "npm publish --access public",
27
28
  "unit-tests": "jest --config test/jest.config.js --maxWorkers=2",
28
29
  "jsdoc": "jsdoc -a all -c jsdoc.json -r -R README.md src/*.js -d docs/jsdoc"
30
+ },
31
+ "jshintConfig": {
32
+ "esversion": 8
29
33
  }
30
34
  }
@@ -28,6 +28,15 @@ const utils = require("./utils.js");
28
28
  }
29
29
  });
30
30
 
31
+ await utils.sample({
32
+ title: "Display the outbound IP address (can be useful to troubleshoot IP whitelisting issues)",
33
+ labels: [ "Basics", "IP", "Whitelisting", "403" ],
34
+ code: async () => {
35
+ const ip = await sdk.ip();
36
+ console.log(`>> ${JSON.stringify(ip)}`);
37
+ }
38
+ });
39
+
31
40
  await utils.sample({
32
41
  title: "Log on and log off",
33
42
  labels: [ "Basics", "connectionParameters", "ofUserAndPassword", "xtk:session", "logon", "logoff" ],
@@ -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,6 +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
  */
12
+ (function() {
13
+ "use strict";
13
14
 
14
15
 
15
16
  /**********************************************************************************
@@ -31,7 +32,7 @@ const EntityAccessor = require('./entityAccessor.js').EntityAccessor;
31
32
  // ========================================================================================
32
33
 
33
34
  // Determine if a name is an attribute name, i.e. if it starts with the "@" character
34
- const isAttributeName = function(name) { return name.length > 0 && name[0] == '@'; }
35
+ const isAttributeName = function(name) { return name.length > 0 && name[0] == '@'; };
35
36
 
36
37
 
37
38
  /**
@@ -325,7 +326,7 @@ class XtkSchemaNode {
325
326
  else if (element.isParent())
326
327
  childNode = node.parent;
327
328
  else
328
- childNode = node._getChildDefAutoExpand(name, mustExist)
329
+ childNode = node._getChildDefAutoExpand(name, mustExist);
329
330
  node = childNode;
330
331
  }
331
332
  return node;
@@ -658,8 +659,6 @@ function newCurrentLogin(userInfo) {
658
659
  // ========================================================================================
659
660
 
660
661
  /**
661
- * The Application object provides access to certain properties of the Campaign server.
662
- *
663
662
  * @class
664
663
  * @constructor
665
664
  * @param {Campaign.Client} client The Campaign Client from which this Application object is created
@@ -667,6 +666,12 @@ function newCurrentLogin(userInfo) {
667
666
  */
668
667
  class Application {
669
668
 
669
+ /**
670
+ * The Application object provides access to certain properties of the Campaign server.
671
+ * Do not create this object directly, it's automatically created by the Campaign.Client at Logon time
672
+ * @private
673
+ * @param {Campaign.Client} client the Campaign client representing the Campaign instance
674
+ */
670
675
  constructor(client) {
671
676
  this.client = client;
672
677
  const info = this.client.getSessionInfo();
@@ -737,3 +742,4 @@ exports.Application = Application;
737
742
  // For tests
738
743
  exports.newSchema = newSchema;
739
744
  exports.newCurrentLogin = newCurrentLogin;
745
+ })();
package/src/cache.js ADDED
@@ -0,0 +1,275 @@
1
+ /*
2
+ Copyright 2020 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ (function() {
13
+ "use strict";
14
+
15
+
16
+ /**********************************************************************************
17
+ *
18
+ * Cache utilities
19
+ *
20
+ *********************************************************************************/
21
+
22
+ /**
23
+ * @namespace Utils
24
+ */
25
+
26
+
27
+ /**********************************************************************************
28
+ *
29
+ * A simple cache for XtkEntities, options, etc.
30
+ *
31
+ *********************************************************************************/
32
+
33
+ /**
34
+ * @private
35
+ * @class
36
+ * @constructor
37
+ * @memberof Utils
38
+ */
39
+ class SafeStorage {
40
+
41
+ /**
42
+ * A wrapper to the Storage interface (LocalStorage, etc.) which is "safe", i.e.
43
+ *
44
+ * - it will never throw / support local stroage to be undefined or not accessible
45
+ * - Handle the notion of "root key", i.e. prefix
46
+ * - Set/get values as JSON only and not as strings
47
+ * - Silently caches all exceptions
48
+ * - Automatically remove from storage cached values which are not valid, expired, or cannot be parsed
49
+ *
50
+ * SafeStorage objects are created automatically by Caches
51
+ *
52
+ * @param {Storage} delegate an optional delegate options, confomring to the Storage interface (getItem, setItem, removeItem)
53
+ * @param {string} rootKey an optional prefix which will be prepend to all keys
54
+ * @param {function} serDeser serializarion & deserialization function. First parameter is the object or value to serialize
55
+ * or deserialize, and second parameter is true for serialization or false for deserialization
56
+ */
57
+ constructor(delegate, rootKey, serDeser) {
58
+ if (!serDeser)
59
+ serDeser = (item, serDeser) => {
60
+ if (serDeser) {
61
+ if (!item) throw Error(`Cannot serialize falsy cached item`);
62
+ if (typeof item !== "object") throw Error(`Cannot serialize non-object`);
63
+ return JSON.stringify(item);
64
+ }
65
+ else {
66
+ if (!item) throw Error(`Cannot deserialize falsy cached item`);
67
+ return JSON.parse(item);
68
+ }
69
+ };
70
+ this._delegate = delegate;
71
+ this._rootKey = rootKey ? `${rootKey}$` : "";
72
+ this._serDeser = serDeser;
73
+ }
74
+
75
+ /**
76
+ * Get an item from storage
77
+ * @param {string} key the item key (relative to the root key)
78
+ * @returns {Utils.CachedObject} the cached object, or undefined if not found.
79
+ * The storage serDeser fucntion will be used to deserialize the cached value
80
+ */
81
+ getItem(key) {
82
+ if (!this._delegate || this._rootKey === undefined || this._rootKey === null)
83
+ return;
84
+ const itemKey = `${this._rootKey}${key}`;
85
+ const raw = this._delegate.getItem(itemKey);
86
+ if (!raw)
87
+ return undefined;
88
+ try {
89
+ return this._serDeser(raw, false);
90
+ } catch(ex) {
91
+ this.removeItem(key);
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Put an item into storage
97
+ * @param {string} key the item key (relative to the root key)
98
+ * @param {Utils.CachedObject} json the object to cache
99
+ * The storage serDeser fucntion will be used to serialize the cached value
100
+ */
101
+ setItem(key, json) {
102
+ if (!this._delegate || this._rootKey === undefined || this._rootKey === null)
103
+ return;
104
+ try {
105
+ //if (json && typeof json === "object") {
106
+ const raw = this._serDeser(json, true);
107
+ this._delegate.setItem(`${this._rootKey}${key}`, raw);
108
+ return;
109
+ } catch(ex) { /* Ignore errors in safe class */
110
+ }
111
+ this.removeItem(key);
112
+ }
113
+
114
+ /**
115
+ * Removes an item from the storage
116
+ * @param {string} key the item key (relative to the root key)
117
+ */
118
+ removeItem(key) {
119
+ if (!this._delegate || this._rootKey === undefined || this._rootKey === null)
120
+ return;
121
+ try {
122
+ this._delegate.removeItem(`${this._rootKey}${key}`);
123
+ } catch(ex) { /* Ignore errors in safe class */
124
+ }
125
+ }
126
+ }
127
+
128
+ /**
129
+ * @private
130
+ * @class
131
+ * @constructor
132
+ * @memberof Utils
133
+ */
134
+ class CachedObject {
135
+
136
+ /**
137
+ * An object in the cache, i.e. a wrapped to a cached value and additional metadata to manage the cache.
138
+ * Do not create such objects directly, they are 100% managed by the Cache object
139
+ *
140
+ * @param {*} value the cached value
141
+ * @param {number} cachedAt the timestamp at which the value was cached
142
+ * @param {number} expiresAt the timestamp at which the cached value expires
143
+ */
144
+ constructor(value, cachedAt, expiresAt) {
145
+ this.value = value;
146
+ this.cachedAt = cachedAt;
147
+ this.expiresAt = expiresAt;
148
+ }
149
+ }
150
+
151
+ /**
152
+ * @private
153
+ * @class
154
+ * @constructor
155
+ * @memberof Utils
156
+ */
157
+ class Cache {
158
+
159
+ /**
160
+ * A general purpose in-memory cache with TTL. In addition to caching in memory, the cache has the ability to delegate the caching
161
+ * to a persistent cache, such as the browser localStorage. The interface is 100% synchronous.
162
+ *
163
+ * By default, caches take a single parameter for the key. It is possible however to use a more complex scenario by setting a makeKeyFn.
164
+ * When set, such a function will take 1 or more arguments and will be responsible to create a primitive key (a string) from the arguments.
165
+ * The cache public APIs : get and put therefore can take a variable number of key arguments, which will be combined into the actual primitive key.
166
+ *
167
+ * @param {Storage} storage is an optional Storage object, such as localStorage or sessionStorage. This object will be wrapped into a SafeStorage object to ensure access is safe and will not throw any exceptions
168
+ * @param {string} rootKey is an optional root key to use for the storage object
169
+ * @param {number} ttl is the TTL for objects in ms. Defaults to 5 mins
170
+ * @param {function} makeKeyFn is an optional function which will generate a key for objects in the cache. It's passed the arguments of the cache 'get' function
171
+ * @param {function} serDeser serializarion & deserialization function. First parameter is the object or value to serialize
172
+ * or deserialize, and second parameter is true for serialization or false for deserialization
173
+ */
174
+ constructor(storage, rootKey, ttl, makeKeyFn, serDeser) {
175
+ this._storage = new SafeStorage(storage, rootKey, serDeser);
176
+ this._ttl = ttl || 1000*300;
177
+ this._makeKeyFn = makeKeyFn || ((x) => x);
178
+ this._cache = {};
179
+ // timestamp at which the cache was last cleared
180
+ this._lastCleared = this._loadLastCleared();
181
+ }
182
+
183
+ // Load timestamp at which the cache was last cleared
184
+ _loadLastCleared() {
185
+ const json = this._storage.getItem("lastCleared");
186
+ return json ? json.timestamp : undefined;
187
+ }
188
+
189
+ _saveLastCleared() {
190
+ const now = Date.now();
191
+ this._lastCleared = now;
192
+ this._storage.setItem("lastCleared", { timestamp: now});
193
+ }
194
+
195
+ // Load from local storage
196
+ _load(key) {
197
+ const json = this._storage.getItem(key);
198
+ if (!json || !json.cachedAt || json.cachedAt <= this._lastCleared) {
199
+ this._storage.removeItem(key);
200
+ return;
201
+ }
202
+ return json;
203
+ }
204
+
205
+ // Save to local storage
206
+ _save(key, cached) {
207
+ this._storage.setItem(key, cached);
208
+ }
209
+
210
+ // Remove from local storage
211
+ _remove(key) {
212
+ this._storage.removeItem(key);
213
+ }
214
+
215
+ _getIfActive(key) {
216
+ // In memory cache?
217
+ var cached = this._cache[key];
218
+ // Local storage ?
219
+ if (!cached) {
220
+ cached = this._load(key);
221
+ this._cache[key] = cached;
222
+ }
223
+ if (!cached)
224
+ return undefined;
225
+ if (cached.expiresAt <= Date.now()) {
226
+ delete this._cache[key];
227
+ this._remove(key);
228
+ return undefined;
229
+ }
230
+ return cached.value;
231
+ }
232
+
233
+ /**
234
+ * Get a value from the cache
235
+ * @param {*} key the key or keys of the value to retreive
236
+ * @returns {*} the cached value, or undefined if not found
237
+ */
238
+ get() {
239
+ const key = this._makeKeyFn.apply(this, arguments);
240
+ const cached = this._getIfActive(key);
241
+ return cached;
242
+ }
243
+
244
+ /**
245
+ * Put a value from the cache
246
+ * @param {*} key the key or keys of the value to retreive
247
+ * @param {*} value the value to cache
248
+ * @returns {CachedObject} a cached object containing the cached value
249
+ */
250
+ put() {
251
+ const value = arguments[arguments.length -1];
252
+ const key = this._makeKeyFn.apply(this, arguments);
253
+ const now = Date.now();
254
+ const expiresAt = now + this._ttl;
255
+ const cached = new CachedObject(value, now, expiresAt);
256
+ this._cache[key] = cached;
257
+ this._save(key, cached);
258
+ return cached;
259
+ }
260
+
261
+ /**
262
+ * Removes everything from the cache. It does not directly removes data from persistent storage if there is, but it marks the cache
263
+ * as cleared so that subsequent get operation will not actually return any data cached in persistent storage
264
+ */
265
+ clear() {
266
+ this._cache = {};
267
+ this._saveLastCleared();
268
+ }
269
+ }
270
+
271
+ // Public expots
272
+ exports.SafeStorage = SafeStorage;
273
+ exports.Cache = Cache;
274
+
275
+ })();
package/src/campaign.js CHANGED
@@ -1,8 +1,3 @@
1
- "use strict";
2
-
3
- const { Util } = require("./util.js");
4
-
5
-
6
1
  /*
7
2
  Copyright 2020 Adobe. All rights reserved.
8
3
  This file is licensed to you under the Apache License, Version 2.0 (the "License");
@@ -14,25 +9,18 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
14
9
  OF ANY KIND, either express or implied. See the License for the specific language
15
10
  governing permissions and limitations under the License.
16
11
  */
12
+ (function() {
13
+ "use strict";
17
14
 
18
-
15
+ const { Util } = require("./util.js");
16
+
19
17
  /**
20
18
  * @namespace Campaign
21
19
  */
22
20
 
23
21
  /**
24
- * Represents a Campaign exception, i.e. any kind of error that can happen when calling Campaign APIs,
25
- * ranging from HTTP errors, XML serialization errors, SOAP errors, authentication errors, etc.
26
- *
27
- * @todo does not really belong to soap.js. Move it to a better place
28
22
  * @class
29
23
  * @constructor
30
- * @param {SoapMethodCall|request} call the call that triggered the error. It can be a SoapMethodCall object, a HTTP request object, or even be undefined if the exception is generated outside of the context of a call
31
- * @param {number} statusCode the HTTP status code (200, 500, etc.)
32
- * @param {string} faultCode the fault code, i.e. an error code
33
- * @param {string} faultString a short description of the error
34
- * @param {string} detail a more detailed description of the error
35
- * @param {*} cause an optional error object representing the cause of the exception
36
24
  * @memberof Campaign
37
25
  */
38
26
  class CampaignException {
@@ -50,18 +38,36 @@ governing permissions and limitations under the License.
50
38
  static NOT_LOGGED_IN(call, details) { return new CampaignException( call, 400, 16384, `SDK-000010 Cannot call API because client is not logged in`, details); }
51
39
  static DECRYPT_ERROR(details) { return new CampaignException(undefined, 400, 16384, `SDK-000011 "Cannot decrypt password: password marker is missing`, details); }
52
40
 
41
+
42
+ /**
43
+ * Returns a short description of the exception
44
+ * @returns {string} a short description of the exception
45
+ */
53
46
  toString() {
54
47
  return this.message;
55
48
  }
56
49
 
50
+ /**
51
+ * Represents a Campaign exception, i.e. any kind of error that can happen when calling Campaign APIs,
52
+ * ranging from HTTP errors, XML serialization errors, SOAP errors, authentication errors, etc.
53
+ *
54
+ * Members of this object are trimmed, and all session tokens, security tokens, passwords, etc. are replaced by "***"
55
+ *
56
+ * @param {SoapMethodCall|request} call the call that triggered the error. It can be a SoapMethodCall object, a HTTP request object, or even be undefined if the exception is generated outside of the context of a call
57
+ * @param {number} statusCode the HTTP status code (200, 500, etc.)
58
+ * @param {string} faultCode the fault code, i.e. an error code
59
+ * @param {string} faultString a short description of the error
60
+ * @param {string} detail a more detailed description of the error
61
+ * @param {Error|string} cause an optional error object representing the cause of the exception
62
+ */
57
63
  constructor(call, statusCode, faultCode, faultString, detail, cause) {
58
64
 
59
65
  // Provides a shorter and more friendly description of the call and method name
60
66
  // depending on whether the exception is thrown by a SOAP or HTTP call
61
- var methodCall = undefined;
62
- var methodName = undefined;
67
+ var methodCall;
68
+ var methodName;
63
69
  if (call) {
64
- const ctor = call.__proto__.constructor;
70
+ const ctor = Object.getPrototypeOf(call).constructor;
65
71
  if (ctor && ctor.name == "SoapMethodCall") {
66
72
  methodCall = {
67
73
  type: "SOAP",
@@ -192,6 +198,7 @@ governing permissions and limitations under the License.
192
198
 
193
199
  /**
194
200
  * Creates a CampaignException for a SOAP call and from a root exception
201
+ *
195
202
  * @private
196
203
  * @param {SoapMethodCall} call the SOAP call
197
204
  * @param {*} err the exception causing the SOAP call.
@@ -204,7 +211,7 @@ function makeCampaignException(call, err) {
204
211
  return err;
205
212
 
206
213
  // Wraps DOM exceptions which can occur when dealing with malformed XML
207
- const ctor = err.__proto__.constructor;
214
+ const ctor = Object.getPrototypeOf(err).constructor;
208
215
  if (ctor && ctor.name == "DOMException") {
209
216
  return new CampaignException(call, 500, err.code, `DOMException (${err.name})`, err.message, err);
210
217
  }
@@ -516,7 +523,7 @@ exports.OPERATOR_TYPE_GROUP = 1;
516
523
  exports.OPERATOR_TYPE_RIGHT = 2;
517
524
 
518
525
  exports.WORKFLOWTASK_STATUS_PENDING = 0;
519
- exports.WORKFLOWTASK_STATUS_COMPLETED = 1
526
+ exports.WORKFLOWTASK_STATUS_COMPLETED = 1;
520
527
 
521
528
  exports.MOBILE_MSGTYPE_SMS = 0;
522
529
  exports.MOBILE_MSGTYPE_WAPPUSH = 1;
@@ -661,4 +668,6 @@ exports.ACTION_TYPE_EXPIRED = 11;
661
668
 
662
669
  exports.CONTENT_EDITING_MODE_DEFAULT = 0;
663
670
  exports.CONTENT_EDITING_MODE_DCE = 1;
664
- exports.CONTENT_EDITING_MODE_AEM = 2;
671
+ exports.CONTENT_EDITING_MODE_AEM = 2;
672
+
673
+ })();