@adobe/acc-js-sdk 1.1.10 → 1.1.11
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/README.md +8 -2170
- package/docs/404.html +11 -0
- package/docs/Gemfile +35 -0
- package/docs/Gemfile.lock +270 -0
- package/docs/_config.yml +55 -0
- package/docs/_data/navigation.yml +119 -0
- package/docs/_includes/navigation.html +33 -0
- package/docs/_layouts/default.html +21 -0
- package/docs/_layouts/home.html +4 -0
- package/docs/_layouts/page.html +5 -0
- package/docs/_layouts/post.html +7 -0
- package/docs/_posts/2022-10-14-welcome.html +149 -0
- package/docs/application.html +366 -0
- package/docs/architecture.html +24 -0
- package/docs/assets/css/styles.css +362 -0
- package/docs/assets/images/adobe-campaign-256.png +0 -0
- package/docs/assets/images/architecture.png +0 -0
- package/docs/assets/images/ref.svg +6 -0
- package/docs/badgerFish.html +14 -0
- package/docs/bestPractices.html +189 -0
- package/docs/blog.html +18 -0
- package/docs/buildAndRun.html +96 -0
- package/docs/caches.html +68 -0
- package/docs/changeLog.html +256 -0
- package/docs/checkList.html +168 -0
- package/docs/concepts.html +130 -0
- package/docs/connecting.html +210 -0
- package/docs/connectionParameters.html +109 -0
- package/docs/contribute.html +54 -0
- package/docs/dataTypes.html +124 -0
- package/docs/differences.html +4 -0
- package/docs/documentation.html +21 -0
- package/docs/domHelper.html +88 -0
- package/docs/dynamicInvoke.html +36 -0
- package/docs/entityAccessor.html +22 -0
- package/docs/errors.html +47 -0
- package/docs/escaping.html +76 -0
- package/docs/favicon.png +0 -0
- package/docs/healthCheck.html +66 -0
- package/docs/httpHeaders.html +78 -0
- package/docs/index.html +64 -0
- package/docs/installation.html +34 -0
- package/docs/license.html +208 -0
- package/docs/messageCenter.html +80 -0
- package/docs/methodLevelRepresentation.html +12 -0
- package/docs/midSourcing.html +19 -0
- package/docs/observability.html +169 -0
- package/docs/passwords.html +27 -0
- package/docs/profiles.html +103 -0
- package/docs/pushDown.html +13 -0
- package/docs/quickstart.html +69 -0
- package/docs/release.html +52 -0
- package/docs/samples.html +82 -0
- package/docs/simpleJson.html +88 -0
- package/docs/soapAPIs.html +234 -0
- package/docs/timeouts.html +23 -0
- package/docs/transport.html +45 -0
- package/docs/troubleshooting.html +17 -0
- package/docs/writeDoc.html +208 -0
- package/docs/xml2json.html +96 -0
- package/docs/xtkCaster.html +67 -0
- package/docs/xtkInterface.html +20 -0
- package/docs/xtkOption.html +54 -0
- package/docs/xtkPackage.html +16 -0
- package/docs/xtkPersist.html +213 -0
- package/docs/xtkQueryDef.html +245 -0
- package/docs/xtkSchema.html +39 -0
- package/docs/xtkSession.html +29 -0
- package/docs/xtkWorkflow.html +28 -0
- package/docs/xtkWrite.html +51 -0
- package/package-lock.json +1 -1
- package/package.json +1 -1
- package/src/campaign.js +1 -1
- package/src/soap.js +6 -6
- package/test/soap.test.js +13 -0
- package/CHANGELOG.md +0 -252
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: post
|
|
3
|
+
title: "Welcome to the ACC JS SDK"
|
|
4
|
+
date: 2022-10-14 09:06:57 +0200
|
|
5
|
+
author: Alexandre Morin
|
|
6
|
+
categories: "SDK Update"
|
|
7
|
+
excerpt: Some ideas about how to use the SDK and a short example illustrating how to build a REST proxy lambda function
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
<p>
|
|
12
|
+
Welcome to the ACC JS SDK. This post introduces a series of posts around Campaign API and the SDK.
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p>
|
|
16
|
+
Here are a couple of ideas about how you can use the SDK
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<ul>
|
|
20
|
+
<li>You can write you own node.js application which interracts with Campaign</li>
|
|
21
|
+
<li>You can build custom UIs for Campaign, using modern technologies such a React</li>
|
|
22
|
+
<li>You can create lambda functions (including Adobe IO Runtime) using the SDK to easily extend Campaign</li>
|
|
23
|
+
<li>You can build a node/express server which exposes a REST API to Campaign, internally using the SDK to perform JSON <=> conversion</li>
|
|
24
|
+
<li>You can build a command line tool (REPL) to play around with Campaign APIs</li>
|
|
25
|
+
<li>You can build a GraphQL API on top of Campaign, etc.</li>
|
|
26
|
+
</ul>
|
|
27
|
+
|
|
28
|
+
<p></p>
|
|
29
|
+
<p class="ref">Start with the <a href="{{ site.baseurl }}/concepts.html">concepts</a> behind Campaign and the SDK.</p>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
<h1>Building a REST Proxy for ACC</h1>
|
|
34
|
+
|
|
35
|
+
<p>
|
|
36
|
+
Here's an advanced example which illustrates how to create a REST API for Campaign using the SDK. This code is expected to run inside
|
|
37
|
+
an express server, or even inside a lambda function.
|
|
38
|
+
</p>
|
|
39
|
+
|
|
40
|
+
<p></p>
|
|
41
|
+
<p class="ref">See the advanced topic of <a href="{{ site.baseurl }}/dynamicInvoke.html">Dynamic Invocation</a> to understand how SOAP calls can be dynamically
|
|
42
|
+
constructed from HTTP requests</p>
|
|
43
|
+
|
|
44
|
+
<p></p>
|
|
45
|
+
<pre class="code">
|
|
46
|
+
const sdk = require('@adobe/acc-js-sdk');
|
|
47
|
+
|
|
48
|
+
// ... perform authentication and get connection parameters here
|
|
49
|
+
const client = await sdk.init(connectionParameters);
|
|
50
|
+
|
|
51
|
+
// It is useful to log the IP address of the server where the SDK
|
|
52
|
+
// runs so that it can be whitelisted in the Campaign configuration
|
|
53
|
+
const ip = await sdk.ip();
|
|
54
|
+
console.log(`Outbound IP address is '${JSON.stringify(ip)}'`);
|
|
55
|
+
|
|
56
|
+
// Log on to Campaign
|
|
57
|
+
await client.logon();
|
|
58
|
+
|
|
59
|
+
// Decode path which must be <namespace>/<schema-id>/<method>.
|
|
60
|
+
// Here we consider we're running inside an Adobe Runtime function
|
|
61
|
+
// which exposes the URL path as <args.__ow_path>
|
|
62
|
+
var path = args.__ow_path;
|
|
63
|
+
if (path[0] == '/')
|
|
64
|
+
path = path.substring(1);
|
|
65
|
+
const pathElements = path.split("/");
|
|
66
|
+
|
|
67
|
+
// Support for /ping endpoint
|
|
68
|
+
if (pathElements.length >= 1 && pathElements[0] === "ping") {
|
|
69
|
+
return sdk.getSDKVersion();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const namespace = pathElements[0].trim();
|
|
73
|
+
const schemaId = pathElements[1].trim();
|
|
74
|
+
const methodName = pathElements[2].trim();
|
|
75
|
+
|
|
76
|
+
// The scopeName is the name of the property of the NLWS object which corresponds
|
|
77
|
+
// to the schema being called. For instance xtk:session => NLWS.xtkSession
|
|
78
|
+
const scopeName = `${namespace}${schemaId[0].toUpperCase()}${schemaId.substring(1)}`;
|
|
79
|
+
const scope = NLWS[scopeName];
|
|
80
|
+
const method = scope[methodName];
|
|
81
|
+
|
|
82
|
+
// Dynamically call SOAP method
|
|
83
|
+
console.log(`About to call method '${methodName}' of scope '${scopeName}'`);
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
// Call the method with a hook to decode parameters. The hook will extract the method
|
|
87
|
+
// parameters values from the action arguments and pass them as an array, as expected
|
|
88
|
+
// by the SDK. It will also set the "this" object for non static methods and fill the
|
|
89
|
+
// "outName" array will be filled with the names of the output parameters of the method
|
|
90
|
+
const outNames = [];
|
|
91
|
+
|
|
92
|
+
const result = await method.call(scope, (method, callContext) => {
|
|
93
|
+
|
|
94
|
+
// Non-static methods require a "this" parameter. This parameter can be passed as
|
|
95
|
+
// a "this" property of the action parameters, or, if this propery is not set, as
|
|
96
|
+
// the action parameters directly (this is just to simplify the REST API callls by
|
|
97
|
+
// allowing to omit the "this" property if the call is non-static with no arguments)
|
|
98
|
+
const isStatic = DomUtil.getAttributeAsBoolean(method, "static");
|
|
99
|
+
if (!isStatic) {
|
|
100
|
+
const object = args["this"] || args;
|
|
101
|
+
callContext.object = object;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Compute parameters array by extracting each parameter by name
|
|
105
|
+
// from the action arguments
|
|
106
|
+
const parameters = [];
|
|
107
|
+
const params = DomUtil.getFirstChildElement(method, "parameters");
|
|
108
|
+
if (params) {
|
|
109
|
+
var param = DomUtil.getFirstChildElement(params, "param");
|
|
110
|
+
while (param) {
|
|
111
|
+
const inout = DomUtil.getAttributeAsString(param, "inout");
|
|
112
|
+
const paramName = DomUtil.getAttributeAsString(param, "name");
|
|
113
|
+
if (!inout || inout=="in") {
|
|
114
|
+
parameters.push(args[paramName]);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
outNames.push(paramName);
|
|
118
|
+
}
|
|
119
|
+
param = DomUtil.getNextSiblingElement(param, "param");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return parameters;
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// Process result. Again this is to simplify the API and return a valid JSON
|
|
127
|
+
var returnedValue = {};
|
|
128
|
+
if (outNames.length == 0) {
|
|
129
|
+
returnedValue = undefined;
|
|
130
|
+
}
|
|
131
|
+
// If the API returns one parameter which is an object, the return it directly.
|
|
132
|
+
// If not (return value is a litteral), then use a JSON with the return parameter name
|
|
133
|
+
else if (outNames.length == 1) {
|
|
134
|
+
if (result && typeof result == "object")
|
|
135
|
+
returnedValue = result;
|
|
136
|
+
else
|
|
137
|
+
returnedValue[outNames[0]] = result;
|
|
138
|
+
}
|
|
139
|
+
// If the API returns multiple values, then build a JSON which each return value
|
|
140
|
+
else {
|
|
141
|
+
for (var i=0; i<outNames.length; i++) {
|
|
142
|
+
const name = outNames[i];
|
|
143
|
+
returnedValue[name] = result[i];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return returnedValue;
|
|
148
|
+
|
|
149
|
+
</pre>
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: page
|
|
3
|
+
title: The Application Object
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
<p>
|
|
8
|
+
The <b>application</b> object can be obtained from a client, and will mimmic the Campaign <a href="https://docs.adobe.com/content/help/en/campaign-classic/technicalresources/api/c-Application.html">Application object</a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<table>
|
|
12
|
+
<thead>
|
|
13
|
+
<tr><th>Attribute/Method</th><th>Description</th></tr>
|
|
14
|
+
</thead>
|
|
15
|
+
<tbody>
|
|
16
|
+
<tr><td><b>buildNumber</b></td><td>The server build number</td></tr>
|
|
17
|
+
<tr><td><b>version</b></td><td>In SDK version 1.1.4 and above, returns the server version formatted as major.minor.servicePack (ex: 8.2.10)</td></tr>
|
|
18
|
+
<tr><td><b>instanceName</b></td><td>The name of the Campaign instance</td></tr>
|
|
19
|
+
<tr><td><b>operator</b></td><td>Information about the current operator (i.e. logged user), of class <b>CurrentLogin</b></td></tr>
|
|
20
|
+
<tr><td><b>packages</b></td><td>List of installed packages, as an array of strings</td></tr>
|
|
21
|
+
<tr><td>async <b>getSchema</b>(schemaId)</td><td> a schema by id (see the Schemas section below)</td></tr>
|
|
22
|
+
<tr><td>async <b>getEnumeration</b>(enumerationName, schemaOrSchemaId)</td><td> an enumeration</td></tr>
|
|
23
|
+
<tr><td><b>hasPackage</b>(name)</td><td>Tests if a package is installed or not
|
|
24
|
+
</tbody>
|
|
25
|
+
</table>
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
<p>The <b>CurrentLogin</b> object has the following attributes / functions</p>
|
|
31
|
+
|
|
32
|
+
<table>
|
|
33
|
+
<thead>
|
|
34
|
+
<tr><th>Attribute/Method</th><th>Description</th></tr>
|
|
35
|
+
</thead>
|
|
36
|
+
<tbody>
|
|
37
|
+
<tr><td><b>id</b></td><td>the internal id (int32) of the operator</td></tr>
|
|
38
|
+
<tr><td><b>login</b></td><td>the login name of the operator</td></tr>
|
|
39
|
+
<tr><td><b>computeString</b></td><td>A human readable name for the operator</td></tr>
|
|
40
|
+
<tr><td><b>timezone</b></td><td>The timezone of the operator</td></tr>
|
|
41
|
+
<tr><td><b>rights</b></td><td>An array of strings describing the rights of the operators</td></tr>
|
|
42
|
+
</tbody>
|
|
43
|
+
</table>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
<h1>Schema API (aka XtkNodeDef)</h1>
|
|
55
|
+
<p>The Schema API is the Campaign API which allows to access schemas and the corresponding node hierarchy in a programmatic way. It's simpler to use this API than to manipulate XML or JSON. The name XtkNodeDef comes from "Xtk Node Definition", where an XtkNode is a generic node in a schema definition.</p>
|
|
56
|
+
|
|
57
|
+
<p>The Schema API closely mimmics the <a href="https://docs.adobe.com/content/help/en/campaign-classic/technicalresources/api/c-Schema.html">Campaign server side API</a> with the following differences:</p>
|
|
58
|
+
<ul>
|
|
59
|
+
<li>The <b>XtkSchema</b> and associated classes (<b>XtkSchemaNode</b>, <b>XtkSchemaKey</b>, <b>XtkEnumeration</b> and <b>XtkEnumerationValue</b>) are all immutable. There are currently no API to create schemas dynamically</li>
|
|
60
|
+
<li>Not all methods and functions are implemented</li>
|
|
61
|
+
<li>Several methods are asynchronous because they may require a server round trip to fetch schemas, etc.</li>
|
|
62
|
+
<li>There could be slight differences in usage due to Campaign server side JavaScript using some E4X specific constructs to iterate over collections (ex: for each(...)) which are not available in standard JavaScript environments</li>
|
|
63
|
+
</ul>
|
|
64
|
+
|
|
65
|
+
<p>The entry point is the application object. Obtain a schema from its id:</p>
|
|
66
|
+
|
|
67
|
+
<pre class="code">
|
|
68
|
+
const application = client.application;
|
|
69
|
+
const schema = await application.getSchema("nms:recipient");
|
|
70
|
+
</pre>
|
|
71
|
+
|
|
72
|
+
<p>This return a schema object of class <b>XtkSchema</b></p>
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
<h1>Iterating over collections</h1>
|
|
79
|
+
<p>The metadata SDK closely mimmics the Campaign API, but provides convenience functions to access collections of objects, such as the children of a node, the values of an enumeration, etc. using an <b>ArrayMap</b> structure which allows access as both an array and a map.</p>
|
|
80
|
+
|
|
81
|
+
<p>Access as a map. Child elements can be accessed with their names, as if it was a JavaScript map. For instance, accessing the gender of a recipient. This method is kept as a compatibility layer with the legacy API and older versions of the SDK but is deprecated / discouraged. The reason is that there are schemas which have attribut names such as "length", or element names such as "forEach" which collide with JavaScript objects.</p>
|
|
82
|
+
<pre class="code">
|
|
83
|
+
const schema = await client.application.getSchema("nms:recipient");
|
|
84
|
+
const enumerations = schema.enumerations;
|
|
85
|
+
// deprecated, discouraged
|
|
86
|
+
expect(enumerations.gender.label).toBe("Gender");
|
|
87
|
+
</pre>
|
|
88
|
+
|
|
89
|
+
<p>Instead, prefer the <b>get</b> function which can retreive any enumeration value</p>
|
|
90
|
+
<pre class="code">
|
|
91
|
+
const schema = await client.application.getSchema("nms:recipient");
|
|
92
|
+
const enumerations = schema.enumerations;
|
|
93
|
+
expect(enumerations.get("gender").label).toBe("Gender");
|
|
94
|
+
</pre>
|
|
95
|
+
|
|
96
|
+
<p>Elements can also be accessed as an array. In this example, we are iterating over the enumerations of a schema</p>
|
|
97
|
+
<pre class="code">
|
|
98
|
+
const schema = await client.application.getSchema("nms:recipient");
|
|
99
|
+
const enumerations = schema.enumerations;
|
|
100
|
+
for (let i=0; i<enumerations.length; i++) {
|
|
101
|
+
const enumeration = enumerations[i];
|
|
102
|
+
}
|
|
103
|
+
</pre>
|
|
104
|
+
|
|
105
|
+
<p>Note that this assumes that there is no enumeration called "length" which will override the "length" attribute. Schemas, schema elements, and sql schemas have attributes named "length", but they are attributes, and will therefore be named "@length" in the metadata API. There is no element named "length" in out-of-the-box schemas.</p>
|
|
106
|
+
<p>The ArrayMap also behaves like an iterator and works fine with the <b>for...of</b> syntax</p>
|
|
107
|
+
<pre class="code">
|
|
108
|
+
const schema = await client.application.getSchema("nms:recipient");
|
|
109
|
+
const enumerations = schema.enumerations;
|
|
110
|
+
for (const enumeration of enumerations) {
|
|
111
|
+
...
|
|
112
|
+
}
|
|
113
|
+
</pre>
|
|
114
|
+
|
|
115
|
+
<p>For convenience, the <b>map</b> and <b>forEach</b>, <b>find</b>, <b>filter</b>, <b>get</b>, and <b>flatMap</b> methods are also available and behave as expected:</p>
|
|
116
|
+
|
|
117
|
+
<pre class="code">
|
|
118
|
+
const schema = await client.application.getSchema("nms:recipient");
|
|
119
|
+
// comma separated list of enumerations
|
|
120
|
+
const enumerations = schema.enumerations.map(e => e.name).join(',');
|
|
121
|
+
</pre>
|
|
122
|
+
|
|
123
|
+
<pre class="code">
|
|
124
|
+
const schema = await client.application.getSchema("nms:recipient");
|
|
125
|
+
schema.enumerations.forEach(e => { ... });
|
|
126
|
+
</pre>
|
|
127
|
+
|
|
128
|
+
<p>The <b>for...in</b> loop is also supported but deprecated/discouraged as it may return incorrect results for collections having items whose key collide with javaScript properties (such as length, map, forEach, etc.). Use a <b>for...of</b> construcr instead, or the <b>map</b> or <b>forEach</b> functions.</p>
|
|
129
|
+
<pre class="code">
|
|
130
|
+
const schema = await client.application.getSchema("nms:recipient");
|
|
131
|
+
// deprecated, discouraged
|
|
132
|
+
for (const key in schema.enumerations) {
|
|
133
|
+
...
|
|
134
|
+
}
|
|
135
|
+
</pre>
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
<h1>Traversing schemas</h1>
|
|
142
|
+
<p>The schema API is useful to quickly traverse in the schema hierarchy. Here are a few examples</p>
|
|
143
|
+
|
|
144
|
+
<p>Get the label of the email attribute of the nms:recipient schema</p>
|
|
145
|
+
<pre class="code">
|
|
146
|
+
const schema = await application.getSchema("nms:recipient");
|
|
147
|
+
const email = await schema.root.findNode("@email");
|
|
148
|
+
console.log(email.label);
|
|
149
|
+
</pre>
|
|
150
|
+
|
|
151
|
+
<p>The <b>findNode</b> function follows links and references</p>
|
|
152
|
+
<ul>
|
|
153
|
+
<li>The function now supports <b>ref</b> nodes. Ref nodes are schema nodes having a <b>ref</b> property which is a reference to another node, possibly in a different schema. </li>
|
|
154
|
+
<ul>
|
|
155
|
+
<li>If the xpath passed to the function ends with a ref node, the ref node itself will be returned. We're not following the reference. You can use the <b>refTarget</b> method to explicitely follow the reference</li>
|
|
156
|
+
<li>If the xpath traverse intermediate nodes which are ref nodes, the <b>findNode</b> method will follow the reference. For instance, the start activity in a workflow is a reference. Finding the xpath "start/@img" will follow the start reference and find the @img attribute from there</li>
|
|
157
|
+
</ul>
|
|
158
|
+
<li>Support for links. If the xpath parameter contains links, <b>findNode</b> will follow the link
|
|
159
|
+
target with the same rules as for reference nodes. To get the target of a link, use the <b>linkTarget</b> method instead of <b>refTarget</b>.</li>
|
|
160
|
+
</ul>
|
|
161
|
+
|
|
162
|
+
<p>For insance, you can get the country of a recipient who clicked in an email. This call follows the link from nms:broadLogRcp to nms:recipient and then from nms:recipient to nms:country, returning the country isoA3 attribute.</p>
|
|
163
|
+
<pre class="code">
|
|
164
|
+
const schema = await application.getSchema("nms:broadLogRcp");
|
|
165
|
+
const node = await schema.root.findNode("recipient/country/@isoA3");
|
|
166
|
+
</pre>
|
|
167
|
+
|
|
168
|
+
<p>The same syntax can be used for reference nodes. For instance, getting the attributes of the start activity of a workflow:</p>
|
|
169
|
+
<pre class="code">
|
|
170
|
+
const schema = await application.getSchema("xtk:workflow");
|
|
171
|
+
const node = await schema.root.findNode("start/@name");
|
|
172
|
+
</pre>
|
|
173
|
+
|
|
174
|
+
<p>In order to actually iterate over the children, things are a little bit more complicated</p>
|
|
175
|
+
<pre class="code">
|
|
176
|
+
const schema = await application.getSchema("xtk:workflow");
|
|
177
|
+
const start = await schema.root.findNode("start");
|
|
178
|
+
// start is the ref node, not the target of the ref. One need to explicitely
|
|
179
|
+
// follow the ref in order to get the list of children
|
|
180
|
+
const target = await start.refTarget();
|
|
181
|
+
target.children.forEach(child => ... );
|
|
182
|
+
</pre>
|
|
183
|
+
|
|
184
|
+
<p>To get the root node of the target of a link, use the <b>linkTarget</b> function</p>
|
|
185
|
+
<pre class="code">
|
|
186
|
+
const schema = await application.getSchema("nms:broadLogRcp");
|
|
187
|
+
const node = await schema.root.findNode("recipient/country");
|
|
188
|
+
// node is the country link, not the root node of the nms:country schema
|
|
189
|
+
const root = await node.linkTarget();
|
|
190
|
+
// root is the root node of the nms:country schema
|
|
191
|
+
</pre>
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
<h1>XtkSchema </h1>
|
|
195
|
+
|
|
196
|
+
<table>
|
|
197
|
+
<thead>
|
|
198
|
+
<tr><th>Attribute/Method</th><th>Description</th></tr>
|
|
199
|
+
</thead>
|
|
200
|
+
<tbody>
|
|
201
|
+
<tr><td><b>id</b></td><td>The id of the schema. For instance "nms:recipient"</td></tr>
|
|
202
|
+
<tr><td><b>namespace</b></td><td>The namespace of the schema. For instance "nms"</td></tr>
|
|
203
|
+
<tr><td><b>name</b></td><td>The name of the schema (internal name)</td></tr>
|
|
204
|
+
<tr><td><b>label</b></td><td>The label (i.e. human readable, localised) name of the node.</td></tr>
|
|
205
|
+
<tr><td><b>labelLocalizationId</b></td><td>The translation id of the label of the node.</td></tr>
|
|
206
|
+
<tr><td><b>labelSingular</b></td><td>The singular label (i.e. human readable, localised) name of the schema. The label of a schema is typically a plural.</td></tr>
|
|
207
|
+
<tr><td><b>labelSingularTranslationId</b></td><td>The translation id of the label of the node of the singular label.</td></tr>
|
|
208
|
+
<tr><td><b>isLibrary</b></td><td>For schemas, indicates if the schema is a library</td></tr>
|
|
209
|
+
<tr><td><b>mappingType</b></td><td>Schema mapping type. Usually "sql"</td></tr>
|
|
210
|
+
<tr><td><b>md5</b></td><td>The MD5 code of the schema in the form of a hexadecimal string</td></tr>
|
|
211
|
+
<tr><td><b>xml</b></td><td>The XML (DOM) corresponding to this schema.<br>Note: this attribute is not available in the JS SDK.</td></tr>
|
|
212
|
+
<tr><td><b>root</b></td><td>The schema root node, if there is one. A reference to a <b>XtkSchemaNode</b></td></tr>
|
|
213
|
+
<tr><td><b>enumerations</b></td><td>Map of enumerations in this schema, indexed by enumeration name. Values are of type <b>XtkEnumeration</b></td></tr>
|
|
214
|
+
<tr><td><b>userDescription</b></td><td>The description of the schema in the form of a string.</td></tr>
|
|
215
|
+
</tbody>
|
|
216
|
+
</table>
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
<p>A schema is also a <b>XtkSchemaNode</b> and the corresponding properties/methods are also availale.</p>
|
|
220
|
+
|
|
221
|
+
<h1>XtkSchemaNode</h1>
|
|
222
|
+
|
|
223
|
+
<table>
|
|
224
|
+
<thead>
|
|
225
|
+
<tr><th>Attribute/Method</th><th>Description</th></tr>
|
|
226
|
+
</thead>
|
|
227
|
+
<tbody>
|
|
228
|
+
<tr><td><b>children</b></td><td>A array/map of children of the node. See note on the ArrayMap structure below</td></tr>
|
|
229
|
+
<tr><td><b>dataPolicy</b></td><td>Returns a string of characters which provides the data policy of the current node.</td></tr>
|
|
230
|
+
<tr><td><b>description</b></td><td>A long, human readable, description of the node</td></tr>
|
|
231
|
+
<tr><td><b>descriptionLocalizationId</b></td><td>The translation id of the description of the node.</td></tr>
|
|
232
|
+
<tr><td><b>editType</b></td><td>Returns a string of characters which specifies the editing type of the current node.
|
|
233
|
+
<tr><td><b>enum</b></td><td>The name of the enumeration for the node, or an empty string if the node does node have an enumeration. See <b>enumeration()</b> method to get the corresponding <b>XtkSchemaNode</b></td></tr>
|
|
234
|
+
<tr><td><b>enumerationImage</b></td><td>Returns the name of the image of the current node in the form of a string of characters.</td></tr>
|
|
235
|
+
<tr><td><b>folderModel</b></td><td>Only on the root node, returns a string which contains the folder template(s). On the other nodes, it returns undefined.
|
|
236
|
+
<tr><td><b>image** </td><td>Returns the name of the image in the form of a string of characters.
|
|
237
|
+
<tr><td><b>img</b></td><td>Returns the name of the image in the form of a string of characters. (alias to <b>image</b> property)</td></tr>
|
|
238
|
+
<tr><td><b>integrity</b></td><td>Returns the link integrity type.</td></tr>
|
|
239
|
+
<tr><td><b>keys</b></td><td>A array/map of keys in this node, indexed by key name. Map values are of type <b>XtkSchemaKey</b></td></tr>
|
|
240
|
+
<tr><td><b>hasEnumeration</b></td><td>Returns a boolean which indicates whether the value of the current node is linked to an enumeration.</td></tr>
|
|
241
|
+
<tr><td><b>childrenCount</b></td><td>Number of children nodes</td></tr>
|
|
242
|
+
<tr><td><b>hasSQLTable</b></td><td>Returns a boolean which indicates whether the current node is linked to an SQL table.</td></tr>
|
|
243
|
+
<tr><td><b>hasUserEnumeration</b></td><td>Returns a boolean which indicates whether the value of the current node is linked to a user enumeration.</td></tr>
|
|
244
|
+
<tr><td><b>schema</b></td><td>The schema (<b>XtkSchema</b>) to which this node belongs</td></tr>
|
|
245
|
+
<tr><td><b>isAdvanced</b></td><td>Returns a boolean which indicates whether the current node is advanced or not.</td></tr>
|
|
246
|
+
<tr><td><b>isAnyType</b></td><td>Returns a boolean which indicates whether the current node is ordinary.</td></tr>
|
|
247
|
+
<tr><td><b>isAttribute</b></td><td>Indicates if the node is an attribute (true) or an element (false)</td></tr>
|
|
248
|
+
<tr><td><b>isAutoIncrement</b></td><td>Returns a boolean which indicates whether the value of the current node is incremented automatically.</td></tr>
|
|
249
|
+
<tr><td><b>isAutoPK</b></td><td>Returns a boolean which indicates whether the current node is a primary key.</td></tr>
|
|
250
|
+
<tr><td><b>isAutoUUID</b></td><td>Returns a boolean which indicates whether the current node is an automatic UUID</td></tr>
|
|
251
|
+
<tr><td><b>isAutoStg</b></td><td>Returns a boolean which indicates whether the schema is a staging schema</td></tr>
|
|
252
|
+
<tr><td><b>isBlob</b></td><td>Returns a boolean which indicates whether the current node is a BLOB.</td></tr>
|
|
253
|
+
<tr><td><b>isCalculated</b></td><td>Returns a boolean which indicates whether the value of the current node is the result of a calculation. Note that compute strings are not considered as calculated attributes.</td></tr>
|
|
254
|
+
<tr><td><b>isCDATA</b></td><td>Returns a boolean which indicates whether the current node is mapped from CDATA type XML.</td></tr>
|
|
255
|
+
<tr><td><b>isCollection</b></td><td>Returns a boolean which indicates whether the current node is a collection of sub-elements and/or attributes. This is an alias to <b>unbound</b> and <b>isUnbound</b> properties.</td></tr>
|
|
256
|
+
<tr><td><b>isDefaultOnDuplicate</b></td><td>Returns a boolean. If the value added is vrai, during record deduplication, the default value (defined in defaultValue) is automatically reapplied during recording.</td></tr>
|
|
257
|
+
<tr><td><b>isElementOnly</b></td><td>Returns a boolean which indicates whether the current node is a logical sub-division of the schema.</td></tr>
|
|
258
|
+
<tr><td><b>isExternalJoin</b></td><td>True if the node is a link and if the join is external.</td></tr>
|
|
259
|
+
<tr><td><b>isLink</b></td><td>Returns a boolean which indicates whether the node is a link.</td></tr>
|
|
260
|
+
<tr><td><b>isMappedAsXML</b></td><td>Returns a boolean which indicates whether the node is an XML mapping.</td></tr>
|
|
261
|
+
<tr><td><b>isMemo</b></td><td>Returns a boolean which indicates whether the current node is mapped by a Memo.</td></tr>
|
|
262
|
+
<tr><td><b>isMemoData</b></td><td>Returns a boolean which indicates whether the current node is mapped by a MemoData.</td></tr>
|
|
263
|
+
<tr><td><b>isNotNull</b></td><td>Returns a boolean which indicates whether or not the current node can take the null value into account.</td></tr>
|
|
264
|
+
<tr><td><b>isRequired</b></td><td>Returns a boolean which indicates whether or not the value of the current node is mandatory.</td></tr>
|
|
265
|
+
<tr><td><b>isRoot</b></td><td>Indicates if the node is the root node of a schema, i.e. the first child of the schema node, whose name matches the schema name</td></tr>
|
|
266
|
+
<tr><td><b>isSQL</b></td><td>Returns a boolean which indicates whether the current node is mapped in SQL.</td></tr>
|
|
267
|
+
<tr><td><b>isTemporaryTable</b></td><td>Returns a boolean indicating whether the table is a temporary table. The table will not be created during database creation.</td></tr>
|
|
268
|
+
<tr><td><b>unbound</b></td><td>Returns a boolean which indicates whether the current node has an unlimited number of children of the same type.</td></tr>
|
|
269
|
+
<tr><td><b>joins</b></td><td>Element of type "link" has an array of XtkJoin. See <b>joinNodes</b> method.</td></tr>
|
|
270
|
+
<tr><td><b>label</b></td><td>The label (i.e. human readable, localised) name of the node.</td></tr>
|
|
271
|
+
<tr><td><b>labelLocalizationId</b></td><td>The translation id of the label of the node.</td></tr>
|
|
272
|
+
<tr><td><b>name</b></td><td>The name of the node (internal name)</td></tr>
|
|
273
|
+
<tr><td><b>nodePath** </td><td>The xpath of the node
|
|
274
|
+
<tr><td><b>parent</b></td><td>The parent node (a <b>XtkSchemaNode</b> object). Will be null for schema nodes</td></tr>
|
|
275
|
+
<tr><td><b>PKSequence</b></td><td>Returns a character string that provides the name of the sequence to use for the primary key.</td></tr>
|
|
276
|
+
<tr><td><b>packageStatus</b></td><td>Returns a number that gives the package status.</td></tr>
|
|
277
|
+
<tr><td><b>packageStatusString</b></td><td> Returns a string that gives the package status ("never", "always", "default", or "preCreate").</td></tr>
|
|
278
|
+
<tr><td><b>revLink</b></td><td>Returns the name of the reverse link in the link target schema. See <b>reverseLink</b> method to get the actual reverse link object</td></tr>
|
|
279
|
+
<tr><td><b>SQLName</b></td><td>The SQL name of the field. The property is an empty string if the object isn't an SQL type field.</td></tr>
|
|
280
|
+
<tr><td><b>SQLTable</b></td><td>The SQL name of the table. The property is an empty string if the object isn't the main element or if schema mapping isn't of SQL type.</td></tr>
|
|
281
|
+
<tr><td><b>size</b></td><td>For string nodes, the maximum length of the node value. Alias to <b>length</b>.</td></tr>
|
|
282
|
+
<tr><td><b>length</b></td><td>For string nodes, the maximum length of the node value. Alias to <b>size</b>.</td></tr>
|
|
283
|
+
<tr><td><b>target</b></td><td>A string corresponding to the target of a link. Note that in the SDK, this is a string, whereas in the JS API, this is the actual target node. Because the SDK is async. Use <b>linkTarget</b> to get the target node of a link.</td></tr>
|
|
284
|
+
<tr><td><b>type</b></td><td>The data type of the node, for instance "string", "long", etc.</td></tr>
|
|
285
|
+
<tr><td><b>userEnumeration</b></td><td>Returns a string of characters which is the name of the user enumeration used by the current node.</td></tr>
|
|
286
|
+
<tr><td><b>ref</b></td><td>Some nodes are only references to other nodes. There are 2 kind of references. Local references are simply a xpath in the current schema (starting from the schema itself, and not the schema root). Fully qualified references are prefixed with a schema id. The target node can be accessed with the <b>refTarget</b> funtion.</td></tr>
|
|
287
|
+
<tr><td><b>isMappedAsXml</b></td><td>Is the field mapped as XML?</td></tr>
|
|
288
|
+
<tr><td><b>visibleIf</b></td><td>The visibility expression of the node (if any) since version 1.1.9 of the SDK</td></tr>
|
|
289
|
+
<tr><td><b>belongsTo</b></td><td>For attribute and elements, indicates the schema id in which they were defined. Since version 1.1.10 of the SDK</td></tr>
|
|
290
|
+
</tbody>
|
|
291
|
+
</table>
|
|
292
|
+
|
|
293
|
+
<p>Methods of a schema node</p>
|
|
294
|
+
|
|
295
|
+
<table>
|
|
296
|
+
<thead>
|
|
297
|
+
<tr><th>Method</th><th>Description</th></tr>
|
|
298
|
+
</thead>
|
|
299
|
+
<tbody>
|
|
300
|
+
<tr><td>async <b>findNode</b></td><td>Find a child node using a xpath. This function follows links and references if necessary and will dynamically fetch/cache necessary schemas. </td></tr></td></tr>
|
|
301
|
+
<tr><td>async <b>refTarget</b></td><td>Get the target node of a reference</td></tr></td></tr>
|
|
302
|
+
<tr><td>async <b>linkTarget</b></td><td>Get the target node of a link. See <b>target</b></td></tr></td></tr>
|
|
303
|
+
<tr><td>async <b>joinNodes</b></td><td>Get the schema nodes corresponding to link. The function returns nodes for both the source and the destination of the link. See <b>joins</b>.</td></tr></td></tr>
|
|
304
|
+
<tr><td>async <b>reverseLink</b></td><td>Returns the node corresponding to the reverse link of a link. See <b>revLink</b> to get the reverse link name rather than the actual node</td></tr></td></tr>
|
|
305
|
+
<tr><td>async <b>computeString</b></td><td>Returns the compute string of a node, following references if necessary</td></tr></td></tr>
|
|
306
|
+
<tr><td>async <b>enumeration</b></td><td>For nodes whose value is an enumeration, return the <b>XtkEnumeration</b> object corresponding to the enumeration definition. See <b>enum</b> property to get the enumeration name instead of the object</td></tr></td></tr>
|
|
307
|
+
<tr><td><b>firstInternalKeyDef</b></td><td></td></tr>
|
|
308
|
+
<tr><td><b>firstExternalKeyDef</b></td><td>
|
|
309
|
+
<tr><td><b>firstKeyDef</b></td><td>
|
|
310
|
+
</tbody>
|
|
311
|
+
</table>
|
|
312
|
+
|
|
313
|
+
<h1>XtkSchemaKey</h1>
|
|
314
|
+
|
|
315
|
+
<table>
|
|
316
|
+
<thead>
|
|
317
|
+
<tr><th>Attribute/Method</th><th>Description</th></tr>
|
|
318
|
+
</thead>
|
|
319
|
+
<tbody>
|
|
320
|
+
<tr><td><b>schema</b></td><td>The schema to which this key belongs</td></tr>
|
|
321
|
+
<tr><td><b>name</b></td><td> The name of the key (internal name)</td></tr>
|
|
322
|
+
<tr><td><b>label</b></td><td>The label (i.e. human readable, localised) name of the key</td></tr>
|
|
323
|
+
<tr><td><b>description</b></td><td>A long, human readable, description of the key</td></tr>
|
|
324
|
+
<tr><td><b>isInternal</b></td><td>Indicates if the key is an internal key (as opposed to an external key)</td></tr>
|
|
325
|
+
<tr><td><b>allowEmptyPart</b></td><td>
|
|
326
|
+
<tr><td><b>fields</b></td><td>A ArrayMap of key fields making up the key. Each value is a reference to a <b>XtkSchemaNode</b> </td></tr>
|
|
327
|
+
</tbody>
|
|
328
|
+
</table>
|
|
329
|
+
|
|
330
|
+
<h1>XtkEnumeration</h1>
|
|
331
|
+
|
|
332
|
+
<table>
|
|
333
|
+
<thead>
|
|
334
|
+
<tr><th>Attribute/Method</th><th>Description</th></tr>
|
|
335
|
+
</thead>
|
|
336
|
+
<tbody>
|
|
337
|
+
<tr><td><b>name</b></td><td> The name of the enumeration, fully qualified, i.e. prefixed with the schema id</td></tr>
|
|
338
|
+
<tr><td><b>label</b></td><td>The label (i.e. human readable, localised) name of the key</td></tr>
|
|
339
|
+
<tr><td><b>labelLocalizationId</b></td><td>The translation id of the label of the key.</td></tr>
|
|
340
|
+
<tr><td><b>description</b></td><td>A long, human readable, description of the key</td></tr>
|
|
341
|
+
<tr><td><b>descriptionLocalizationId</b></td><td>The translation id of the description of the key.</td></tr>
|
|
342
|
+
<tr><td><b>baseType</b></td><td>The base type of the enumeration, usually "string" or "byte"</td></tr>
|
|
343
|
+
<tr><td><b>default</b></td><td>The default value of the enumeration, casted to the enumeration type</td></tr>
|
|
344
|
+
<tr><td><b>hasImage</b></td><td>If the enumeration has an image</td></tr>
|
|
345
|
+
<tr><td><b>values</b></td><td>A ArrayMap of enumeration values, of type <b>XtkEnumerationValue</b></td></tr>
|
|
346
|
+
</tbody>
|
|
347
|
+
</table>
|
|
348
|
+
|
|
349
|
+
<h1>XtkEnumerationValue</h1>
|
|
350
|
+
|
|
351
|
+
<table>
|
|
352
|
+
<thead>
|
|
353
|
+
<tr><th>Attribute/Method</th><th>Description</th></tr>
|
|
354
|
+
</thead>
|
|
355
|
+
<tbody>
|
|
356
|
+
<tr><td><b>name</b></td><td> The name of the key (internal name)</td></tr>
|
|
357
|
+
<tr><td><b>label</b></td><td>The label (i.e. human readable, localised) name of the key</td></tr>
|
|
358
|
+
<tr><td><b>labelLocalizationId</b></td><td>The translation id of the label of the key.</td></tr>
|
|
359
|
+
<tr><td><b>description</b></td><td>A long, human readable, description of the key</td></tr>
|
|
360
|
+
<tr><td><b>descriptionLocalizationId</b></td><td>The translation id of the description of the key.</td></tr>
|
|
361
|
+
<tr><td><b>image</b></td><td>
|
|
362
|
+
<tr><td><b>enabledIf</b></td><td>
|
|
363
|
+
<tr><td><b>applicableIf</b></td><td>
|
|
364
|
+
<tr><td><b>value</b></td><td>The value of the enumeration (casted to the proper Javascript type)</td></tr>
|
|
365
|
+
</tbody>
|
|
366
|
+
</table>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: page
|
|
3
|
+
title: Architecture
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<p>
|
|
7
|
+
The SDK is designed to be simple, small and ready to go. It does not depend on any piece of infrastructure, and is
|
|
8
|
+
designed to be able to connect to any Campaign (Classic) version both from a server-side environment (node.js) or
|
|
9
|
+
a client-side environment (browser).
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<img src="{{ site.baseurl }}/assets/images/architecture.png" width="400px"/>
|
|
13
|
+
<p class="caption">The architecture of the SDK</p>
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
<h1>Core principles</h1>
|
|
17
|
+
<p></p>
|
|
18
|
+
<ul>
|
|
19
|
+
<li><b>Small</b>: the bundle is kept intentionally small, with a minimum set of dependencies</li>
|
|
20
|
+
<li><b>Quality</b>: the SDK is extensively tested, with hundreds of unit tests, and 100% coverage</li>
|
|
21
|
+
<li><b>Vanilla JS</b>: the code is written in plain JavaScript with the minimum compilation phase</li>
|
|
22
|
+
<li><b>Consistent</b>: we try to offer a consistent developer experience, both inside the SDK itself, but also with existing Campaign JavaScipt</li>
|
|
23
|
+
</ul>
|
|
24
|
+
|