@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 +2 -1
- package/CHANGELOG.md +23 -0
- package/README.md +104 -27
- package/compile.js +2 -1
- package/package-lock.json +19 -12
- package/package.json +1 -1
- package/samples/011 - basics - packages.js +60 -0
- package/src/application.js +46 -6
- package/src/cache.js +11 -1
- package/src/cacheRefresher.js +227 -0
- package/src/client.js +96 -23
- package/src/index.js +3 -1
- package/src/soap.js +18 -12
- package/src/testUtil.js +2 -2
- package/src/transport.js +17 -2
- package/test/application.test.js +13 -2
- package/test/cacheRefresher.test.js +338 -0
- package/test/caches.test.js +16 -1
- package/test/client.test.js +314 -6
- package/test/mock.js +66 -1
- package/test/soap.test.js +45 -31
- package/.vscode/launch.json +0 -22
package/.eslintrc.js
CHANGED
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
|
-
|
|
193
|
-
|
|
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
|
-
|
|
208
|
-
|
|
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"
|
|
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
|
-
|
|
514
|
-
|
|
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
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
1056
|
-
|
|
1131
|
+
<Cookie>__sessiontoken=***</Cookie>
|
|
1132
|
+
<X-Security-Token>***</X-Security-Token>
|
|
1057
1133
|
</SOAP-ENV:Header>
|
|
1058
1134
|
<SOAP-ENV:Body>
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
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
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
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
|
+
"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.
|
|
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.
|
|
1406
|
-
"resolved": "https://
|
|
1407
|
-
"integrity": "sha512-
|
|
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
|
-
|
|
1411
|
-
|
|
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.
|
|
6151
|
-
"resolved": "https://
|
|
6152
|
-
"integrity": "sha512-
|
|
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
|
@@ -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
|
+
|
package/src/application.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1254
|
+
this.operator = new CurrentLogin(userInfo);
|
|
1222
1255
|
/**
|
|
1223
1256
|
* The list of installed packages
|
|
1224
1257
|
* @type {string[]}
|
|
1225
1258
|
*/
|
|
1226
|
-
|
|
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
|
|
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
|
|
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
|