mcdev 7.4.2 → 7.4.3
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/.github/ISSUE_TEMPLATE/bug.yml +1 -0
- package/@types/lib/metadataTypes/DataExtract.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Event.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Journey.d.ts +13 -0
- package/@types/lib/metadataTypes/Journey.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Script.d.ts +2 -2
- package/@types/lib/metadataTypes/SendClassification.d.ts +6 -0
- package/@types/lib/metadataTypes/SendClassification.d.ts.map +1 -1
- package/@types/lib/metadataTypes/SenderProfile.d.ts +49 -6
- package/@types/lib/metadataTypes/SenderProfile.d.ts.map +1 -1
- package/@types/lib/metadataTypes/User.d.ts +10 -2
- package/@types/lib/metadataTypes/User.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Verification.d.ts.map +1 -1
- package/@types/lib/metadataTypes/definitions/Journey.definition.d.ts +13 -0
- package/@types/lib/metadataTypes/definitions/Script.definition.d.ts +2 -2
- package/@types/lib/metadataTypes/definitions/SenderProfile.definition.d.ts +42 -6
- package/@types/lib/util/validations.d.ts.map +1 -1
- package/boilerplate/files/.prettierrc +6 -0
- package/boilerplate/files/eslint.config.js +18 -0
- package/boilerplate/forcedUpdates.json +4 -0
- package/lib/metadataTypes/DataExtract.js +29 -0
- package/lib/metadataTypes/Event.js +30 -0
- package/lib/metadataTypes/Journey.js +79 -32
- package/lib/metadataTypes/SendClassification.js +47 -16
- package/lib/metadataTypes/SenderProfile.js +49 -0
- package/lib/metadataTypes/User.js +74 -40
- package/lib/metadataTypes/Verification.js +15 -0
- package/lib/metadataTypes/definitions/DataExtract.definition.js +1 -1
- package/lib/metadataTypes/definitions/Event.definition.js +1 -1
- package/lib/metadataTypes/definitions/Journey.definition.js +14 -0
- package/lib/metadataTypes/definitions/Script.definition.js +4 -2
- package/lib/metadataTypes/definitions/SendClassification.definition.js +1 -1
- package/lib/metadataTypes/definitions/SenderProfile.definition.js +54 -21
- package/lib/metadataTypes/definitions/Verification.definition.js +2 -2
- package/lib/util/validations.js +3 -2
- package/package.json +1 -1
- package/test/general.test.js +21 -21
- package/test/mockRoot/.mcdevrc.json +1 -1
- package/test/resources/9999999/accountUser/retrieve-response.xml +104 -0
- package/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/patch-response.json +2 -2
- package/test/resources/9999999/automation/v1/dataextracts/post-response.json +2 -2
- package/test/resources/9999999/dataExtract/get-expected.json +2 -2
- package/test/resources/9999999/dataExtract/patch-expected.json +2 -2
- package/test/resources/9999999/dataExtract/post-expected.json +2 -2
- package/test/resources/9999999/event/get-expected.json +2 -2
- package/test/resources/9999999/interaction/v1/eventDefinitions/get-response.json +4 -4
- package/test/resources/9999999/journey/build-expected.json +1 -0
- package/test/resources/9999999/journey/get-multistep-expected.json +1 -0
- package/test/resources/9999999/journey/get-quicksend-expected.json +1 -0
- package/test/resources/9999999/journey/get-quicksend-rcb-id-expected.json +1 -0
- package/test/resources/9999999/journey/get-quicksend-rcb-key-expected.json +1 -0
- package/test/resources/9999999/journey/get-quicksend-rcb-name-expected.json +1 -0
- package/test/resources/9999999/journey/get-transactionalEmail-expected.json +1 -0
- package/test/resources/9999999/journey/template-expected.json +1 -0
- package/test/resources/9999999/sendClassification/retrieve-response.xml +4 -4
- package/test/resources/9999999/senderProfile/build-expected.json +1 -0
- package/test/resources/9999999/senderProfile/create-response.xml +1 -0
- package/test/resources/9999999/senderProfile/get-expected.json +4 -1
- package/test/resources/9999999/senderProfile/get-rcb-id-expected.json +3 -0
- package/test/resources/9999999/senderProfile/get-rcb-key-expected.json +3 -0
- package/test/resources/9999999/senderProfile/get-rcb-name-expected.json +3 -0
- package/test/resources/9999999/senderProfile/patch-expected.json +1 -0
- package/test/resources/9999999/senderProfile/post-expected.json +1 -0
- package/test/resources/9999999/senderProfile/retrieve-CustomerKey=Default-response.xml +5 -0
- package/test/resources/9999999/senderProfile/retrieve-response.xml +15 -0
- package/test/resources/9999999/senderProfile/template-expected.json +1 -0
- package/test/resources/9999999/senderProfile/update-response.xml +1 -0
- package/test/resources/9999999/verification/get-expected.json +1 -0
- package/test/resources/9999999/verification/patch-expected.json +1 -0
- package/test/resources/9999999/verification/post-expected.json +1 -0
- package/test/type.automation.test.js +4 -4
- package/test/type.dataExtract.test.js +4 -4
- package/test/type.event.test.js +6 -6
- package/test/type.journey.test.js +11 -11
- package/test/type.senderProfile.test.js +6 -6
- package/test/type.user.test.js +2 -2
- package/test/type.verification.test.js +3 -3
|
@@ -854,8 +854,21 @@ class Journey extends MetadataType {
|
|
|
854
854
|
}
|
|
855
855
|
// delivery profile
|
|
856
856
|
if (triggeredSend.deliveryProfileId) {
|
|
857
|
-
|
|
858
|
-
|
|
857
|
+
try {
|
|
858
|
+
triggeredSend.r__deliveryProfile_key = cache.searchForField(
|
|
859
|
+
'deliveryProfile',
|
|
860
|
+
triggeredSend.deliveryProfileId,
|
|
861
|
+
'ObjectID',
|
|
862
|
+
'key'
|
|
863
|
+
);
|
|
864
|
+
delete triggeredSend.deliveryProfileId;
|
|
865
|
+
} catch {
|
|
866
|
+
Util.logger.warn(
|
|
867
|
+
` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${
|
|
868
|
+
metadata[this.definition.keyField]
|
|
869
|
+
}): Dependent deliveryProfile was not found. Please note that this can only be resolved if you have at least ONE Send Classification set up on the target BU that uses this Delivery Profile.`
|
|
870
|
+
);
|
|
871
|
+
}
|
|
859
872
|
}
|
|
860
873
|
// message priority
|
|
861
874
|
if (triggeredSend.priority) {
|
|
@@ -1150,6 +1163,8 @@ class Journey extends MetadataType {
|
|
|
1150
1163
|
delete activity.metaData.highThroughput.r__dataExtension_key;
|
|
1151
1164
|
}
|
|
1152
1165
|
|
|
1166
|
+
this._preDeployTasks_activities(metadata);
|
|
1167
|
+
|
|
1153
1168
|
break;
|
|
1154
1169
|
}
|
|
1155
1170
|
default: {
|
|
@@ -1306,6 +1321,25 @@ class Journey extends MetadataType {
|
|
|
1306
1321
|
);
|
|
1307
1322
|
delete triggeredSend.r__sendClassification_key;
|
|
1308
1323
|
}
|
|
1324
|
+
// delivery profile
|
|
1325
|
+
if (triggeredSend.r__deliveryProfile_key) {
|
|
1326
|
+
// remove it because we cannot resolve it and it should be set by selecting the sendClassification
|
|
1327
|
+
try {
|
|
1328
|
+
triggeredSend.deliveryProfileId = cache.searchForField(
|
|
1329
|
+
'deliveryProfile',
|
|
1330
|
+
triggeredSend.r__deliveryProfile_key,
|
|
1331
|
+
'key',
|
|
1332
|
+
'ObjectID'
|
|
1333
|
+
);
|
|
1334
|
+
delete triggeredSend.r__deliveryProfile_key;
|
|
1335
|
+
} catch (ex) {
|
|
1336
|
+
Util.logger.error(
|
|
1337
|
+
`Could not find the ID for Delivery Profile '${triggeredSend.r__deliveryProfile_key}'. Please note that this can only be resolved if you have at least ONE Send Classification set up on the target BU that uses a Delivery Profile with this key.`
|
|
1338
|
+
);
|
|
1339
|
+
throw ex;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1309
1343
|
// message priority
|
|
1310
1344
|
if (triggeredSend.c__priority) {
|
|
1311
1345
|
triggeredSend.priority =
|
|
@@ -1824,41 +1858,54 @@ class Journey extends MetadataType {
|
|
|
1824
1858
|
}).start();
|
|
1825
1859
|
const transactionalKeyArr = (await Promise.all(resultsTransactional)).filter(Boolean);
|
|
1826
1860
|
spinner.success('done.');
|
|
1827
|
-
executedKeyArr.push(...transactionalKeyArr);
|
|
1828
1861
|
|
|
1829
|
-
|
|
1830
|
-
|
|
1862
|
+
// if all publish actions failed, we don't need to re-retrieve anything here
|
|
1863
|
+
if (transactionalKeyArr.length) {
|
|
1864
|
+
executedKeyArr.push(...transactionalKeyArr);
|
|
1831
1865
|
|
|
1832
|
-
|
|
1833
|
-
const
|
|
1834
|
-
['journey'],
|
|
1835
|
-
transactionalKeyArr
|
|
1836
|
-
);
|
|
1866
|
+
Util.logger.info('Retrieving relevant journeys');
|
|
1867
|
+
const retriever = new Retriever(this.properties, this.buObject);
|
|
1837
1868
|
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
)
|
|
1869
|
+
try {
|
|
1870
|
+
const updatedJourneyRetrieve = await retriever.retrieve(
|
|
1871
|
+
['journey'],
|
|
1872
|
+
transactionalKeyArr
|
|
1873
|
+
);
|
|
1874
|
+
|
|
1875
|
+
/** @type {MetadataTypeItem[]} */
|
|
1876
|
+
const updatedJourneys =
|
|
1877
|
+
updatedJourneyRetrieve?.journey?.length > 1
|
|
1878
|
+
? Object.values(
|
|
1879
|
+
updatedJourneyRetrieve?.journey.reduce(
|
|
1880
|
+
(previousValue, currentValue) =>
|
|
1881
|
+
Object.assign(previousValue, currentValue),
|
|
1882
|
+
{}
|
|
1883
|
+
)
|
|
1884
|
+
)
|
|
1885
|
+
: Object.values(updatedJourneyRetrieve?.journey[0]);
|
|
1886
|
+
if (updatedJourneys) {
|
|
1887
|
+
const updatedTransactionalEmails = [];
|
|
1888
|
+
for (const journey of updatedJourneys) {
|
|
1889
|
+
updatedTransactionalEmails.push(
|
|
1890
|
+
journey.activities?.[0]?.configurationArguments
|
|
1891
|
+
?.r__transactionalEmail_key
|
|
1892
|
+
);
|
|
1893
|
+
}
|
|
1894
|
+
if (updatedTransactionalEmails.filter(Boolean).length) {
|
|
1895
|
+
Util.logger.info('Retrieving relevant transactionalEmails');
|
|
1896
|
+
await retriever.retrieve(
|
|
1897
|
+
['transactionalEmail'],
|
|
1898
|
+
updatedTransactionalEmails.filter(Boolean)
|
|
1899
|
+
);
|
|
1900
|
+
} else {
|
|
1901
|
+
Util.logger.error(
|
|
1902
|
+
`Could not find transactional Emails for the published journeys`
|
|
1903
|
+
);
|
|
1904
|
+
}
|
|
1858
1905
|
}
|
|
1906
|
+
} catch (ex) {
|
|
1907
|
+
Util.logger.errorStack(ex, 'retrieve failed');
|
|
1859
1908
|
}
|
|
1860
|
-
} catch (ex) {
|
|
1861
|
-
Util.logger.errorStack(ex, 'retrieve failed');
|
|
1862
1909
|
}
|
|
1863
1910
|
}
|
|
1864
1911
|
Util.logger.info(
|
|
@@ -47,6 +47,20 @@ class SendClassification extends MetadataType {
|
|
|
47
47
|
return super.retrieveSOAP(retrieveDir, requestParams, key);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Retrieves event definition metadata for caching
|
|
52
|
+
*
|
|
53
|
+
* @returns {Promise.<MetadataTypeMapObj>} Promise of metadata
|
|
54
|
+
*/
|
|
55
|
+
static async retrieveForCache() {
|
|
56
|
+
const typeMap = await this.retrieve(null);
|
|
57
|
+
for (const item of Object.values(typeMap.metadata)) {
|
|
58
|
+
// run postRetrieveTasks to cross-update deliveryProfile cache
|
|
59
|
+
this.postRetrieveTasks(item);
|
|
60
|
+
}
|
|
61
|
+
return typeMap;
|
|
62
|
+
}
|
|
63
|
+
|
|
50
64
|
/**
|
|
51
65
|
* Updates a single item
|
|
52
66
|
*
|
|
@@ -100,13 +114,15 @@ class SendClassification extends MetadataType {
|
|
|
100
114
|
};
|
|
101
115
|
delete metadata.r__senderProfile_key;
|
|
102
116
|
|
|
117
|
+
const dpId = cache.searchForField(
|
|
118
|
+
'deliveryProfile',
|
|
119
|
+
metadata.r__deliveryProfile_key,
|
|
120
|
+
'key',
|
|
121
|
+
'ObjectID'
|
|
122
|
+
);
|
|
103
123
|
metadata.DeliveryProfile = {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
metadata.r__deliveryProfile_key,
|
|
107
|
-
'key',
|
|
108
|
-
'key'
|
|
109
|
-
),
|
|
124
|
+
ObjectID: dpId,
|
|
125
|
+
CustomerKey: metadata.r__deliveryProfile_key,
|
|
110
126
|
};
|
|
111
127
|
delete metadata.r__deliveryProfile_key;
|
|
112
128
|
|
|
@@ -126,16 +142,21 @@ class SendClassification extends MetadataType {
|
|
|
126
142
|
);
|
|
127
143
|
delete metadata.SendClassificationType;
|
|
128
144
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
metadata.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
145
|
+
if (cache.getCache().senderProfile) {
|
|
146
|
+
// when sendClassification was only cached it can happen that we don't have the senderProfile cache yet
|
|
147
|
+
try {
|
|
148
|
+
metadata.r__senderProfile_key = cache.searchForField(
|
|
149
|
+
'senderProfile',
|
|
150
|
+
metadata.SenderProfile.ObjectID,
|
|
151
|
+
'ObjectID',
|
|
152
|
+
'CustomerKey'
|
|
153
|
+
);
|
|
154
|
+
delete metadata.SenderProfile;
|
|
155
|
+
} catch (ex) {
|
|
156
|
+
Util.logger.warn(
|
|
157
|
+
` - ${this.definition.type} ${metadata.CustomerKey}: ${ex.message}`
|
|
158
|
+
);
|
|
159
|
+
}
|
|
139
160
|
}
|
|
140
161
|
try {
|
|
141
162
|
metadata.r__deliveryProfile_key = cache.searchForField(
|
|
@@ -144,6 +165,16 @@ class SendClassification extends MetadataType {
|
|
|
144
165
|
'key',
|
|
145
166
|
'key'
|
|
146
167
|
);
|
|
168
|
+
// add ObjectID to deliveryProfile cache because it cannot be retrieved any other way and this way we can resolve it in journeys
|
|
169
|
+
const dp = cache.getByKey('deliveryProfile', metadata.DeliveryProfile.CustomerKey);
|
|
170
|
+
if (dp) {
|
|
171
|
+
dp.ObjectID = metadata.DeliveryProfile.ObjectID;
|
|
172
|
+
} else {
|
|
173
|
+
Util.logger.debug(
|
|
174
|
+
` - ${this.definition.type} ${metadata.CustomerKey}: Could not find deliveryProfile ${metadata.DeliveryProfile.CustomerKey} in cache`
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
147
178
|
delete metadata.DeliveryProfile;
|
|
148
179
|
} catch (ex) {
|
|
149
180
|
Util.logger.warn(` - ${this.definition.type} ${metadata.CustomerKey}: ${ex.message}`);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
import MetadataType from './MetadataType.js';
|
|
4
|
+
import cache from '../util/cache.js';
|
|
4
5
|
import { Util } from '../util/util.js';
|
|
5
6
|
import ReplaceCbReference from '../util/replaceContentBlockReference.js';
|
|
6
7
|
|
|
@@ -77,6 +78,50 @@ class SenderProfile extends MetadataType {
|
|
|
77
78
|
return super.deleteByKeySOAP(customerKey);
|
|
78
79
|
}
|
|
79
80
|
|
|
81
|
+
/**
|
|
82
|
+
* manages post retrieve steps
|
|
83
|
+
*
|
|
84
|
+
* @param {MetadataTypeItem} metadata a single item
|
|
85
|
+
* @returns {MetadataTypeItem} a single item
|
|
86
|
+
*/
|
|
87
|
+
static postRetrieveTasks(metadata) {
|
|
88
|
+
// makes or easier reading
|
|
89
|
+
if (metadata.Client) {
|
|
90
|
+
try {
|
|
91
|
+
metadata.createdBy = cache.searchForField(
|
|
92
|
+
'user',
|
|
93
|
+
metadata.Client.CreatedBy,
|
|
94
|
+
'AccountUserID',
|
|
95
|
+
'Name'
|
|
96
|
+
);
|
|
97
|
+
} catch (ex) {
|
|
98
|
+
Util.logger.verbose(
|
|
99
|
+
` - ${this.definition.type} ${metadata[this.definition.nameField]} (${
|
|
100
|
+
metadata[this.definition.keyField]
|
|
101
|
+
}): ${ex.message}.`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
metadata.modifiedBy = cache.searchForField(
|
|
107
|
+
'user',
|
|
108
|
+
metadata.Client.ModifiedBy,
|
|
109
|
+
'AccountUserID',
|
|
110
|
+
'Name'
|
|
111
|
+
);
|
|
112
|
+
} catch (ex) {
|
|
113
|
+
Util.logger.verbose(
|
|
114
|
+
` - ${this.definition.type} ${metadata[this.definition.nameField]} (${
|
|
115
|
+
metadata[this.definition.keyField]
|
|
116
|
+
}): ${ex.message}.`
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
delete metadata.Client;
|
|
121
|
+
}
|
|
122
|
+
return metadata;
|
|
123
|
+
}
|
|
124
|
+
|
|
80
125
|
/**
|
|
81
126
|
* prepares a single item for deployment
|
|
82
127
|
*
|
|
@@ -84,6 +129,10 @@ class SenderProfile extends MetadataType {
|
|
|
84
129
|
* @returns {Promise.<MetadataTypeItem>} Promise
|
|
85
130
|
*/
|
|
86
131
|
static async preDeployTasks(metadata) {
|
|
132
|
+
// cleanup
|
|
133
|
+
delete metadata.createdBy;
|
|
134
|
+
delete metadata.modifiedBy;
|
|
135
|
+
|
|
87
136
|
if (
|
|
88
137
|
metadata.UseDefaultRMMRules &&
|
|
89
138
|
(metadata.AutoForwardToEmailAddress !== '' || metadata.AutoForwardToName !== '')
|
|
@@ -33,6 +33,7 @@ import cache from '../util/cache.js';
|
|
|
33
33
|
*/
|
|
34
34
|
class User extends MetadataType {
|
|
35
35
|
static userBUassignments;
|
|
36
|
+
static userIdBuMap;
|
|
36
37
|
|
|
37
38
|
/**
|
|
38
39
|
* Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata
|
|
@@ -44,7 +45,8 @@ class User extends MetadataType {
|
|
|
44
45
|
* @returns {Promise.<MetadataTypeMapObj>} Promise of metadata
|
|
45
46
|
*/
|
|
46
47
|
static async retrieve(retrieveDir, _, __, key) {
|
|
47
|
-
if (this.buObject.eid !== this.buObject.mid) {
|
|
48
|
+
if (retrieveDir && this.buObject.eid !== this.buObject.mid) {
|
|
49
|
+
// only skip if this was not for caching
|
|
48
50
|
Util.logger.info(' - Skipping User retrieval on non-parent BU');
|
|
49
51
|
return;
|
|
50
52
|
}
|
|
@@ -217,6 +219,22 @@ class User extends MetadataType {
|
|
|
217
219
|
return metadata;
|
|
218
220
|
}
|
|
219
221
|
|
|
222
|
+
/**
|
|
223
|
+
* MetadataType upsert, after retrieving from target and comparing to check if create or update operation is needed.
|
|
224
|
+
*
|
|
225
|
+
* @param {MetadataTypeMap} metadataMap metadata mapped by their keyField
|
|
226
|
+
* @param {string} deployDir directory where deploy metadata are saved
|
|
227
|
+
* @param {boolean} [runUpsertSequentially] when a type has self-dependencies creates need to run one at a time and created/changed keys need to be cached to ensure following creates/updates have thoses keys available
|
|
228
|
+
* @returns {Promise.<MetadataTypeMap>} keyField => metadata map
|
|
229
|
+
*/
|
|
230
|
+
static async upsert(metadataMap, deployDir, runUpsertSequentially = false) {
|
|
231
|
+
if (typeof this.userIdBuMap !== 'object' || Object.keys(this.userIdBuMap).length === 0) {
|
|
232
|
+
this.cacheBusinessUnitAssignments();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return super.upsert(metadataMap, deployDir, runUpsertSequentially);
|
|
236
|
+
}
|
|
237
|
+
|
|
220
238
|
/**
|
|
221
239
|
* helper for {@link MetadataType.upsert}
|
|
222
240
|
*
|
|
@@ -256,6 +274,7 @@ class User extends MetadataType {
|
|
|
256
274
|
}
|
|
257
275
|
|
|
258
276
|
/**
|
|
277
|
+
* helper for {@link createOrUpdate}
|
|
259
278
|
*
|
|
260
279
|
* @private
|
|
261
280
|
* @param {MetadataTypeItem} metadata single metadata itme
|
|
@@ -313,7 +332,7 @@ class User extends MetadataType {
|
|
|
313
332
|
}
|
|
314
333
|
|
|
315
334
|
/**
|
|
316
|
-
* create/update business unit assignments
|
|
335
|
+
* create/update business unit assignments. helper for {@link postDeployTasks}
|
|
317
336
|
*
|
|
318
337
|
* @private
|
|
319
338
|
* @param {UserDocumentMap} upsertResults metadata mapped by their keyField
|
|
@@ -589,7 +608,6 @@ class User extends MetadataType {
|
|
|
589
608
|
* @returns {Promise.<MetadataTypeMapObj>} Promise of metadata
|
|
590
609
|
*/
|
|
591
610
|
static async _retrieve(retrieveDir, key) {
|
|
592
|
-
this.userIdBuMap = {};
|
|
593
611
|
/** @type {SoapRequestParams} */
|
|
594
612
|
const requestParams = {
|
|
595
613
|
QueryAllAccounts: true,
|
|
@@ -693,50 +711,18 @@ class User extends MetadataType {
|
|
|
693
711
|
}
|
|
694
712
|
|
|
695
713
|
const metadata = this.parseResponseBody(resultsBulk);
|
|
696
|
-
|
|
697
|
-
if (resultsBulk?.Results?.length > 0) {
|
|
714
|
+
if (retrieveDir) {
|
|
698
715
|
if (!singleRetrieve) {
|
|
699
716
|
Util.logger.info(
|
|
700
717
|
Util.getGrayMsg(` - found ${resultsBulk?.Results.length} users`)
|
|
701
718
|
);
|
|
702
719
|
}
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
for (let i = 0; i < resultsBulk?.Results?.length; i += chunkSize) {
|
|
708
|
-
if (i > 0) {
|
|
709
|
-
Util.logger.info(
|
|
710
|
-
Util.getGrayMsg(` - Requesting next batch (retrieved BUs for ${i} users)`)
|
|
711
|
-
);
|
|
712
|
-
}
|
|
713
|
-
const chunk = resultsBulk?.Results?.slice(i, i + chunkSize);
|
|
714
|
-
const resultsBatch = (
|
|
715
|
-
await this.client.soap.retrieveBulk(
|
|
716
|
-
'AccountUserAccount',
|
|
717
|
-
['AccountUser.AccountUserID', 'Account.ID'],
|
|
718
|
-
{
|
|
719
|
-
filter: {
|
|
720
|
-
leftOperand: 'AccountUser.AccountUserID',
|
|
721
|
-
operator: chunk.length > 1 ? 'IN' : 'equals', // API does not allow IN for single item
|
|
722
|
-
rightOperand: chunk.map((item) => item.AccountUserID),
|
|
723
|
-
},
|
|
724
|
-
}
|
|
725
|
-
)
|
|
726
|
-
).Results;
|
|
727
|
-
for (const item of resultsBatch) {
|
|
728
|
-
this.userIdBuMap[item.AccountUser.AccountUserID] ||= [];
|
|
729
|
-
// push to array if not already in array
|
|
730
|
-
if (
|
|
731
|
-
!this.userIdBuMap[item.AccountUser.AccountUserID].includes(item.Account.ID)
|
|
732
|
-
) {
|
|
733
|
-
this.userIdBuMap[item.AccountUser.AccountUserID].push(item.Account.ID);
|
|
734
|
-
}
|
|
735
|
-
}
|
|
720
|
+
if (resultsBulk?.Results?.length > 0) {
|
|
721
|
+
// get BUs that each users have access to
|
|
722
|
+
// split array resultsBulk?.Results into chunks to avoid not getting all roles
|
|
723
|
+
await this.cacheBusinessUnitAssignments(resultsBulk.Results);
|
|
736
724
|
}
|
|
737
|
-
}
|
|
738
725
|
|
|
739
|
-
if (retrieveDir) {
|
|
740
726
|
const savedMetadata = await this.saveResults(metadata, retrieveDir, null);
|
|
741
727
|
Util.logger.info(
|
|
742
728
|
`Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` +
|
|
@@ -771,6 +757,54 @@ class User extends MetadataType {
|
|
|
771
757
|
return { metadata: metadata, type: this.definition.type };
|
|
772
758
|
}
|
|
773
759
|
|
|
760
|
+
/**
|
|
761
|
+
* helper for {@link retrieveSOAP} and {@link upsert}; populates userIdBuMap
|
|
762
|
+
*
|
|
763
|
+
* @param {MetadataTypeItem[]} [metadataList] -
|
|
764
|
+
* @returns {Promise.<void>} -
|
|
765
|
+
*/
|
|
766
|
+
static async cacheBusinessUnitAssignments(metadataList) {
|
|
767
|
+
if (!metadataList) {
|
|
768
|
+
// if run via upsert() then we won't have the metadataList with AccountUserID anywhere but in cache
|
|
769
|
+
const cacheUsers = cache.getCache().user;
|
|
770
|
+
metadataList = cacheUsers ? Object.values(cacheUsers) : [];
|
|
771
|
+
}
|
|
772
|
+
const chunkSize = 100;
|
|
773
|
+
this.userIdBuMap = {};
|
|
774
|
+
Util.logger.info(` - Caching dependent Metadata: Business Unit assignments`);
|
|
775
|
+
for (let i = 0; i < metadataList?.length; i += chunkSize) {
|
|
776
|
+
if (i > 0) {
|
|
777
|
+
Util.logger.info(
|
|
778
|
+
Util.getGrayMsg(` - Requesting next batch (retrieved BUs for ${i} users)`)
|
|
779
|
+
);
|
|
780
|
+
}
|
|
781
|
+
const accountUserIDList = metadataList
|
|
782
|
+
.map((item) => item.AccountUserID)
|
|
783
|
+
.filter(Boolean);
|
|
784
|
+
const chunk = accountUserIDList?.slice(i, i + chunkSize);
|
|
785
|
+
const resultsBatch = (
|
|
786
|
+
await this.client.soap.retrieveBulk(
|
|
787
|
+
'AccountUserAccount',
|
|
788
|
+
['AccountUser.AccountUserID', 'Account.ID'],
|
|
789
|
+
{
|
|
790
|
+
filter: {
|
|
791
|
+
leftOperand: 'AccountUser.AccountUserID',
|
|
792
|
+
operator: chunk.length > 1 ? 'IN' : 'equals', // API does not allow IN for single item
|
|
793
|
+
rightOperand: chunk,
|
|
794
|
+
},
|
|
795
|
+
}
|
|
796
|
+
)
|
|
797
|
+
).Results;
|
|
798
|
+
for (const item of resultsBatch) {
|
|
799
|
+
this.userIdBuMap[item.AccountUser.AccountUserID] ||= [];
|
|
800
|
+
// push to array if not already in array
|
|
801
|
+
if (!this.userIdBuMap[item.AccountUser.AccountUserID].includes(item.Account.ID)) {
|
|
802
|
+
this.userIdBuMap[item.AccountUser.AccountUserID].push(item.Account.ID);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
|
|
774
808
|
/**
|
|
775
809
|
* helper for {@link User.retrieveSOAP}
|
|
776
810
|
*
|
|
@@ -217,6 +217,21 @@ class Verification extends MetadataType {
|
|
|
217
217
|
* @returns {VerificationItem} Array with one metadata object and one sql string
|
|
218
218
|
*/
|
|
219
219
|
static postRetrieveTasks(metadata) {
|
|
220
|
+
try {
|
|
221
|
+
// @ts-expect-error
|
|
222
|
+
metadata.createdBy = cache.searchForField(
|
|
223
|
+
'user',
|
|
224
|
+
metadata.createdBy,
|
|
225
|
+
'AccountUserID',
|
|
226
|
+
'Name'
|
|
227
|
+
);
|
|
228
|
+
} catch (ex) {
|
|
229
|
+
Util.logger.verbose(
|
|
230
|
+
` - ${this.definition.type} ${metadata[this.definition.nameField]} (${
|
|
231
|
+
metadata[this.definition.keyField]
|
|
232
|
+
}): ${ex.message}.`
|
|
233
|
+
);
|
|
234
|
+
}
|
|
220
235
|
try {
|
|
221
236
|
metadata.r__dataExtension_key = cache.searchForField(
|
|
222
237
|
'dataExtension',
|
|
@@ -9,6 +9,7 @@ export default {
|
|
|
9
9
|
'folder-journey',
|
|
10
10
|
'triggeredSend', // for EMAILV2-activity
|
|
11
11
|
'dataExtension', // for transactionalEmails: EMAILV2-activity
|
|
12
|
+
'deliveryProfile',
|
|
12
13
|
'event', // for Multistep and Quicksend journeys
|
|
13
14
|
'mobileMessage', // for SMSSYNC-activity
|
|
14
15
|
'mobileCode', // for SMSSYNC-activity
|
|
@@ -27,6 +28,7 @@ export default {
|
|
|
27
28
|
'activities.metaData.highThroughput.r__dataExtension_key',
|
|
28
29
|
'activities.configurationArguments.triggeredSend.r__dataExtension_key.domainExclusions',
|
|
29
30
|
],
|
|
31
|
+
deliveryProfile: ['activities.configurationArguments.triggeredSend.r__deliveryProfile_key'],
|
|
30
32
|
list: [
|
|
31
33
|
'activities.configurationArguments.triggeredSend.r__list_PathName.publicationList',
|
|
32
34
|
'activities.configurationArguments.triggeredSend.r__list_PathName.suppressionLists',
|
|
@@ -303,6 +305,12 @@ export default {
|
|
|
303
305
|
retrieving: true,
|
|
304
306
|
template: true,
|
|
305
307
|
},
|
|
308
|
+
'activities[].configurationArguments.triggeredSend.deliveryProfileId': {
|
|
309
|
+
isCreateable: true,
|
|
310
|
+
isUpdateable: true,
|
|
311
|
+
retrieving: true,
|
|
312
|
+
template: true,
|
|
313
|
+
},
|
|
306
314
|
'activities[].configurationArguments.triggeredSend.r__senderProfile_key': {
|
|
307
315
|
isCreateable: false,
|
|
308
316
|
isUpdateable: false,
|
|
@@ -315,6 +323,12 @@ export default {
|
|
|
315
323
|
retrieving: true,
|
|
316
324
|
template: true,
|
|
317
325
|
},
|
|
326
|
+
'activities[].configurationArguments.triggeredSend.r__deliveryProfile_key': {
|
|
327
|
+
isCreateable: false,
|
|
328
|
+
isUpdateable: false,
|
|
329
|
+
retrieving: true,
|
|
330
|
+
template: true,
|
|
331
|
+
},
|
|
318
332
|
'activities[].configurationArguments.triggeredSend.r__sendClassification_key': {
|
|
319
333
|
isCreateable: false,
|
|
320
334
|
isUpdateable: false,
|
|
@@ -10,9 +10,9 @@ export default {
|
|
|
10
10
|
nameField: 'name',
|
|
11
11
|
folderIdField: 'categoryId',
|
|
12
12
|
createdDateField: 'createdDate',
|
|
13
|
-
createdNameField:
|
|
13
|
+
createdNameField: null,
|
|
14
14
|
lastmodDateField: 'modifiedDate',
|
|
15
|
-
lastmodNameField:
|
|
15
|
+
lastmodNameField: null,
|
|
16
16
|
restPagination: true,
|
|
17
17
|
type: 'script',
|
|
18
18
|
typeDescription: 'Execute more complex tasks via SSJS or AMPScript.',
|
|
@@ -26,6 +26,7 @@ export default {
|
|
|
26
26
|
template: true,
|
|
27
27
|
},
|
|
28
28
|
createdBy: {
|
|
29
|
+
// not existing in rest api
|
|
29
30
|
isCreateable: false,
|
|
30
31
|
isUpdateable: false,
|
|
31
32
|
retrieving: false,
|
|
@@ -56,6 +57,7 @@ export default {
|
|
|
56
57
|
template: true,
|
|
57
58
|
},
|
|
58
59
|
modifiedBy: {
|
|
60
|
+
// not existing in rest api
|
|
59
61
|
isCreateable: false,
|
|
60
62
|
isUpdateable: false,
|
|
61
63
|
retrieving: false,
|