@adobe/acc-js-sdk 1.1.3 → 1.1.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/.eslintrc.js CHANGED
@@ -4,7 +4,8 @@ module.exports = {
4
4
  "commonjs": true,
5
5
  "es2021": true,
6
6
  "node": true,
7
- "jest": true
7
+ "jest": true,
8
+ circus: true
8
9
  },
9
10
  "extends": "eslint:recommended",
10
11
  "parserOptions": {
package/CHANGELOG.md CHANGED
@@ -5,6 +5,25 @@ This is a node.js SDK for Campaign API. It exposes the Campaign API exactly like
5
5
 
6
6
  # Changelog
7
7
 
8
+ ## Version 1.1.6
9
+ _2022_08_19_
10
+
11
+ * New auto-refresh mechanism to keep schemas and option caches up-to-date. See `client.startRefreshCaches` and `client.stopRefreshCaches` functions.
12
+
13
+ ## Version 1.1.5
14
+ _2022/07/07__
15
+
16
+ * The SOAP method name was not showing up properly in the Chrome console
17
+
18
+ ## Version 1.1.4
19
+ _2022/07/07__
20
+
21
+ * Added `application.version` which returns the server version in the format major.minor.servicePack (ex: 8.2.10)
22
+ * Added the ability to push down parameters to the SOAP and transport layers. See the pushDown section of the readme file.
23
+ * The pushDown mechanism can be used to simply overwrite the request timeout, either globally or at the method level
24
+ * Publicly export the HttpError class so that custom transports can be written more safely. A failure during transport should return an HttpError object
25
+ * By default, the SOAP method name is now added in the URLs for better troubleshooting
26
+
8
27
  ## Version 1.1.3
9
28
  _2022/05/30_
10
29
 
@@ -15,6 +34,10 @@ _2022/05/30_
15
34
  * Document how to set the password of an external account
16
35
  * By default, SDK will send additional HTTP headers to help troubleshooting and usage tracking
17
36
  * Add the ability to pass extra HTTP headers to API calls, either globally (to all HTTP headers), or locally, i.e. for a specific method
37
+ * Remove .vscode folder from the sources
38
+ * Example for xtkBuilder.installPackage API
39
+ * For APIs which have parameters of type DOMElement and which are called using XML, support passing either a DOMElement or a DOMDocument
40
+
18
41
 
19
42
  ## Version 1.1.2
20
43
  _2022/03/22_
package/README.md CHANGED
@@ -133,6 +133,8 @@ charset|UTF-8|The charset encoding used for http requests. In version 1.1.1 and
133
133
  extraHttpHeaders|[string]:string|An optional dictionary (key/value pairs) of extra HTTP headers to pass to all API calls.
134
134
  clientApp|string|An optional string describing the name and version of the SDK client application. It will be passed to the server in the ACC-SDK-Client-App HTTP header
135
135
  noSDKHeaders|boolean|Can be set to disable passing ACC-SDK-* HTTP headers to the server
136
+ noMethodInURL|boolean|Can be set to true to remove the method name from the URL
137
+ timeout|number|Can be used to set the APIs call timeout (in ms)
136
138
  ```js
137
139
  const connectionParameters = sdk.ConnectionParameters.ofUserAndPassword(
138
140
  "https://myInstance.campaign.adobe.com",
@@ -189,8 +191,8 @@ If you want to use the SDK client-side in a web page returned by Campaign, you c
189
191
  For this scenario, the `ofSecurityToken` function can be used. Pass it a security token (usually available as document.__securitytoken), and the SDK will let the browser handle the session token (cookie) for you.
190
192
 
191
193
  ```html
192
- <script src="acc-sdk.js"></script>
193
- <script>
194
+ <script src="acc-sdk.js"></script>
195
+ <script>
194
196
  (async () => {
195
197
  try {
196
198
  const sdk = document.accSDK;
@@ -204,8 +206,8 @@ For this scenario, the `ofSecurityToken` function can be used. Pass it a securit
204
206
  console.error(ex);
205
207
  }
206
208
  })();
207
- </script>
208
- </body>
209
+ </script>
210
+ </body>
209
211
  </html>
210
212
  ```
211
213
 
@@ -320,7 +322,8 @@ The Simple JSON format works like this:
320
322
 
321
323
  The XML root element tag is determined by the SDK as it's generating the XML, usually from the current schema name.
322
324
 
323
- * XML: `<root/>`
325
+ * XML: `<root/>
326
+ `
324
327
  * JSON: `{}`
325
328
 
326
329
  XML attributes are mapped to JSON attributes with the same name, whose litteral value can be a string, number, or boolean. There's no "@" sign in the JSON attribute name.
@@ -357,7 +360,9 @@ Text of a child element
357
360
  * Alternative JSON: `{ item: { $: "Hello" } }`
358
361
 
359
362
  If an element contains both text, and children, you need to use the alternative `$` syntax
360
- * XML: `<root><item>Hello<child id="1"/></item></root>`
363
+ * XML: `<root><item>Hello<child id="1"/>
364
+ </item>
365
+ </root>`
361
366
  * JSON: `{ item: { $: "Hello", child: { id:1 } }`
362
367
 
363
368
 
@@ -510,8 +515,8 @@ const DomUtil = client.DomUtil;
510
515
  Create DOM from XML string:
511
516
  ```js
512
517
  const doc = DomUtil.parse(`<root>
513
- <one/>
514
- </root>`);
518
+ <one/>
519
+ </root>`);
515
520
  ```
516
521
 
517
522
  Writes a DOM document or element as a string:
@@ -582,12 +587,12 @@ const json = DomUtil.toJSON(documentOrElement, "BadgerFish");
582
587
  Many Campaign APIs take arguments which are DOM documents or DOM elements. For example, the nms:delivery#DeployTriggerMessages first argument is a DOMElement which is supposed to be a `<where>` clause used as a condition to select Message Center deliveries to publish.
583
588
 
584
589
  ```xml
585
- <method name="DeployTriggerMessages" static="true">
586
- <parameters>
587
- <param inout="in" name="deliveries" type="DOMElement"/>
588
- <param inout="in" name="localPublish" type="boolean"/>
589
- </parameters>
590
- </method>
590
+ <method name="DeployTriggerMessages" static="true">
591
+ <parameters>
592
+ <param inout="in" name="deliveries" type="DOMElement"/>
593
+ <param inout="in" name="localPublish" type="boolean"/>
594
+ </parameters>
595
+ </method>
591
596
  ```
592
597
 
593
598
  For example, one would want to use the following condition to republish a particular delivery
@@ -603,7 +608,7 @@ For example, one would want to use the following condition to republish a partic
603
608
  The JSON object corresponds to the following XML
604
609
  ```xml
605
610
  <where>
606
- <condition expr="@internalName='DM23'"/>
611
+ <condition expr="@internalName='DM23'"/>
607
612
  </where>
608
613
  ```
609
614
 
@@ -688,6 +693,30 @@ It's possible to disable persistent caches using the `noStorage` connection opti
688
693
  It is also possible to setup one's own persistent cache, by passing a `storage` object as a connection option. This object should implement 3 methods: `getItem`, `setItem`, and `removeItem` (synchronous)
689
694
 
690
695
 
696
+ ## Auto-refresh caches
697
+
698
+ The SDK includes a mechnism to maintain the schemas and options caches up-to-date by polling the Campaign server on a regular basis (10 seconds by default). The server returns the list of entities (schemas or options) which have changed since they were cached, and the client removes them from the cache. When a schema changes, the corresponding methods are also removed from the method cache.
699
+
700
+ This mechanism is not activate by default but can be activated or deactivated by the following functions
701
+
702
+ ```js
703
+ client.startRefreshCaches(30000); // activate cache auto-refresh mechanism every 30s
704
+ client.stopRefreshCaches(); // de-activate cache auto-refresh
705
+ ```
706
+
707
+ This mechanism is based on the `xtk:session#GetModifiedEntities` SOAP method which is only available in Campaign 8.4 and above only. For other builds of Campaign, the auto-refresh mechanism will not do anything.
708
+
709
+ The following changes are handled:
710
+ * If the build number has changed, the whole cache is cleared
711
+ * If more than 10 schemas or options have changed, the whole cache is cleared
712
+ * if less than 10 schemas or options have changed, only those entities are removed from the cache
713
+
714
+
715
+ The refresh mechanism includes the following guardrails
716
+ * Both xtk:option and xtk:schema caches are refreshed every n seconds. To avoid issuing two API calls at the same time to the server, the schema cache refresh call is delayed by a few seconds. In the future this delay may change.
717
+ * If the xtk:session#GetModifiedEntities API is not available, the auto refresh mechanism will silently stop automatically
718
+ * If an error occurs while trying to refresh, a warning will be logged to the JavaScript console but the auto refresh will not be stopped.
719
+
691
720
  ## Passwords
692
721
 
693
722
  External account passwords can be decrypted using a Cipher. This function is deprecated since version 1.0.0 since it's not guaranteed to work in future versions of Campaign (V8 and above)
@@ -757,6 +786,49 @@ const query = client.NLWS
757
786
  await query.executeQuery();
758
787
  ```
759
788
 
789
+ ## Timeouts
790
+
791
+ By default, the SDK has a timeout of 5s when running in a node.js environment, and uses the browser defaults when run inside a browser (using the fetch API).
792
+
793
+ It is possible to overwrite the transport layer (see `The Transport Protocol` and use your own code to make and configure HTTP requests) to tune the timeout value. It is a bit cumbersome though.
794
+
795
+ Instead, you can use the `timeout` parameter, and set it either globally, as a connection parameter, or even at the API call level but using the `PushDown` mechanism described below.
796
+
797
+ Sets a timeout of 10s gloally
798
+ ```js
799
+ const connectionParameters = sdk.ConnectionParameters.ofUserAndPassword(
800
+ "https://myInstance.campaign.adobe.com",
801
+ "admin", "admin",
802
+ { timeout: 10000 });
803
+ ```
804
+
805
+ Override the timeout to 1 min for a particular API call
806
+ ```js
807
+ NLWS.xml.pushDown({ timeout: 60000 }).xtkBuilder.installPackage(dom);
808
+ ```
809
+
810
+ ## Pushdown mechanism
811
+ The Pushdown mechanism can be used to push down variables to the transport layer. A common use case it to pass a custom timeout value down to the transport layer.
812
+
813
+ The pushed down parameters are passed as a second parameter to the transport function. This parameter will contain all the connection parameters as well as any parameter that you can push down at the API call level. API call pushdowns can override default pushdowns.
814
+
815
+ Any key/value pairs can be pushed down. This example pushes down the timeout and foo variables to the transport layer.
816
+ ```js
817
+ NLWS.xml.pushDown({ timeout: 60000, foo: 'bar' }).xtkBuilder.installPackage(dom);
818
+ ```
819
+
820
+ ## Troubleshooting
821
+ In the version 1.1.5 of the SDK, we are automatically adding the SOAP method name in the URL in order to simplify troubleshooting. Normally, all SOAP method calls are make to the soaprouter.jsp endpoint, which makes it difficult to understand which actual API call is being made.
822
+ In fact the SOAP call name is available via the SOAPAction HTTP header, but it's usually not immediatelly visible.
823
+
824
+ The SOAP calls URLs are now formed like this: `http://acc-sdk:8080/nl/jsp/soaprouter.jsp?xtk:queryDef:ExecuteQuery` where the SOAP method name is added as a query parameter. Campaign server ignores this parameter.
825
+
826
+ This can be disabled using the `noMethodInURL` connection parameter
827
+
828
+ const connectionParameters = sdk.ConnectionParameters.ofUserAndPassword(
829
+ "https://myInstance.campaign.adobe.com",
830
+ "admin", "admin",
831
+ { noMethodInURL: true });
760
832
 
761
833
 
762
834
  # Samples
@@ -982,12 +1054,16 @@ The transport protocol defines
982
1054
  - What is the corresponding response
983
1055
  - How errors are handled
984
1056
 
985
- The transport protocol exports a single asynchronous function `request` which takes a `Request` literal object with the following attributes. Note that it matches axios requests.
1057
+ The transport protocol exports a single asynchronous function `request` which takes two parameters.
1058
+
1059
+ The first parameter is the request object with the following attributes. Note that it matches axios requests.
986
1060
  * `method` is the HTTP verb
987
1061
  * `url` is the URL to call
988
1062
  * `headers` is an object containing key value pairs with http headers and their values
989
1063
  * `data` is the request payload
990
1064
 
1065
+ The second parameter is an set of additional parameters that have been pushed down to the transport layer (see the `Pushdown` paragraph for more details). In particular, the `timeout` parameter should be honored by the transport layer.
1066
+
991
1067
  If the request is successful, a promise is returned with the result payload, as a string.
992
1068
 
993
1069
  If the request fails, the promise is rejected with an error object with class `HttpError`, a litteral with the following attributes:
@@ -995,7 +1071,7 @@ If the request fails, the promise is rejected with an error object with class `H
995
1071
  * `statusText` is the HTTP status text coming with the error
996
1072
  * `data` is the response data, if any
997
1073
 
998
- For proper error handling by the ACC SDK, it's important that the actual class of returned objects is names "HttpError"
1074
+ For proper error handling by the ACC SDK, it's important that the actual class of returned objects is named "HttpError"
999
1075
 
1000
1076
  The transport can be overriden by using the `client.setTransport` call and passing it a transport function, i.e. an async function which
1001
1077
  * Takes a `Request` object litteral as a parameter
@@ -1052,14 +1128,14 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1052
1128
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
1053
1129
  xmlns:ns="http://xml.apache.org/xml-soap">
1054
1130
  <SOAP-ENV:Header>
1055
- <Cookie>__sessiontoken=***</Cookie>
1056
- <X-Security-Token>***</X-Security-Token>
1131
+ <Cookie>__sessiontoken=***</Cookie>
1132
+ <X-Security-Token>***</X-Security-Token>
1057
1133
  </SOAP-ENV:Header>
1058
1134
  <SOAP-ENV:Body>
1059
- <m:GetOption xmlns:m="urn:xtk:session" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
1060
- <sessiontoken xsi:type="xsd:string">***</sessiontoken>
1061
- <name xsi:type="xsd:string">XtkDatabaseId</name>
1062
- </m:GetOption>
1135
+ <m:GetOption xmlns:m="urn:xtk:session" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
1136
+ <sessiontoken xsi:type="xsd:string">***</sessiontoken>
1137
+ <name xsi:type="xsd:string">XtkDatabaseId</name>
1138
+ </m:GetOption>
1063
1139
  </SOAP-ENV:Body>
1064
1140
  </SOAP-ENV:Envelope>
1065
1141
 
@@ -1069,10 +1145,10 @@ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
1069
1145
  xmlns:ns='urn:xtk:session'
1070
1146
  xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'>
1071
1147
  <SOAP-ENV:Body>
1072
- <GetOptionResponse xmlns='urn:xtk:session' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1073
- <pstrValue xsi:type='xsd:string'>uFE80000000000000F1FA913DD7CC7C4804BA419F</pstrValue>
1074
- <pbtType xsi:type='xsd:byte'>6</pbtType>
1075
- </GetOptionResponse>
1148
+ <GetOptionResponse xmlns='urn:xtk:session' SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
1149
+ <pstrValue xsi:type='xsd:string'>uFE80000000000000F1FA913DD7CC7C4804BA419F</pstrValue>
1150
+ <pbtType xsi:type='xsd:byte'>6</pbtType>
1151
+ </GetOptionResponse>
1076
1152
  </SOAP-ENV:Body>
1077
1153
  </SOAP-ENV:Envelope>
1078
1154
  `````
@@ -1461,6 +1537,7 @@ The `application` object can be obtained from a client, and will mimmic the Camp
1461
1537
  | Attribute/Method | Description |
1462
1538
  |---|---|
1463
1539
  | **buildNumber** | The server build number
1540
+ | **version** | In SDK version 1.1.4 and above, returns the server version formatted as major.minor.servicePack (ex: 8.2.10)
1464
1541
  | **instanceName** | The name of the Campaign instance
1465
1542
  | **operator** | Information about the current operator (i.e. logged user), of class `CurrentLogin`
1466
1543
  | **packages** | List of installed packages, as an array of strings
package/compile.js CHANGED
@@ -36,10 +36,11 @@ var resources = [
36
36
  { name: "./xtkEntityCache.js" },
37
37
  { name: "./methodCache.js" },
38
38
  { name: "./optionCache.js" },
39
+ { name: "./cacheRefresher.js" },
39
40
  { name: "./soap.js" },
40
41
  { name: "./crypto.js" },
41
- { name: "./testUtil.js" },
42
42
  { name: "./application.js" },
43
+ { name: "./testUtil.js" },
43
44
  { name: "./client.js" },
44
45
  { name: "./index.js" },
45
46
  ];
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@adobe/acc-js-sdk",
3
- "version": "1.1.3",
3
+ "version": "1.1.6",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@adobe/acc-js-sdk",
9
- "version": "1.1.3",
9
+ "version": "1.1.6",
10
10
  "license": "ISC",
11
11
  "dependencies": {
12
12
  "axios": "^0.25.0",
@@ -1402,14 +1402,21 @@
1402
1402
  }
1403
1403
  },
1404
1404
  "node_modules/caniuse-lite": {
1405
- "version": "1.0.30001301",
1406
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001301.tgz",
1407
- "integrity": "sha512-csfD/GpHMqgEL3V3uIgosvh+SVIQvCh43SNu9HRbP1lnxkKm1kjDG4f32PP571JplkLjfS+mg2p1gxR7MYrrIA==",
1405
+ "version": "1.0.30001378",
1406
+ "resolved": "https://artifactory.corp.adobe.com/artifactory/api/npm/npm-adobe-release/caniuse-lite/-/caniuse-lite-1.0.30001378.tgz",
1407
+ "integrity": "sha512-JVQnfoO7FK7WvU4ZkBRbPjaot4+YqxogSDosHv0Hv5mWpUESmN+UubMU6L/hGz8QlQ2aY5U0vR6MOs6j/CXpNA==",
1408
1408
  "dev": true,
1409
- "funding": {
1410
- "type": "opencollective",
1411
- "url": "https://opencollective.com/browserslist"
1412
- }
1409
+ "funding": [
1410
+ {
1411
+ "type": "opencollective",
1412
+ "url": "https://opencollective.com/browserslist"
1413
+ },
1414
+ {
1415
+ "type": "tidelift",
1416
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
1417
+ }
1418
+ ],
1419
+ "license": "CC-BY-4.0"
1413
1420
  },
1414
1421
  "node_modules/catharsis": {
1415
1422
  "version": "0.9.0",
@@ -6147,9 +6154,9 @@
6147
6154
  "dev": true
6148
6155
  },
6149
6156
  "caniuse-lite": {
6150
- "version": "1.0.30001301",
6151
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001301.tgz",
6152
- "integrity": "sha512-csfD/GpHMqgEL3V3uIgosvh+SVIQvCh43SNu9HRbP1lnxkKm1kjDG4f32PP571JplkLjfS+mg2p1gxR7MYrrIA==",
6157
+ "version": "1.0.30001378",
6158
+ "resolved": "https://artifactory.corp.adobe.com/artifactory/api/npm/npm-adobe-release/caniuse-lite/-/caniuse-lite-1.0.30001378.tgz",
6159
+ "integrity": "sha512-JVQnfoO7FK7WvU4ZkBRbPjaot4+YqxogSDosHv0Hv5mWpUESmN+UubMU6L/hGz8QlQ2aY5U0vR6MOs6j/CXpNA==",
6153
6160
  "dev": true
6154
6161
  },
6155
6162
  "catharsis": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/acc-js-sdk",
3
- "version": "1.1.3",
3
+ "version": "1.1.6",
4
4
  "description": "ACC Javascript SDK",
5
5
  "main": "src/index.js",
6
6
  "homepage": "https://github.com/adobe/acc-js-sdk#readme",
@@ -0,0 +1,60 @@
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
+ const { DomUtil } = require('../src/domUtil.js');
13
+ const sdk = require('../src/index.js');
14
+ const utils = require("./utils.js");
15
+
16
+
17
+ /**
18
+ * This sample illustrates how to generate and import packages
19
+ */
20
+
21
+ ( async () => {
22
+
23
+ await utils.sample({
24
+ title: "Testing generating and importing packages",
25
+ labels: [ "Basics", "Packages", "xtk:builder", "InstallPackage" ],
26
+ description: `The xtkBuilder.installPackage() can be used to import packages`,
27
+ code: async() => {
28
+ return await utils.logon(async (client, NLWS) => {
29
+ console.log(`Generating package with an option named AccJsSdk`);
30
+ const doc = sdk.DomUtil.newDocument('pkgDesc');
31
+ const package = doc.createElement('package');
32
+ doc.documentElement.appendChild(package);
33
+ package.setAttribute('namespace', 'cus');
34
+ package.setAttribute('name', 'sdk');
35
+ package.setAttribute('buildNumber', '*');
36
+ package.setAttribute('buildVersion', '*');
37
+ package.setAttribute('label', 'Test package for ACC JS SDK');
38
+ package.setAttribute('vendor', 'acc-js-sdk');
39
+
40
+ const entities = doc.createElement('entities');
41
+ package.appendChild(entities);
42
+ entities.setAttribute('schema', 'xtk:option');
43
+
44
+ const option = doc.createElement('option');
45
+ option.setAttribute('name', 'AccJsSdk');
46
+ option.setAttribute('dataType', '6');
47
+ const version = client.application.version;
48
+ option.setAttribute('stringValue', JSON.stringify(version));
49
+ entities.appendChild(option);
50
+
51
+ // Install package. The package is in XML format and we set the timeout to 5 mins to prevent any issues
52
+ console.log(`Installing package`, DomUtil.toXMLString(doc));
53
+ await NLWS.xml.pushDown({ timeout: 5*60*1000 }).xtkBuilder.installPackage(doc);
54
+ console.log(`Package installed`);
55
+ });
56
+ }
57
+ });
58
+
59
+ })();
60
+
@@ -65,20 +65,46 @@ function propagateImplicitValues(xtkDesc, labelOnly) {
65
65
  // ========================================================================================
66
66
  // Schema Cache
67
67
  // ========================================================================================
68
+
69
+ /**
70
+ * A cache of schemas of type `XtkSchema` instead of plain XML or JSON objects
71
+ *
72
+ * @private
73
+ * @class
74
+ * @constructor
75
+ * @memberof Campaign
76
+ */
77
+
68
78
  class SchemaCache {
69
79
  constructor(client) {
70
80
  this._client = client;
71
81
  this._schemas = {};
72
82
  }
83
+
84
+ /**
85
+ * Get a schema by id from schema cache of type `XtkSchema`
86
+ *
87
+ * @param {string} schemaId
88
+ * @returns {Campaign.XtkSchema} the schema, or null if the schema was not found
89
+ */
73
90
  async getSchema(schemaId) {
74
91
  let schema = this._schemas[schemaId];
75
92
  if (schema === undefined) {
76
93
  schema = await this._client.application._getSchema(schemaId);
77
94
  if (!schema) schema = null; // null = not found
78
- this._schemas[schemaId] = schema;
95
+ this._schemas[schemaId] = schema;
79
96
  }
80
97
  return schema;
81
98
  }
99
+
100
+ /**
101
+ * Remove a schema from schema cache. The callback function when refreshing cache in cacheRefresher
102
+ *
103
+ * @param {string} schemaId
104
+ */
105
+ invalidateCacheItem(schemaId) {
106
+ this._schemas[schemaId] = undefined;
107
+ }
82
108
  }
83
109
 
84
110
  // ========================================================================================
@@ -1207,29 +1233,43 @@ class Application {
1207
1233
  * The server build number
1208
1234
  * @type {string}
1209
1235
  */
1210
- this.buildNumber = EntityAccessor.getAttributeAsString(serverInfo, "buildNumber");
1236
+ this.buildNumber = EntityAccessor.getAttributeAsString(serverInfo, "buildNumber");
1237
+ /**
1238
+ * The server version, formatted as major.minor.servicePack (ex: 8.2.10)
1239
+ * @type {string}
1240
+ */
1241
+ this.version = EntityAccessor.getAttributeAsString(serverInfo, "majNumber") + "." +
1242
+ EntityAccessor.getAttributeAsString(serverInfo, "minNumber") + "." +
1243
+ EntityAccessor.getAttributeAsString(serverInfo, "servicePack");
1211
1244
  /**
1212
1245
  * The Campaign instance name
1213
1246
  * @type {string}
1214
1247
  */
1215
- this.instanceName = EntityAccessor.getAttributeAsString(serverInfo, "instanceName");
1248
+ this.instanceName = EntityAccessor.getAttributeAsString(serverInfo, "instanceName");
1216
1249
  const userInfo = EntityAccessor.getElement(info, "userInfo");
1217
1250
  /**
1218
1251
  * The logged operator
1219
1252
  * @type {Campaign.CurrentLogin}
1220
1253
  */
1221
- this.operator = new CurrentLogin(userInfo);
1254
+ this.operator = new CurrentLogin(userInfo);
1222
1255
  /**
1223
1256
  * The list of installed packages
1224
1257
  * @type {string[]}
1225
1258
  */
1226
- this.packages = [];
1259
+ this.packages = [];
1227
1260
  for (var p of EntityAccessor.getChildElements(userInfo, "installed-package")) {
1228
1261
  this.packages.push(`${EntityAccessor.getAttributeAsString(p, "namespace")}:${EntityAccessor.getAttributeAsString(p, "name")}`);
1229
1262
  }
1230
1263
  }
1231
1264
  }
1232
1265
 
1266
+ _registerCacheChangeListener() {
1267
+ this.client._registerCacheChangeListener(this._schemaCache);
1268
+ }
1269
+
1270
+ _unregisterCacheChangeListener() {
1271
+ this.client._unregisterCacheChangeListener(this._schemaCache);
1272
+ }
1233
1273
  /**
1234
1274
  * Get a schema by id. This function returns an XtkSchema object or null if the schema is not found.
1235
1275
  * Using the `XtkSchema` API makes it easier to navigate schemas than using a plain XML or JSON object
@@ -1241,7 +1281,7 @@ class Application {
1241
1281
  return this._schemaCache.getSchema(schemaId);
1242
1282
  }
1243
1283
 
1244
- // Private function: get a schema without using the cache
1284
+ // Private function: get a schema without using the SchemaCache
1245
1285
  async _getSchema(schemaId) {
1246
1286
  const xml = await this.client.getSchema(schemaId, "xml");
1247
1287
  if (!xml)
package/src/cache.js CHANGED
@@ -123,6 +123,7 @@ class SafeStorage {
123
123
  } catch(ex) { /* Ignore errors in safe class */
124
124
  }
125
125
  }
126
+
126
127
  }
127
128
 
128
129
  /**
@@ -243,7 +244,7 @@ class Cache {
243
244
 
244
245
  /**
245
246
  * Put a value from the cache
246
- * @param {*} key the key or keys of the value to retreive
247
+ * @param {*} key the key or keys of the value to retrieve
247
248
  * @param {*} value the value to cache
248
249
  * @returns {CachedObject} a cached object containing the cached value
249
250
  */
@@ -266,6 +267,15 @@ class Cache {
266
267
  this._cache = {};
267
268
  this._saveLastCleared();
268
269
  }
270
+
271
+ /**
272
+ * Remove a key from the cache
273
+ * @param {string} key the key to remove
274
+ */
275
+ remove(key) {
276
+ delete this._cache[key];
277
+ this._remove(key);
278
+ }
269
279
  }
270
280
 
271
281
  // Public expots