@adobe/acc-js-sdk 1.1.8 → 1.1.10
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/CHANGELOG.md +17 -5
- package/README.md +211 -1
- package/package-lock.json +843 -5820
- package/package.json +1 -1
- package/samples/005 - basics - persist.js +160 -0
- package/src/application.js +11 -0
- package/src/client.js +68 -25
- package/src/methodCache.js +24 -13
- package/src/soap.js +13 -1
- package/src/xtkCaster.js +61 -3
- package/test/application.test.js +38 -0
- package/test/caches.test.js +1 -1
- package/test/client.test.js +118 -3
- package/test/mock.js +41 -4
- package/test/xtkCaster.test.js +62 -0
- package/test/xtkPersist.test.js +97 -0
- package/test/xtkProxy.test.js +81 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,29 +5,41 @@ 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.10
|
|
9
|
+
_2022/10/13_
|
|
10
|
+
|
|
11
|
+
* Added support for `primaryKey` type
|
|
12
|
+
* Added support for the `xtk:persist` interface
|
|
13
|
+
* Added support for schema belongsTo attribute
|
|
14
|
+
|
|
15
|
+
## Version 1.1.9
|
|
16
|
+
_2022/10/11_
|
|
17
|
+
|
|
18
|
+
* Added support for schema visibleIf attribute
|
|
19
|
+
|
|
8
20
|
## Version 1.1.8
|
|
9
|
-
|
|
21
|
+
_2022/10/03_
|
|
10
22
|
|
|
11
23
|
* Added translation ids (`labelLocalizationId`,`descriptionLocalizationId`, `labelSingularLocalizationId`) for `XtkSchema`, `XtkSchemaNode`, `XtkEnumerationValue` and `XtkEnumeration`
|
|
12
24
|
|
|
13
25
|
## Version 1.1.7
|
|
14
|
-
|
|
26
|
+
_2022/08/30_
|
|
15
27
|
|
|
16
28
|
* New listener interface to be notified of internal events from the SDK. Can be used to integrate with observability frameworks. See the "Observers" section of the README file.
|
|
17
29
|
* Experimental file upload feature. Will require server-side changes to work, and is currently limited to be used with browsers only.
|
|
18
30
|
|
|
19
31
|
## Version 1.1.6
|
|
20
|
-
|
|
32
|
+
_2022/08/19_
|
|
21
33
|
|
|
22
34
|
* New auto-refresh mechanism to keep schemas and option caches up-to-date. See `client.startRefreshCaches` and `client.stopRefreshCaches` functions.
|
|
23
35
|
|
|
24
36
|
## Version 1.1.5
|
|
25
|
-
_2022/07/
|
|
37
|
+
_2022/07/07_
|
|
26
38
|
|
|
27
39
|
* The SOAP method name was not showing up properly in the Chrome console
|
|
28
40
|
|
|
29
41
|
## Version 1.1.4
|
|
30
|
-
_2022/07/
|
|
42
|
+
_2022/07/07_
|
|
31
43
|
|
|
32
44
|
* Added `application.version` which returns the server version in the format major.minor.servicePack (ex: 8.2.10)
|
|
33
45
|
* Added the ability to push down parameters to the SOAP and transport layers. See the pushDown section of the readme file.
|
package/README.md
CHANGED
|
@@ -426,12 +426,31 @@ const queryDef = {
|
|
|
426
426
|
operation: "get",
|
|
427
427
|
where: { condition: [ { expr:`@name='XtkDatabaseId'` } ] }
|
|
428
428
|
};
|
|
429
|
+
const query = client.NLWS.xtkQueryDef.create(queryDef);
|
|
429
430
|
await query.selectAll(false);
|
|
430
431
|
var result = await query.executeQuery();
|
|
431
432
|
```
|
|
432
433
|
|
|
433
434
|
In the previous example, a queryDef is created without any select nodes. Then the selectAll method is called. After the call, the JavaScript queryDef object will contain a select elements with all the nodes corresponding to attributes of the xtk:option schema.
|
|
434
435
|
|
|
436
|
+
|
|
437
|
+
## XTK interfaces
|
|
438
|
+
|
|
439
|
+
Campaign schemas are following an object model. An interface is a set of methods. For instance, the "xtk:persist" interface, defined in the "xtk:session" schema, has a NewInstance method.
|
|
440
|
+
Schemas can implement interface, which means they inherit and implement the methods of the interface. Such methods are internally called using a particular SOAP call URN, which is formed of the interface name, followed by a pipe character, followed by the implementation schema id. For instance "xtk:persist|nms:delivery" is used to indicate that we're calling a method of the xtk:persist on a nms:delivery object which implements the xtk:persist interface.
|
|
441
|
+
|
|
442
|
+
The version 1.1.9 of the SDK properly implement this type of calls and will deal with this complexity for you. For instance, you can simply call the NewInstance method as follows:
|
|
443
|
+
|
|
444
|
+
```js
|
|
445
|
+
// Create a proxy delivery object
|
|
446
|
+
const delivery = client.NLWS.nmsDelivery.create({ label: "Hello" });
|
|
447
|
+
// Call the xtk:persist|nms:delivery#NewInstance method to retreive the default
|
|
448
|
+
// values of a delivery object before actually saving the delivery
|
|
449
|
+
await delivery.newInstance();
|
|
450
|
+
```
|
|
451
|
+
There are 2 common interfaces: xtk:persist and xtk:jobInterface which are documented below.
|
|
452
|
+
|
|
453
|
+
|
|
435
454
|
## Campaign data types
|
|
436
455
|
|
|
437
456
|
Campaign uses a typed system with some specificities:
|
|
@@ -458,6 +477,7 @@ Campaign uses a typed system with some specificities:
|
|
|
458
477
|
| date | 10 | Date | UTC timestamp with day precision. Can be null |
|
|
459
478
|
| boolean | 15 | boolean | boolean value, defaultint to false. Cannot be null |
|
|
460
479
|
| timespan | | | |
|
|
480
|
+
| primarykey | | string | A primary key is serialized with format <schemaId>|<keyField>[|<keyField>[...]]
|
|
461
481
|
|
|
462
482
|
|
|
463
483
|
The SDK user does not have to handle this, but outside of the Campaign ecosystem, those rules may not apply and you probably do not want to use a number for a string, etc. The `XtkCaster` class is here to help.
|
|
@@ -968,6 +988,195 @@ or
|
|
|
968
988
|
var hasAmp = client.hasPackage("nms", "amp");
|
|
969
989
|
```
|
|
970
990
|
|
|
991
|
+
## Creating and updating entities in Campaign
|
|
992
|
+
|
|
993
|
+
There are several possibillities to create objects in Campaign.
|
|
994
|
+
|
|
995
|
+
### Create from scratch
|
|
996
|
+
|
|
997
|
+
This first method is to create an object from scratch. It's a multi-step operation which contains the following steps
|
|
998
|
+
|
|
999
|
+
* Create an object with the "create" function. This function takes an optional parameter with the attributes you know you're going to set
|
|
1000
|
+
* Call the xtk:persist#NewInstance API which will generate a unique id, and complete your object with default values (such as default folder, etc.) depending on your role
|
|
1001
|
+
* Optionally set more attributes to override any defaults
|
|
1002
|
+
* Call save() or xtk:session#Write to create the object in the database
|
|
1003
|
+
|
|
1004
|
+
```js
|
|
1005
|
+
const delivery = client.NLWS.nmsDelivery.create({ label: "Test #1", messageType: "0" });
|
|
1006
|
+
await delivery.newInstance();
|
|
1007
|
+
delivery.$desc = "My description";
|
|
1008
|
+
await client.NLWS.xtkSession.write(delivery); // or await delivery.save();
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
You'll notice that this method does not return anything. You may have expected this method to return the created object or some id of this object,
|
|
1012
|
+
but Campaign does not. Campaign works the other way round. You first get call NewInstance which will give the id before the object is actually saved
|
|
1013
|
+
in the database.
|
|
1014
|
+
|
|
1015
|
+
```js
|
|
1016
|
+
const delivery = client.NLWS.nmsDelivery.create({ label: "Test #1", messageType: "0" });
|
|
1017
|
+
await delivery.newInstance();
|
|
1018
|
+
// delivery.entity.id is the future id of the object in the database
|
|
1019
|
+
```
|
|
1020
|
+
|
|
1021
|
+
If you need to modify the object again after it's been created, you can use xtk:session#Write or save again, but you must tell Campaign to perform an update operation instead of an insert, or the call will probably fail or create a duplicate in the database.
|
|
1022
|
+
Make sure to read the section about the "xtk:session#Write" method below to understand how exactly objects are updated
|
|
1023
|
+
|
|
1024
|
+
```js
|
|
1025
|
+
delivery._operation = "update";
|
|
1026
|
+
delivery.$desc = "My updated description";
|
|
1027
|
+
await delivery.save();
|
|
1028
|
+
```
|
|
1029
|
+
|
|
1030
|
+
Finally, to delete the object, use xtk:session#Write or save again, this time passing it the "_operation=delete" attribute
|
|
1031
|
+
```js
|
|
1032
|
+
delivery._operation = "delete";
|
|
1033
|
+
await delivery.save();
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
### Create by duplicating an existing object
|
|
1037
|
+
|
|
1038
|
+
Sometimes, you do not want to create objects from scratch. Instead you can copy an existing object. Campaign has a sophisticated mechanism to duplicate object and ensures that only the relevant attributes are actually set. For instance, when you dupliate a delivery which is finished, you probably want the new delivery to be in the edition state rather than in the finished state. Schema attributes having the "defOnDuplicate" property will be reset to their defaults in the duplicated object.
|
|
1039
|
+
|
|
1040
|
+
Just like the "NewInstance" API, the "xtk:persist#Duplicate" will automatically set the primary key for you. And again, it is a multi-step process.
|
|
1041
|
+
|
|
1042
|
+
* Create an object with the "create" function. This time, do no pass any parameters
|
|
1043
|
+
* Call the duplicate method, passing it the primary key of the entity you want to duplicate
|
|
1044
|
+
* Optionally set more attributes to override any defaults
|
|
1045
|
+
* Call save() or xtk:session#Write to create the object in the database
|
|
1046
|
+
|
|
1047
|
+
```js
|
|
1048
|
+
const operator = client.NLWS.xtkOperator.create();
|
|
1049
|
+
await operator.duplicate("xtk:operator|1610");
|
|
1050
|
+
operator.name = "Alex";
|
|
1051
|
+
await operator.save();
|
|
1052
|
+
```
|
|
1053
|
+
|
|
1054
|
+
The primary key format is described in the data types section of this document.
|
|
1055
|
+
|
|
1056
|
+
|
|
1057
|
+
### Updating entities
|
|
1058
|
+
|
|
1059
|
+
Entities can be updated using the `xtk:session#Write` API. This API is very flexible and also can be used to create or delete entities or to modify multiple entites at once.
|
|
1060
|
+
|
|
1061
|
+
This method takes an unique argument which is a patch to apply. A patch has the same structure as an entity, but only contains the attributes or elements that need to be modified, created, or deleted. In addition to the value, the patch can also use the _operation property to indicate if a particular set of data needs to be inserted, updated or deleted.
|
|
1062
|
+
The patch object also must have the `xtkschema` property set to the schema id of the entity to modify.
|
|
1063
|
+
|
|
1064
|
+
For instance, one can update the email of a recipient with the following code which clearly shows the xtkschema property, the id and _operation properties to indicate that it is an update and which entity to update, and finally, the email attribute which is the only modified attribute.
|
|
1065
|
+
|
|
1066
|
+
```js
|
|
1067
|
+
client.NLWS.xtkSession.write({ xtkschema: "nms:recipient",
|
|
1068
|
+
id: "1234", _operation:"update",
|
|
1069
|
+
email: "amorin@adobe.com"
|
|
1070
|
+
});
|
|
1071
|
+
```
|
|
1072
|
+
|
|
1073
|
+
It's of course possible to pass the whole entity to an update, but this is strongly discouraged as it can have unwanted side effects in complex scenario when passed nested documents with linked objects. It's also less performant, and may overwrite data.
|
|
1074
|
+
Passing a patch (sometimes called a diff) containing only the actually modified attributes is the best practice. It also has the benefit to allow some sort of concurrent modifications as each update will onlly update the attributes actually changed.
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
### Setting foreign keys
|
|
1078
|
+
|
|
1079
|
+
It's pretty common to have to set foreign keys. For instance one want to set the folder in which a recipient is stored. The first possibility is to set the folder-id attribute directly. It's also the most efficient, but it assumes you know the foreign key in the first place.
|
|
1080
|
+
|
|
1081
|
+
```js
|
|
1082
|
+
client.NLWS.xtkSession.write({ xtkschema: "nms:recipient",
|
|
1083
|
+
xtkschema:"nms:recipient",
|
|
1084
|
+
id: 2020, _operation:"update",
|
|
1085
|
+
"folder-id": 6040
|
|
1086
|
+
});
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1089
|
+
If you do not know the primary key of the folder but know its name, you can use the following syntax. It works for all collections, where items can be identified with their keys (as defined in the schemas).
|
|
1090
|
+
```js
|
|
1091
|
+
client.NLWS.xtkSession.write({ xtkschema: "nms:recipient",
|
|
1092
|
+
xtkschema:"nms:recipient",
|
|
1093
|
+
id: 1990, _operation:"update",
|
|
1094
|
+
folder: {
|
|
1095
|
+
_operation: "none",
|
|
1096
|
+
name: "test"
|
|
1097
|
+
}
|
|
1098
|
+
});
|
|
1099
|
+
```
|
|
1100
|
+
|
|
1101
|
+
Note the `operation="none"` attribute on the folder element which tells Campaign that we should not actually update the folder object itself, but to set the recipient folder instead. If you omit the _operation: "none" property, Campaign will modify both the recipient, but also the folder. It is useful in some cases, but does not make sense in this scenario.
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
### Identifying entities
|
|
1105
|
+
|
|
1106
|
+
We've had a glimpse of it but the xtk:session#Write API has several strategies to identify entities, both the top level entity but also linked entities as we've seen with the recipient folder example above.
|
|
1107
|
+
|
|
1108
|
+
* If the entity is an "autopk" entity, i.e. has autopk=true set defined in its schema, then it will have an internal primary key using the @id attribute. If the corresponding id is set in the patch document, it will be used to identify the object.
|
|
1109
|
+
* Otherwise, it will use the entity keys, as defined in the schema.
|
|
1110
|
+
|
|
1111
|
+
For instance, folders are an autopk entity and have the id attribute. They also have 2 keys: name and fullName. All 3 can be used as identifiers to update a folder label as the 3 examples below show
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
```js
|
|
1115
|
+
// Update folder by id
|
|
1116
|
+
await client.NLWS.xtkSession.write({
|
|
1117
|
+
xtkschema: "xtk:folder",
|
|
1118
|
+
_operation: "update", id: 1234,
|
|
1119
|
+
label: "Hello World",
|
|
1120
|
+
});
|
|
1121
|
+
});
|
|
1122
|
+
|
|
1123
|
+
// Update folder by name
|
|
1124
|
+
await client.NLWS.xtkSession.write({
|
|
1125
|
+
xtkschema: "xtk:folder",
|
|
1126
|
+
_operation: "update", name: "test",
|
|
1127
|
+
label: "Hello World",
|
|
1128
|
+
});
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
// Update folder by full name
|
|
1132
|
+
// This is just for example, do not use this method as the folder full name is the concatenation
|
|
1133
|
+
// of the folder label and it's parent folders labels. Changing the label will create an
|
|
1134
|
+
// inconsistency between the folder full name and its label. You can update other attributes though.
|
|
1135
|
+
await client.NLWS.xtkSession.write({
|
|
1136
|
+
xtkschema: "xtk:folder",
|
|
1137
|
+
_operation: "update", fullName: "/Profiles and Targets/Recipients/Hello/",
|
|
1138
|
+
label: "Hello World",
|
|
1139
|
+
});
|
|
1140
|
+
});
|
|
1141
|
+
```
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
### Deleting data
|
|
1145
|
+
|
|
1146
|
+
The `xtkSession#write` API can also be used to delete data using the "_operation=delete" attribute. For a delete operation, the patch should contain the xtkschema attribute, the _operation=delete attribute and an identifier of the entity.
|
|
1147
|
+
|
|
1148
|
+
For insance, a folder can be delete with
|
|
1149
|
+
|
|
1150
|
+
```js
|
|
1151
|
+
await client.NLWS.xtkSession.write({
|
|
1152
|
+
xtkschema: "xtk:folder",
|
|
1153
|
+
_operation: "delete", name: "test",
|
|
1154
|
+
});
|
|
1155
|
+
});
|
|
1156
|
+
```
|
|
1157
|
+
|
|
1158
|
+
Owned entities which are also autopk will also be deleted
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
### Setting ids
|
|
1162
|
+
|
|
1163
|
+
In the previous examples we showed how to create or update object and let Campaign generate the ids. In some cases, you'll want to explictiely set the ids upfront. To ensure uniqueness of the ids, Campaign provides an API to "reserve" ids in advane that you can use afterwards: xtk:session#GetNewIdsEx.
|
|
1164
|
+
|
|
1165
|
+
In this example, we're getting an id and creating a recipient. The id can be re-used in subsequent calls as a foreign key
|
|
1166
|
+
```js
|
|
1167
|
+
const idList = XtkCaster.asArray(await client.NLWS.xtkSession.GetNewIdsEx(1, "XtkNewId"));
|
|
1168
|
+
await client.NLWS.xtkSession.write({ xtkschema:"nms:recipient", id: idList[0], email: 'amorin@adobe.com' });
|
|
1169
|
+
```
|
|
1170
|
+
|
|
1171
|
+
Note that:
|
|
1172
|
+
* Calling GetNewIdsEx for individual ids is not efficient. It's usually better to reserve a large range of ids and insert multiple rows using those ids
|
|
1173
|
+
* Inserting data in unitary fashion with API calls is not efficient. Use data management workflows for large imports
|
|
1174
|
+
* Make sure that the NLWS.xtkSession.GetNewIdsEx returns an array by using XtkCaster.asArray(...)
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
## The xtk:jobInterface interface
|
|
971
1180
|
|
|
972
1181
|
## Connect to mid-sourcing
|
|
973
1182
|
From a marketing client connection, one can get a client to a mid server
|
|
@@ -1830,7 +2039,8 @@ A schema is also a `XtkSchemaNode` and the corresponding properties/methods are
|
|
|
1830
2039
|
| **userEnumeration** | Returns a string of characters which is the name of the user enumeration used by the current node.
|
|
1831
2040
|
| **ref** | 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 `refTarget` funtion.
|
|
1832
2041
|
| **isMappedAsXml** | Is the field mapped as XML?
|
|
1833
|
-
|
|
2042
|
+
| **visibleIf** | The visibility expression of the node (if any) since version 1.1.9 of the SDK
|
|
2043
|
+
| **belongsTo** | For attribute and elements, indicates the schema id in which they were defined. Since version 1.1.10 of the SDK
|
|
1834
2044
|
|
|
1835
2045
|
|
|
1836
2046
|
| Method | Description |
|