@adobe/acc-js-sdk 1.1.14 → 1.1.16
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/compile.js +1 -0
- package/docs/_data/navigation.yml +2 -0
- package/docs/_posts/2022-10-14-welcome.html +1 -1
- package/docs/changeLog.html +16 -2
- package/docs/escaping.html +4 -4
- package/docs/simpleJson.html +78 -5
- package/docs/transport.html +2 -2
- package/docs/xtkInterface.html +1 -1
- package/docs/xtkJob.html +131 -0
- package/docs/xtkQueryDef.html +1 -1
- package/package-lock.json +1 -1
- package/package.json +1 -1
- package/src/campaign.js +1 -1
- package/src/client.js +38 -27
- package/src/domUtil.js +67 -18
- package/src/index.js +6 -6
- package/src/soap.js +1 -1
- package/src/transport.js +0 -1
- package/src/util.js +19 -1
- package/src/xtkJob.js +337 -0
- package/test/client.test.js +22 -8
- package/test/domUtil.test.js +283 -33
- package/test/escape.test.js +3 -3
- package/test/mock.js +109 -1
- package/test/util.test.js +11 -3
- package/test/xtkJob.test.js +713 -0
package/compile.js
CHANGED
|
@@ -129,7 +129,7 @@ console.log(`About to call method '${methodName}' of scope '${scopeName}'`);
|
|
|
129
129
|
returnedValue = undefined;
|
|
130
130
|
}
|
|
131
131
|
// If the API returns one parameter which is an object, the return it directly.
|
|
132
|
-
// If not (return value is a
|
|
132
|
+
// If not (return value is a literal), then use a JSON with the return parameter name
|
|
133
133
|
else if (outNames.length == 1) {
|
|
134
134
|
if (result && typeof result == "object")
|
|
135
135
|
returnedValue = result;
|
package/docs/changeLog.html
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
layout: page
|
|
3
3
|
title: Change Log
|
|
4
4
|
---
|
|
5
|
+
<section class="changelog"><h1>Version 1.1.16</h1>
|
|
6
|
+
<h2>2022/11/29</h2>
|
|
7
|
+
|
|
8
|
+
<li>Added support for xtk:job interface and job-related methods. See <a href="https://opensource.adobe.com/acc-js-sdk/xtkJob.html">Jobs documentation</a> for more details</li>
|
|
9
|
+
</section>
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
<section class="changelog"><h1>Version 1.1.15</h1>
|
|
13
|
+
<h2>2022/11/28</h2>
|
|
14
|
+
|
|
15
|
+
<li>Fix an issue with SimpleJson serialization. See <a href="https://opensource.adobe.com/acc-js-sdk/simpleJson.html">SimpleJson documentation</a> for more details, and in particular the <b>Compatibility Notes</b> section</li>
|
|
16
|
+
<li>Fix credentials passing for fileUpload and getReportData methods. This is still a temporary fix until those APIs are made IMS compatible.</li>
|
|
17
|
+
</section>
|
|
18
|
+
|
|
5
19
|
<section class="changelog"><h1>Version 1.1.14</h1>
|
|
6
20
|
<h2>2022/11/25</h2>
|
|
7
21
|
|
|
@@ -202,7 +216,7 @@ For breaking changes see the [migration guide](MIGRATION.md)
|
|
|
202
216
|
<li><b>getEntityIfMoreRecent</b> now takes an additional parameter which allows to specify and force a representation (xml, json...)
|
|
203
217
|
<li>New helper function <b>DomUtil.isArray</b> to test if a JavaScript object is an array
|
|
204
218
|
<li>New <b>EntityAccessor</b> object which allows to get attributes and child elements from xml or json objects, regardless of their representation
|
|
205
|
-
<li>New <b>escapeXtk</b> function to escape
|
|
219
|
+
<li>New <b>escapeXtk</b> function to escape literal values in Xtk expression. Can be used as a function or as a tagged template literal
|
|
206
220
|
<li>New function <b>XtkCaster._variantStorageAttribute</b> which returns the name of a schema attribute used to store variant value types. The name of the attribute depends on the type: stringValue, longValue, etc.
|
|
207
221
|
<li>Support for non static method that mutate the object on which they apply. For instance, the <b>xtk:queryDef#SelectAll</b>
|
|
208
222
|
<li>Added samples in the samples/ folder
|
|
@@ -229,7 +243,7 @@ _Breaking changes in 1.0.0_
|
|
|
229
243
|
<li>Changes in the <b>sdk.init</b>, <b>Client</b> constructor, and <b>logon</b> functions. Now using <b>ConnectionParameters</b> and <b>Credentials</b> objects to configure a Campaign connection
|
|
230
244
|
<li>Client object members are now private: access to representation, etc. attributes is not allowed anymore except for <b>NLWS</b>, <b>XtkCaster</b>, and <b>DomUtil</b>
|
|
231
245
|
<li>Access to the <b>sessionInfo</b> object after <b>logon</b> can be done via the new <b>getSessionInfo</b> call
|
|
232
|
-
<li>Options cache internal strucutre change: option values in the cache are now object
|
|
246
|
+
<li>Options cache internal strucutre change: option values in the cache are now object literals containing the option value, type, and raw value (which may not be casted to the expected type yet)
|
|
233
247
|
<li>Connecting to mid-sourcing (or other Campaign instances which are defined by an external account) is now done with the <b>ConnectionParameters.ofExternalAccount</b> function. As a consequence, <b>getSecretKeyCipher</b> is now private and deprecated
|
|
234
248
|
<li>CampaignException object signature changed (but was not previously exposed)
|
|
235
249
|
<li>The client-side bundle is now generated in the <b>dist/bundle.js</b> file instead of <b>bundle.js</b>
|
package/docs/escaping.html
CHANGED
|
@@ -4,7 +4,7 @@ title: Escaping
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
<p>It's common to use variables in query conditions. For instance, in the above example, you'll want to query an account by name instead of using the hardcoded <b>ffda</b> name. The <b>expr</b> attribute takes an XTK expression as a parameter, and <b>ffda</b> is a string
|
|
7
|
+
<p>It's common to use variables in query conditions. For instance, in the above example, you'll want to query an account by name instead of using the hardcoded <b>ffda</b> name. The <b>expr</b> attribute takes an XTK expression as a parameter, and <b>ffda</b> is a string literal in an xtk expression.</p>
|
|
8
8
|
|
|
9
9
|
<p>To prevent xtk ingestions vulnerabilities, you should not concatenate strings and write code such as expr: "@name = '" + name + "'": if the value of the name
|
|
10
10
|
parameter contains single quotes, your code will not work, but could also cause vulnerabilities.
|
|
@@ -13,19 +13,19 @@ title: Escaping
|
|
|
13
13
|
|
|
14
14
|
<h1>sdk.escapeXtk</h1>
|
|
15
15
|
|
|
16
|
-
<p>The <b>sdk.escapeXtk</b> can be used to properly escape string
|
|
16
|
+
<p>The <b>sdk.escapeXtk</b> can be used to properly escape string literals in xtk expressions. The function will also surround the escaped value with single quotes.</p>
|
|
17
17
|
|
|
18
18
|
<p>You can use string concatenation like this. Note the lack of single quotes around the value.</p>
|
|
19
19
|
<pre class="code">
|
|
20
20
|
{ expr: "@name=" + sdk.escapeXtk(name) }
|
|
21
21
|
</pre>
|
|
22
22
|
|
|
23
|
-
<p>or a template
|
|
23
|
+
<p>or a template literal</p>
|
|
24
24
|
<pre class="code">
|
|
25
25
|
`{ expr: "@name=${sdk.escapeXtk(name)}" }`
|
|
26
26
|
</pre>
|
|
27
27
|
|
|
28
|
-
<p>The <b>escapeXtk</b> function can also be used to create tagged string
|
|
28
|
+
<p>The <b>escapeXtk</b> function can also be used to create tagged string literals. This leads to a much shorter syntax. Note that with this syntax, only the parameter values of the template literal are escaped</p>
|
|
29
29
|
<pre class="code">
|
|
30
30
|
sdk.escapeXtk`{ expr: "@name=${name}" }`
|
|
31
31
|
</pre>
|
package/docs/simpleJson.html
CHANGED
|
@@ -4,7 +4,7 @@ title: SimpleJson format
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<p>The <b>SimpleJson</b> format is the format used by default by the SDK to conver between Campaign XML and JSON</p>
|
|
7
|
-
|
|
7
|
+
<p></p>
|
|
8
8
|
|
|
9
9
|
<ul>
|
|
10
10
|
<li>XML attributes are JSON properties (without the “@” sign)</li>
|
|
@@ -27,6 +27,7 @@ title: SimpleJson format
|
|
|
27
27
|
</pre>
|
|
28
28
|
|
|
29
29
|
|
|
30
|
+
<h1>XML Root</h1>
|
|
30
31
|
<p>The XML root element tag is automatically determined by the SDK as it's generating the XML, usually from the current schema name.</p>
|
|
31
32
|
|
|
32
33
|
<pre class="code">
|
|
@@ -34,15 +35,21 @@ XML: <root/>
|
|
|
34
35
|
JSON: {}
|
|
35
36
|
</pre>
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
<h1>XML Attributes</h1>
|
|
42
|
+
<p>XML attributes are mapped to JSON attributes with the same name, whose literal value can be a string, number, or boolean. There's no "@" sign in the JSON attribute name.
|
|
43
|
+
Values in JSON attributes can be either typed (ex: number, boolean), or strings (ex: "3" instead of just 3) depending if the conversion could determine the attribute type or not.
|
|
44
|
+
API users should expect and handle both value and use the <b>XtkCaster</b> object to ensure proper conversion.</p>
|
|
40
45
|
|
|
41
46
|
<pre class="code">
|
|
42
47
|
XML <root hello="world" count="3" ok="true"/>
|
|
43
48
|
JSON: { hello:"world", count:"3", ok:"true" }
|
|
44
49
|
</pre>
|
|
45
50
|
|
|
51
|
+
|
|
52
|
+
<h1>XML Elements</h1>
|
|
46
53
|
<p>XML elements are mapped to JSON objects</p>
|
|
47
54
|
|
|
48
55
|
<pre class="code">
|
|
@@ -64,7 +71,9 @@ XML: <root><item id=1/><item id=2/></root>
|
|
|
64
71
|
JSON: { item: [ { id:"1" }, { id:"2" } ] }
|
|
65
72
|
</pre>
|
|
66
73
|
|
|
67
|
-
|
|
74
|
+
|
|
75
|
+
<h1>Text nodes</h1>
|
|
76
|
+
<p>Text of XML element is handled with the <b>$</b> sign in the JSON attribute name, or with a child JSON object name <b>$</b></p>
|
|
68
77
|
|
|
69
78
|
<p>Text of the root element</p>
|
|
70
79
|
<pre class="code">
|
|
@@ -86,3 +95,67 @@ XML: <root><item>Hello<child id="1"/>
|
|
|
86
95
|
</root>
|
|
87
96
|
JSON: { item: { $: "Hello", child: { id:"1" } }
|
|
88
97
|
</pre>
|
|
98
|
+
|
|
99
|
+
<p>Normally Campaign will not generate XML with elements containing multiple sibling text nodes. If this should happen, the SDK will consider them as a single text value, i.e. it will concatenate the contents of each text and CDATA node as if there was only one. However, whitespaces are processed independently for each text node.
|
|
100
|
+
</p>
|
|
101
|
+
|
|
102
|
+
<h1>Whitespaces</h1>
|
|
103
|
+
<p>In XML documents, whitespaces can be either significant or insignificant. The SDK uses the following rules to strip whitespaces, which correspond to how Campaign specifically uses XML</p>
|
|
104
|
+
<p> </p>
|
|
105
|
+
<ul>
|
|
106
|
+
<li>The characters " ", "\t", "\r" and "\n" are considered whitespaces</li>
|
|
107
|
+
<li>CDATA sections are kept unchanged, i.e. whitespaces are preserved exactly</li>
|
|
108
|
+
<li>For TEXT nodes directly under the root node are, whitespaces will be trimmed as explained below</li>
|
|
109
|
+
<li>For element nodes which only contain text and possibly attributes (for instance <node>value</node></li>, the text is kept unchanged, i.e. whitespaces are preserved exactly</li>
|
|
110
|
+
<li>For element nodes which have child elements, whitespaces will be trimmed as explained below</li>
|
|
111
|
+
<li>For the root element, whitespaces are always trimmed</li>
|
|
112
|
+
</ul>
|
|
113
|
+
<p> </p>
|
|
114
|
+
<p>
|
|
115
|
+
Whitespace trimming consists of removing all the leading and trailing whitespaces of each text node and concatenating all text node values. If the resulting value is empty, the text node is ignored. The rationale is to remove insignificant spaces created when formatting XML documents
|
|
116
|
+
</p>
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
<h1>Exceptions</h1>
|
|
120
|
+
|
|
121
|
+
<h2>When an attribute has the same name of an element</h2>
|
|
122
|
+
|
|
123
|
+
<p>If an element contains another element and an attribute which have the same name, the attribute name is prefixed with the "@" character</p>
|
|
124
|
+
<pre class="code">
|
|
125
|
+
XML: <root timezone="Europe/Paris">
|
|
126
|
+
<timezone>Europe/Paris</timezone>
|
|
127
|
+
</root>
|
|
128
|
+
JSON: { "@timezone": "Europe/Paris",
|
|
129
|
+
timezone: { "$": "Europe/Paris" } }
|
|
130
|
+
</pre>
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
<h1>Arrays of text elements</h1>
|
|
134
|
+
<p></p>
|
|
135
|
+
<pre class="code">
|
|
136
|
+
XML: <root>
|
|
137
|
+
<item>One</item>
|
|
138
|
+
<item>Two</item>
|
|
139
|
+
</root>
|
|
140
|
+
JSON: { item: [
|
|
141
|
+
{ $: "One" },
|
|
142
|
+
{ $: "Two" }
|
|
143
|
+
] }
|
|
144
|
+
</pre>
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
<h1>Compatibility notes</h1>
|
|
149
|
+
|
|
150
|
+
<p>
|
|
151
|
+
A few gaps were identified regarding SimpleJson format when converting from XML to JSON. They were fixed in release 1.1.15 and may introduce some behavior changes for cases which were ambiguous
|
|
152
|
+
</p>
|
|
153
|
+
<p> </p>
|
|
154
|
+
<ul>
|
|
155
|
+
<li>When XML element has both a text content and attributes or child elements</li>
|
|
156
|
+
<li>When root element has only text</li>
|
|
157
|
+
<li>When XML element has both an attribute and a child element with the same name</li>
|
|
158
|
+
<li>When array contains element which only have text</li>
|
|
159
|
+
<li>When XML is formatted (and therefore has insignificant whitespaces)</li>
|
|
160
|
+
<li>XML collections (i.e. when root node ends with “-collection”) would sometimes contain a JSON property “#text”</li>
|
|
161
|
+
</ul>
|
package/docs/transport.html
CHANGED
|
@@ -27,7 +27,7 @@ title: The Transport Protocol
|
|
|
27
27
|
|
|
28
28
|
<p>If the request is successful, a promise is returned with the result payload, as a string.</p>
|
|
29
29
|
|
|
30
|
-
<p>If the request fails, the promise is rejected with an error object with class <b>HttpError</b>, a
|
|
30
|
+
<p>If the request fails, the promise is rejected with an error object with class <b>HttpError</b>, a literal with the following attributes:</p>
|
|
31
31
|
<ul>
|
|
32
32
|
<li><b>statusCode</b> is the HTTP status code, such as 404, 500, etc.</li>
|
|
33
33
|
<li><b>statusText</b> is the HTTP status text coming with the error</li>
|
|
@@ -39,7 +39,7 @@ title: The Transport Protocol
|
|
|
39
39
|
<p>The transport can be overriden by using the <b>client.setTransport</b> call and passing it a transport function, i.e. an async function which</p>
|
|
40
40
|
|
|
41
41
|
<ul>
|
|
42
|
-
<li>Takes a <b>Request</b> object
|
|
42
|
+
<li>Takes a <b>Request</b> object literal as a parameter</li>
|
|
43
43
|
<li>Returns a the request result in a promise</li>
|
|
44
44
|
<li>Returns a rejected promise containing an <b>HttpError</b> in case of failure</li>
|
|
45
45
|
</ul>
|
package/docs/xtkInterface.html
CHANGED
|
@@ -17,4 +17,4 @@ const delivery = client.NLWS.nmsDelivery.create({ label: "Hello" });
|
|
|
17
17
|
await delivery.newInstance();
|
|
18
18
|
</pre>
|
|
19
19
|
|
|
20
|
-
<p>There are 2 common interfaces: <a href="{{ site.baseurl }}/xtkPersist.html">xtk:persist</a> and <a href="">xtk:jobInterface</a> which are documented below.</p>
|
|
20
|
+
<p>There are 2 common interfaces: <a href="{{ site.baseurl }}/xtkPersist.html">xtk:persist</a> and <a href="{{ site.baseurl }}/xtkJob.html">xtk:jobInterface</a> which are documented below.</p>
|
package/docs/xtkJob.html
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: page
|
|
3
|
+
title: XTK Jobs (xkt:job, xkt:jobInterface)
|
|
4
|
+
---
|
|
5
|
+
<p>This section describes how long running jobs are handled in ACC and ACC api. There are 2 schemas for jobs</p>
|
|
6
|
+
<ul>
|
|
7
|
+
<li>xtk:job which represents an acutal job, and which is implemented by several objects such as nms:delivery</li>
|
|
8
|
+
<li>xtk:jobInterface which contains methods to submit jobs and get their statuses. Other schemas do not actually implement the xtk:jobInterface interface</li>
|
|
9
|
+
</ul>
|
|
10
|
+
|
|
11
|
+
<p>In term of SOAP calls, running a job is simply executing a SOAP call synchronously or asynchronously in a separate thread or process. However, calls must be made on both the xtk:jobInterface and job entity schema. The SDK provides a helper interface to submit and handle jobs</p>
|
|
12
|
+
|
|
13
|
+
<h1>Simple Jobs</h1>
|
|
14
|
+
|
|
15
|
+
<p>
|
|
16
|
+
Simple jobs are non-static methods with no parameters, such as the nms:delivery#Prepare method which is used to prepare a delivery.
|
|
17
|
+
Such jobs can be executed synchronously (xtk:jobInterface#Execute) or asynchronously (xtk:jobInterface#Submit). Both methods return
|
|
18
|
+
a job id which can be used to retreive (poll) more about the job.
|
|
19
|
+
<p>
|
|
20
|
+
|
|
21
|
+
<p>
|
|
22
|
+
First, we need to retreive a delivery, which is the object upon which to run the Prepare method, but also implements xtk:job interface.
|
|
23
|
+
The Prepare method requires a complete delivery object, so we use SelectAll
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
<pre class="code">
|
|
27
|
+
const queryDef = {
|
|
28
|
+
schema: "nms:delivery",
|
|
29
|
+
operation: "get",
|
|
30
|
+
select: { node: [ { expr: "@id" } ] },
|
|
31
|
+
where: { condition: [ { expr:`@internalName='DM19'` } ] }
|
|
32
|
+
}
|
|
33
|
+
const query = NLWS.xtkQueryDef.create(queryDef);
|
|
34
|
+
await query.selectAll();
|
|
35
|
+
const delivery = await query.executeQuery();
|
|
36
|
+
</pre>
|
|
37
|
+
|
|
38
|
+
<p>
|
|
39
|
+
Now we can create a job for the Prepare method using the <b>client.jobInterface</b> function which returns a XtkJobInterface object.
|
|
40
|
+
We pass it a job specification containing the schema, method, and object
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
<pre class="code">
|
|
44
|
+
const job = await client.jobInterface({
|
|
45
|
+
xtkschema: 'nms:delivery',
|
|
46
|
+
method: 'Prepare',
|
|
47
|
+
object: delivery
|
|
48
|
+
});
|
|
49
|
+
</pre>
|
|
50
|
+
|
|
51
|
+
<p>
|
|
52
|
+
Finally we can submit the job and get it's status, progress, result, etc.
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
<pre class="code">
|
|
56
|
+
await job.submit();
|
|
57
|
+
var status = await job.getStatus();
|
|
58
|
+
</pre>
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
<h1>Soap calls</h1>
|
|
62
|
+
<p>
|
|
63
|
+
The <b>SubmitSoapCall</b> method allows to run more complex jobs with parameters. The principle is the same, for instance calling the <b>PrepareProof</b> method
|
|
64
|
+
which takes a boolean parameter
|
|
65
|
+
</p>
|
|
66
|
+
|
|
67
|
+
<pre class="code">
|
|
68
|
+
const job = await client.jobInterface({
|
|
69
|
+
xtkschema: 'nms:delivery',
|
|
70
|
+
method: 'PrepareProof',
|
|
71
|
+
object: delivery,
|
|
72
|
+
args: [ false ]
|
|
73
|
+
});
|
|
74
|
+
</pre>
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
<h1>Job Status</h1>
|
|
78
|
+
<p>
|
|
79
|
+
The status of a job is made of 3 pieces of information
|
|
80
|
+
</p>
|
|
81
|
+
<ul>
|
|
82
|
+
<li>The job status code</li>
|
|
83
|
+
<li>Job logs</li>
|
|
84
|
+
<li>Job properties which are arbitrary key value pairs and also contain progress information</li>
|
|
85
|
+
</ul>
|
|
86
|
+
|
|
87
|
+
<p>
|
|
88
|
+
For convenience, the SDK provides a <b>getStatus</b> function which will fetch and return the full job status object with strong
|
|
89
|
+
typing. When getStatus is called several time, each call will fetch the most recent status, and new logs since the previous call.
|
|
90
|
+
</p>
|
|
91
|
+
|
|
92
|
+
<table>
|
|
93
|
+
<thead>
|
|
94
|
+
<tr><th>Status code</th><th>Description</th></tr>
|
|
95
|
+
</thead>
|
|
96
|
+
<tbody>
|
|
97
|
+
<tr><td><b>0</b></td><td>Being edited</td></tr>
|
|
98
|
+
<tr><td><b>2</b></td><td>Running: execution is in progress</td></tr>
|
|
99
|
+
<tr><td><b>3</b></td><td>Canceling: a cancel request was submitted and the job will be canceld as soon as possible</td></tr>
|
|
100
|
+
<tr><td><b>4</b></td><td>Canceled</td></tr>
|
|
101
|
+
<tr><td><b>5</b></td><td>Finished: the job has finished successfully and getResult can be called</td></tr>
|
|
102
|
+
<tr><td><b>6</b></td><td>Error: the job failed. Details about the error can be found in the logs</td></tr>
|
|
103
|
+
<tr><td><b>7</b></td><td>Pause pending: a pause request was submitted and the job will be paused as soon as possible</td></tr>
|
|
104
|
+
<tr><td><b>8</b></td><td>Pause: the job is paused</td></tr>
|
|
105
|
+
<tr><td><b>9</b></td><td>Purge pending: a purge request was submitted and the job will be purged as soon as possible</td></tr>
|
|
106
|
+
</tbody>
|
|
107
|
+
</table>
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
<h1>Job Progress</h1>
|
|
111
|
+
<p>
|
|
112
|
+
The progress of a job is available as 2 integers: current and max which represent the current progression and max value for progression.
|
|
113
|
+
Both values are returned by the getStatus call as properties (i.e. <b>properties.progress.current</b> and <b>properties.progress.max</b>).
|
|
114
|
+
The SDK provides the <b>getProgress</b> function to retreive the progress as a percentage (and a valid number)
|
|
115
|
+
</p>
|
|
116
|
+
|
|
117
|
+
<pre class="code">
|
|
118
|
+
// Returns progress as a percentage in the [0..1] range
|
|
119
|
+
var progressPercent = job.getProgress();
|
|
120
|
+
</pre>
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
<h1>Job Result</h1>
|
|
124
|
+
<p>
|
|
125
|
+
Typically, a client would call the getStatus method every few seconds to get updates on the progress. When a job is finished and successfull,
|
|
126
|
+
one can get the result using the <b>getResult</b> function
|
|
127
|
+
</p>
|
|
128
|
+
|
|
129
|
+
<pre class="code">
|
|
130
|
+
var result = await job.getResult();
|
|
131
|
+
</pre>
|
package/docs/xtkQueryDef.html
CHANGED
|
@@ -74,7 +74,7 @@ const extAccount = await query.executeQuery();
|
|
|
74
74
|
|
|
75
75
|
|
|
76
76
|
<h1>Escaping</h1>
|
|
77
|
-
<p>It's common to use variables in query conditions. For instance, in the above example, you'll want to query an account by name instead of using the hardcoded <b>ffda</b> name. The <b>expr</b> attribute takes an XTK expression as a parameter, and <b>ffda</b> is a string
|
|
77
|
+
<p>It's common to use variables in query conditions. For instance, in the above example, you'll want to query an account by name instead of using the hardcoded <b>ffda</b> name. The <b>expr</b> attribute takes an XTK expression as a parameter, and <b>ffda</b> is a string literal in an xtk expression.</p>
|
|
78
78
|
|
|
79
79
|
<p>To prevent xtk ingestions vulnerabilities, you should not concatenate strings and write code such as expr: "@name = '" + name + "'": if the value of the name
|
|
80
80
|
parameter contains single quotes, your code will not work, but could also cause vulnerabilities.
|
package/package-lock.json
CHANGED
package/package.json
CHANGED
package/src/campaign.js
CHANGED
|
@@ -28,7 +28,7 @@ const { Util } = require("./util.js");
|
|
|
28
28
|
static INVALID_CREDENTIALS_TYPE(type, details) { return new CampaignException(undefined, 400, 16384, `SDK-000000 Invalid credentials type '${type}'`, details); }
|
|
29
29
|
static CANNOT_GET_CREDENTIALS_USER(type) { return new CampaignException(undefined, 400, 16384, `SDK-000001 Cannot get user for Credentials of type '${type}'`); }
|
|
30
30
|
static CANNOT_GET_CREDENTIALS_PASSWORD(type) { return new CampaignException(undefined, 400, 16384, `SDK-000002 Cannot get password for Credentials of type '${type}'`); }
|
|
31
|
-
static INVALID_CONNECTION_OPTIONS(options) { return new CampaignException(undefined, 400, 16384, `SDK-000003 Invalid options parameter (type '${typeof options}'). An object
|
|
31
|
+
static INVALID_CONNECTION_OPTIONS(options) { return new CampaignException(undefined, 400, 16384, `SDK-000003 Invalid options parameter (type '${typeof options}'). An object literal is expected`); }
|
|
32
32
|
static INVALID_REPRESENTATION(representation, details) { return new CampaignException(undefined, 400, 16384, `SDK-000004 Invalid representation '${representation}'.`, details); }
|
|
33
33
|
static CREDENTIALS_FOR_INVALID_EXT_ACCOUNT(name, type) { return new CampaignException(undefined, 400, 16384, `SDK-000005 Cannot created connection parameters for external account '${name}': account type ${type} not supported`); }
|
|
34
34
|
static BAD_PARAMETER(name, value, details) { return new CampaignException(undefined, 400, 16384, `SDK-000006 Bad parameter '${name}' with value '${value}'`, details); }
|
package/src/client.js
CHANGED
|
@@ -36,6 +36,7 @@ const request = require('./transport.js').request;
|
|
|
36
36
|
const Application = require('./application.js').Application;
|
|
37
37
|
const EntityAccessor = require('./entityAccessor.js').EntityAccessor;
|
|
38
38
|
const { Util } = require('./util.js');
|
|
39
|
+
const { XtkJobInterface } = require('./xtkJob.js');
|
|
39
40
|
const qsStringify = require('qs-stringify');
|
|
40
41
|
|
|
41
42
|
/**
|
|
@@ -173,16 +174,7 @@ const clientHandler = (representation, headers, pushDownOptions) => {
|
|
|
173
174
|
return callContext;
|
|
174
175
|
|
|
175
176
|
// get Schema id from namespace (find first upper case letter)
|
|
176
|
-
|
|
177
|
-
for (var i=0; i<namespace.length; i++) {
|
|
178
|
-
const c = namespace[i];
|
|
179
|
-
if (c >='A' && c<='Z') {
|
|
180
|
-
schemaId = schemaId + ":" + c.toLowerCase() + namespace.substr(i+1);
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
schemaId = schemaId + c;
|
|
184
|
-
}
|
|
185
|
-
callContext.schemaId = schemaId;
|
|
177
|
+
callContext.schemaId = Util.schemaIdFromNamespace(namespace);
|
|
186
178
|
|
|
187
179
|
const caller = function(thisArg, argumentsList) {
|
|
188
180
|
const callContext = thisArg["."];
|
|
@@ -546,16 +538,14 @@ const fileUploader = (client) => {
|
|
|
546
538
|
}
|
|
547
539
|
const data = new FormData();
|
|
548
540
|
data.append('file_noMd5', file);
|
|
549
|
-
//TODO: Needs to be refactored after cookie issue get resolved.
|
|
550
541
|
client._makeHttpCall({
|
|
551
542
|
url: `${client._connectionParameters._endpoint}/nl/jsp/uploadFile.jsp`,
|
|
552
543
|
processData: false,
|
|
553
|
-
credentials: 'include',
|
|
554
544
|
method: 'POST',
|
|
555
545
|
data: data,
|
|
556
546
|
headers: {
|
|
557
|
-
'
|
|
558
|
-
'
|
|
547
|
+
'X-Security-Token': client._securityToken,
|
|
548
|
+
'X-Session-Token': client._sessionToken,
|
|
559
549
|
}
|
|
560
550
|
}).then((okay) => {
|
|
561
551
|
if (!okay.startsWith('Ok')) {
|
|
@@ -1475,11 +1465,21 @@ class Client {
|
|
|
1475
1465
|
const result = [];
|
|
1476
1466
|
const schemaId = callContext.schemaId;
|
|
1477
1467
|
|
|
1478
|
-
var
|
|
1468
|
+
var entitySchemaId = schemaId;
|
|
1469
|
+
if (schemaId === 'xtk:jobInterface')
|
|
1470
|
+
entitySchemaId = callContext.entitySchemaId;
|
|
1471
|
+
|
|
1472
|
+
// Get the schema which contains the method call. Methods of the xtk:jobInterface interface are handled specificaaly
|
|
1473
|
+
// because xtk:jobInterface is not actually a schema, but just an interface. In practice, it's used as an xtk template
|
|
1474
|
+
// rather that an xtk inheritance mechanism
|
|
1475
|
+
const methodSchemaId = schemaId === 'xtk:jobInterface' ? 'xtk:job' : schemaId;
|
|
1476
|
+
var schema = await that.getSchema(methodSchemaId, "xml", true);
|
|
1479
1477
|
if (!schema)
|
|
1480
1478
|
throw CampaignException.SOAP_UNKNOWN_METHOD(schemaId, methodName, `Schema '${schemaId}' not found`);
|
|
1481
1479
|
var schemaName = schema.getAttribute("name");
|
|
1482
|
-
|
|
1480
|
+
|
|
1481
|
+
// Lookup the method to call
|
|
1482
|
+
var method = that._methodCache.get(methodSchemaId, methodName);
|
|
1483
1483
|
if (!method) {
|
|
1484
1484
|
// first char of the method name may be lower case (ex: nms:seedMember.getAsModel) but the methodName
|
|
1485
1485
|
// variable has been capitalized. Make an attempt to lookup method name without capitalisation
|
|
@@ -1489,13 +1489,16 @@ class Client {
|
|
|
1489
1489
|
}
|
|
1490
1490
|
if (!method) {
|
|
1491
1491
|
this._methodCache.put(schema);
|
|
1492
|
-
method = that._methodCache.get(
|
|
1492
|
+
method = that._methodCache.get(methodSchemaId, methodName);
|
|
1493
1493
|
}
|
|
1494
1494
|
if (!method)
|
|
1495
1495
|
throw CampaignException.SOAP_UNKNOWN_METHOD(schemaId, methodName, `Method '${methodName}' of schema '${schemaId}' not found`);
|
|
1496
|
-
// console.log(method.toXMLString());
|
|
1497
1496
|
|
|
1498
|
-
|
|
1497
|
+
// Compute the SOAP URN. Again, specically handle xtk:jobInterface as it's not a real schema. The actual entity schema
|
|
1498
|
+
// would be available as the entitySchemaId property of the callContext
|
|
1499
|
+
var urn = schemaId !== 'xtk:jobInterface' ? that._methodCache.getSoapUrn(schemaId, methodName)
|
|
1500
|
+
: `xtk:jobInterface|${entitySchemaId}`;
|
|
1501
|
+
|
|
1499
1502
|
var soapCall = that._prepareSoapCall(urn, methodName, false, callContext.headers, callContext.pushDownOptions);
|
|
1500
1503
|
|
|
1501
1504
|
// If method is called with one parameter which is a function, then we assume it's a hook: the function will return
|
|
@@ -1512,13 +1515,13 @@ class Client {
|
|
|
1512
1515
|
if (!object)
|
|
1513
1516
|
throw CampaignException.SOAP_UNKNOWN_METHOD(schemaId, methodName, `Cannot call non-static method '${methodName}' of schema '${schemaId}' : no object was specified`);
|
|
1514
1517
|
|
|
1515
|
-
const rootName =
|
|
1518
|
+
const rootName = entitySchemaId.substr(entitySchemaId.indexOf(':') + 1);
|
|
1516
1519
|
object = that._fromRepresentation(rootName, object, callContext.representation);
|
|
1517
1520
|
// The xtk:persist#NewInstance requires a xtkschema attribute which we can compute here
|
|
1518
1521
|
// Actually, we're always adding it, for all non-static methods
|
|
1519
1522
|
const xmlRoot = object.nodeType === 9 ? object.documentElement : object;
|
|
1520
1523
|
if (!xmlRoot.hasAttribute("xtkschema"))
|
|
1521
|
-
xmlRoot.setAttribute("xtkschema",
|
|
1524
|
+
xmlRoot.setAttribute("xtkschema", entitySchemaId);
|
|
1522
1525
|
soapCall.writeDocument("document", object);
|
|
1523
1526
|
}
|
|
1524
1527
|
const parametersIsArray = (typeof parameters == "object") && parameters.length;
|
|
@@ -1527,7 +1530,7 @@ class Client {
|
|
|
1527
1530
|
var param = DomUtil.getFirstChildElement(params, "param");
|
|
1528
1531
|
var paramIndex = 0;
|
|
1529
1532
|
while (param) {
|
|
1530
|
-
|
|
1533
|
+
const inout = DomUtil.getAttributeAsString(param, "inout");
|
|
1531
1534
|
if (!inout || inout=="in") {
|
|
1532
1535
|
const type = DomUtil.getAttributeAsString(param, "type");
|
|
1533
1536
|
const paramName = DomUtil.getAttributeAsString(param, "name");
|
|
@@ -1570,9 +1573,9 @@ class Client {
|
|
|
1570
1573
|
// Hack for workflow API. The C++ code checks that the name of the XML element is <variables>. When
|
|
1571
1574
|
// using xml representation at the SDK level, it's ok since the SDK caller will set that. But this does
|
|
1572
1575
|
// not work when using "BadgerFish" representation where we do not know the root element name.
|
|
1573
|
-
if (
|
|
1576
|
+
if (entitySchemaId == "xtk:workflow" && methodName == "StartWithParameters" && paramName == "parameters")
|
|
1574
1577
|
docName = "variables";
|
|
1575
|
-
if (
|
|
1578
|
+
if (entitySchemaId == "nms:rtEvent" && methodName == "PushEvent")
|
|
1576
1579
|
docName = "rtEvent";
|
|
1577
1580
|
// Try to guess the document name. This is usually available in the xtkschema attribute
|
|
1578
1581
|
var xtkschema = EntityAccessor.getAttributeAsString(paramValue, "xtkschema");
|
|
@@ -1636,7 +1639,7 @@ class Client {
|
|
|
1636
1639
|
else if (type == "DOMDocument") {
|
|
1637
1640
|
returnValue = soapCall.getNextDocument();
|
|
1638
1641
|
returnValue = that._toRepresentation(returnValue, callContext.representation);
|
|
1639
|
-
if (
|
|
1642
|
+
if (entitySchemaId === "xtk:queryDef" && methodName === "ExecuteQuery" && paramName === "output") {
|
|
1640
1643
|
// https://github.com/adobe/acc-js-sdk/issues/3
|
|
1641
1644
|
// Check if query operation is "getIfExists". The "object" variable at this point
|
|
1642
1645
|
// is always an XML, regardless of the xml/json representation
|
|
@@ -1794,11 +1797,10 @@ class Client {
|
|
|
1794
1797
|
url: `${this._connectionParameters._endpoint}/report/${callContext.reportName}?${encodeURI(`_noRender=true&_schema=${callContext.schema}&_context=${callContext.context}&_selection=${callContext.selection}`)}&_selectionCount=${selectionCount}`,
|
|
1795
1798
|
headers: {
|
|
1796
1799
|
'X-Security-Token': this._securityToken,
|
|
1797
|
-
'
|
|
1800
|
+
'X-Session-Token': this._sessionToken,
|
|
1798
1801
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
1799
1802
|
},
|
|
1800
1803
|
method: 'POST',
|
|
1801
|
-
credentials: 'include',
|
|
1802
1804
|
data : qsStringify(callContext.formData)
|
|
1803
1805
|
};
|
|
1804
1806
|
|
|
@@ -1871,6 +1873,15 @@ class Client {
|
|
|
1871
1873
|
const result = this._toRepresentation(doc);
|
|
1872
1874
|
return result;
|
|
1873
1875
|
}
|
|
1876
|
+
|
|
1877
|
+
/**
|
|
1878
|
+
* Creates a Job object which can be used to submit jobs, retrieve status, logs and progress, etc.
|
|
1879
|
+
* @param {Campaign.XtkSoapCallSpec} soapCallSpec the definition of the SOAP call
|
|
1880
|
+
* @returns {Campaign.XtkJobInterface} a job
|
|
1881
|
+
*/
|
|
1882
|
+
jobInterface(soapCallSpec) {
|
|
1883
|
+
return new XtkJobInterface(this, soapCallSpec);
|
|
1884
|
+
}
|
|
1874
1885
|
}
|
|
1875
1886
|
|
|
1876
1887
|
|