mcdev 7.3.0 → 7.4.0
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 +2 -0
- package/.github/PULL_REQUEST_TEMPLATE/pr_template_release.md +3 -3
- package/.vscode/settings.json +1 -1
- package/@types/lib/index.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Asset.d.ts +25 -0
- package/@types/lib/metadataTypes/Asset.d.ts.map +1 -1
- package/@types/lib/metadataTypes/DataExtension.d.ts +3 -2
- package/@types/lib/metadataTypes/DataExtension.d.ts.map +1 -1
- package/@types/lib/metadataTypes/DataExtensionField.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Event.d.ts +33 -0
- package/@types/lib/metadataTypes/Event.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Journey.d.ts +4 -2
- package/@types/lib/metadataTypes/Journey.d.ts.map +1 -1
- package/@types/lib/metadataTypes/MetadataType.d.ts +22 -3
- package/@types/lib/metadataTypes/MetadataType.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Role.d.ts +7 -0
- package/@types/lib/metadataTypes/Role.d.ts.map +1 -1
- package/@types/lib/util/init.config.d.ts.map +1 -1
- package/@types/lib/util/replaceContentBlockReference.d.ts +4 -5
- package/@types/lib/util/replaceContentBlockReference.d.ts.map +1 -1
- package/@types/lib/util/util.d.ts +11 -2
- package/@types/lib/util/util.d.ts.map +1 -1
- package/@types/lib/util/validations.d.ts +9 -0
- package/@types/lib/util/validations.d.ts.map +1 -0
- package/boilerplate/config.json +22 -0
- package/boilerplate/files/.gitattributes +1 -1
- package/boilerplate/files/.vscode/settings.json +3 -2
- package/boilerplate/files/README.md +1 -1
- package/boilerplate/forcedUpdates.json +8 -0
- package/lib/cli.js +28 -3
- package/lib/index.js +3 -2
- package/lib/metadataTypes/Asset.js +87 -7
- package/lib/metadataTypes/DataExtension.js +74 -4
- package/lib/metadataTypes/DataExtensionField.js +7 -1
- package/lib/metadataTypes/Event.js +254 -200
- package/lib/metadataTypes/Journey.js +242 -132
- package/lib/metadataTypes/MetadataType.js +182 -37
- package/lib/metadataTypes/Role.js +47 -35
- package/lib/util/init.config.js +10 -6
- package/lib/util/replaceContentBlockReference.js +15 -11
- package/lib/util/util.js +29 -9
- package/lib/util/validations.js +66 -0
- package/package.json +7 -2
- package/test/general.test.js +5 -2
- package/test/mockRoot/.mcdevrc.json +15 -1
- package/test/type.journey.test.js +11 -11
- package/test/utils.js +1 -0
- /package/test/resources/9999999/interaction/v1/interactions/publishAsync/{3c3f4112-9b43-43ca-8a89-aa0375b2c1a2 → 0175b971-71a3-4d8e-98ac-48121f3fbf4f}/post-response.json +0 -0
package/lib/cli.js
CHANGED
|
@@ -163,7 +163,14 @@ yargs(hideBin(process.argv))
|
|
|
163
163
|
group: 'Options for deploy:',
|
|
164
164
|
describe:
|
|
165
165
|
'Some metadata types allow updating resources despite a key mismatch by matching the name. That avoids clean-ups on all BUs but instead allows you to continously get higher environmetns into a better shape.',
|
|
166
|
+
})
|
|
167
|
+
.option('skipValidation', {
|
|
168
|
+
alias: 'sv',
|
|
169
|
+
group: 'Options for deploy:',
|
|
170
|
+
describe:
|
|
171
|
+
'allows reducing validation rules from error to warn to handle edge cases',
|
|
166
172
|
}),
|
|
173
|
+
|
|
167
174
|
(argv) => {
|
|
168
175
|
Mcdev.setOptions(argv);
|
|
169
176
|
|
|
@@ -395,6 +402,12 @@ yargs(hideBin(process.argv))
|
|
|
395
402
|
group: 'Options for build:',
|
|
396
403
|
describe:
|
|
397
404
|
're-retrieves potentially relevant metadata before running buildTemplate (all if --dependencies is used)',
|
|
405
|
+
})
|
|
406
|
+
.option('skipValidation', {
|
|
407
|
+
alias: 'sv',
|
|
408
|
+
group: 'Options for build:',
|
|
409
|
+
describe:
|
|
410
|
+
'allows reducing validation rules from error to warn to handle edge cases',
|
|
398
411
|
}),
|
|
399
412
|
(argv) => {
|
|
400
413
|
Mcdev.setOptions(argv);
|
|
@@ -521,6 +534,12 @@ yargs(hideBin(process.argv))
|
|
|
521
534
|
group: 'Options for buildDefinition:',
|
|
522
535
|
describe: 'market used for building deployable definition',
|
|
523
536
|
})
|
|
537
|
+
.option('skipValidation', {
|
|
538
|
+
alias: 'sv',
|
|
539
|
+
group: 'Options for buildDefinition:',
|
|
540
|
+
describe:
|
|
541
|
+
'allows reducing validation rules from error to warn to handle edge cases',
|
|
542
|
+
})
|
|
524
543
|
.check((argv) => {
|
|
525
544
|
if (!argv.MARKET && !argv.market) {
|
|
526
545
|
throw new Error(
|
|
@@ -572,6 +591,12 @@ yargs(hideBin(process.argv))
|
|
|
572
591
|
alias: 'm',
|
|
573
592
|
group: 'Options for buildDefinitionBulk:',
|
|
574
593
|
describe: 'type:templateName combos to build template for',
|
|
594
|
+
})
|
|
595
|
+
.option('skipValidation', {
|
|
596
|
+
alias: 'sv',
|
|
597
|
+
group: 'Options for deploy:',
|
|
598
|
+
describe:
|
|
599
|
+
'allows reducing validation rules from error to warn to handle edge cases',
|
|
575
600
|
}),
|
|
576
601
|
(argv) => {
|
|
577
602
|
Mcdev.setOptions(argv);
|
|
@@ -679,8 +704,8 @@ yargs(hideBin(process.argv))
|
|
|
679
704
|
}
|
|
680
705
|
)
|
|
681
706
|
.command(
|
|
682
|
-
['execute <BU> [TYPE] [KEY]', 'exec', 'start'],
|
|
683
|
-
'executes the entity
|
|
707
|
+
['execute <BU> [TYPE] [KEY]', 'exec', 'start', 'resume'],
|
|
708
|
+
'executes the entity',
|
|
684
709
|
(yargs) =>
|
|
685
710
|
yargs
|
|
686
711
|
.positional('BU', {
|
|
@@ -733,7 +758,7 @@ yargs(hideBin(process.argv))
|
|
|
733
758
|
}
|
|
734
759
|
)
|
|
735
760
|
.command(
|
|
736
|
-
['publish <BU> [TYPE] [KEY]'],
|
|
761
|
+
['publish <BU> [TYPE] [KEY]', 'activate'],
|
|
737
762
|
'publishes the entity',
|
|
738
763
|
(yargs) =>
|
|
739
764
|
yargs
|
package/lib/index.js
CHANGED
|
@@ -113,6 +113,7 @@ class Mcdev {
|
|
|
113
113
|
'skipInteraction',
|
|
114
114
|
'skipRetrieve',
|
|
115
115
|
'skipStatusCheck',
|
|
116
|
+
'skipValidation',
|
|
116
117
|
'_runningTest',
|
|
117
118
|
'_welcomeMessageShown',
|
|
118
119
|
];
|
|
@@ -939,7 +940,7 @@ class Mcdev {
|
|
|
939
940
|
'Searching for additional dependencies that were linked via ContentBlockByKey, ContentBlockByName and ContentBlockById'
|
|
940
941
|
);
|
|
941
942
|
|
|
942
|
-
await ReplaceContentBlockReference.
|
|
943
|
+
await ReplaceContentBlockReference.createCache(properties, buObject, true);
|
|
943
944
|
|
|
944
945
|
// because we re-use the replaceReference logic here we need to manually set this value
|
|
945
946
|
/** @type {ContentBlockConversionTypes[]} */
|
|
@@ -2073,7 +2074,7 @@ class Mcdev {
|
|
|
2073
2074
|
buObject.businessUnit,
|
|
2074
2075
|
]);
|
|
2075
2076
|
|
|
2076
|
-
await ReplaceContentBlockReference.
|
|
2077
|
+
await ReplaceContentBlockReference.createCache(properties, buObject);
|
|
2077
2078
|
|
|
2078
2079
|
try {
|
|
2079
2080
|
let metadataMap;
|
|
@@ -9,6 +9,7 @@ import cache from '../util/cache.js';
|
|
|
9
9
|
import TriggeredSend from './TriggeredSend.js';
|
|
10
10
|
import Folder from './Folder.js';
|
|
11
11
|
import ReplaceCbReference from '../util/replaceContentBlockReference.js';
|
|
12
|
+
import toposort from 'toposort';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* @typedef {import('../../types/mcdev.d.js').BuObject} BuObject
|
|
@@ -27,6 +28,7 @@ import ReplaceCbReference from '../util/replaceContentBlockReference.js';
|
|
|
27
28
|
* @typedef {import('../../types/mcdev.d.js').AssetMap} AssetMap
|
|
28
29
|
* @typedef {import('../../types/mcdev.d.js').AssetItem} AssetItem
|
|
29
30
|
* @typedef {import('../../types/mcdev.d.js').AssetRequestParams} AssetRequestParams
|
|
31
|
+
* @typedef {import('../../types/mcdev.d.js').ContentBlockConversionTypes} ContentBlockConversionTypes
|
|
30
32
|
*/
|
|
31
33
|
|
|
32
34
|
/**
|
|
@@ -185,6 +187,81 @@ class Asset extends MetadataType {
|
|
|
185
187
|
/* eslint-enable unicorn/prefer-ternary */
|
|
186
188
|
}
|
|
187
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Returns Order in which metadata needs to be retrieved/deployed
|
|
192
|
+
*
|
|
193
|
+
* @param {AssetMap} metadataMap metadata mapped by their keyField
|
|
194
|
+
* @param {string} deployDir directory where deploy metadata are saved
|
|
195
|
+
* @returns {Promise.<AssetMap>} keyField => metadata map but sorted to ensure dependencies are deployed in correct order
|
|
196
|
+
*/
|
|
197
|
+
static async _getUpsertOrder(metadataMap, deployDir) {
|
|
198
|
+
/**
|
|
199
|
+
* one entry for each dependency with the first item being the key thats required by the second item
|
|
200
|
+
*
|
|
201
|
+
* @type {string[][]}
|
|
202
|
+
*/
|
|
203
|
+
const dependencies = [];
|
|
204
|
+
/** @type {ContentBlockConversionTypes[]} */
|
|
205
|
+
Util.OPTIONS.referenceFrom = ['key', 'name', 'id'];
|
|
206
|
+
/** @type {ContentBlockConversionTypes} */
|
|
207
|
+
Util.OPTIONS.referenceTo = 'key';
|
|
208
|
+
// loop through all metadata types which are being retrieved/deployed
|
|
209
|
+
for (const key in metadataMap) {
|
|
210
|
+
const findAssetKeys = new Set();
|
|
211
|
+
try {
|
|
212
|
+
// find asset references in code
|
|
213
|
+
await this.replaceCbReference(metadataMap[key], deployDir, findAssetKeys);
|
|
214
|
+
// find asset references in metadata
|
|
215
|
+
const findAssetKeyMeta = Util.findLeafVals(metadataMap[key], 'r__asset_key');
|
|
216
|
+
for (const metaKey of findAssetKeyMeta) {
|
|
217
|
+
findAssetKeys.add(metaKey);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const dependentKeys = [...findAssetKeys];
|
|
221
|
+
if (dependentKeys.length > 0) {
|
|
222
|
+
dependencies.push(...dependentKeys.map((depKey) => [depKey, key]));
|
|
223
|
+
} else {
|
|
224
|
+
Util.logger.debug('Asset._getUpsertOrder: this case should not happen');
|
|
225
|
+
dependencies.push([undefined, key]);
|
|
226
|
+
}
|
|
227
|
+
} catch (ex) {
|
|
228
|
+
if (ex.code !== 200) {
|
|
229
|
+
Util.logger.errorStack(ex, 'Cannot find related code blocks for ' + key);
|
|
230
|
+
}
|
|
231
|
+
// no dependent keys found
|
|
232
|
+
dependencies.push([undefined, key]);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// sort list & remove the undefined dependencies
|
|
237
|
+
const flatList = toposort(dependencies).filter((a) => !!a);
|
|
238
|
+
|
|
239
|
+
/** @type {AssetMap} */
|
|
240
|
+
const metadataTypeMapSorted = {};
|
|
241
|
+
// group subtypes per type
|
|
242
|
+
for (const key of flatList) {
|
|
243
|
+
metadataTypeMapSorted[key] = metadataMap[key];
|
|
244
|
+
}
|
|
245
|
+
return metadataTypeMapSorted;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* MetadataType upsert, after retrieving from target and comparing to check if create or update operation is needed.
|
|
250
|
+
*
|
|
251
|
+
* @param {AssetMap} metadataMap metadata mapped by their keyField
|
|
252
|
+
* @param {string} deployDir directory where deploy metadata are saved
|
|
253
|
+
* @returns {Promise.<AssetMap>} keyField => metadata map
|
|
254
|
+
*/
|
|
255
|
+
static async upsert(metadataMap, deployDir) {
|
|
256
|
+
if (Object.keys(metadataMap).length > 1) {
|
|
257
|
+
// fill the cache map with our deployment package to ensure we can find
|
|
258
|
+
ReplaceCbReference.createCacheForMap(metadataMap);
|
|
259
|
+
// assets can link to other assets (via template, content block reference and SSJS/AMPscript) and deployment would fail if we did not sort this here
|
|
260
|
+
metadataMap = await this._getUpsertOrder(metadataMap, deployDir);
|
|
261
|
+
}
|
|
262
|
+
return super.upsert(metadataMap, deployDir, true);
|
|
263
|
+
}
|
|
264
|
+
|
|
188
265
|
/**
|
|
189
266
|
* Creates a single asset
|
|
190
267
|
*
|
|
@@ -1037,8 +1114,9 @@ class Asset extends MetadataType {
|
|
|
1037
1114
|
* generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve
|
|
1038
1115
|
*
|
|
1039
1116
|
* @param {MetadataTypeItem} metadata a single script activity definition
|
|
1117
|
+
* @param {boolean} [hideWarning] when checking content blocks we do want to set the folder path but if we cant, lets not cludder the log with warnings about it
|
|
1040
1118
|
*/
|
|
1041
|
-
static setFolderPath(metadata) {
|
|
1119
|
+
static setFolderPath(metadata, hideWarning = false) {
|
|
1042
1120
|
try {
|
|
1043
1121
|
metadata.r__folder_Path = cache.searchForField(
|
|
1044
1122
|
'folder',
|
|
@@ -1048,11 +1126,13 @@ class Asset extends MetadataType {
|
|
|
1048
1126
|
);
|
|
1049
1127
|
delete metadata.category;
|
|
1050
1128
|
} catch (ex) {
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
metadata[this.definition.
|
|
1054
|
-
|
|
1055
|
-
|
|
1129
|
+
if (!hideWarning) {
|
|
1130
|
+
Util.logger.warn(
|
|
1131
|
+
` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${
|
|
1132
|
+
metadata[this.definition.keyField]
|
|
1133
|
+
}): Could not find folder (${ex.message})`
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
1056
1136
|
}
|
|
1057
1137
|
}
|
|
1058
1138
|
|
|
@@ -1827,7 +1907,7 @@ class Asset extends MetadataType {
|
|
|
1827
1907
|
}
|
|
1828
1908
|
}
|
|
1829
1909
|
if (asset.category?.id) {
|
|
1830
|
-
this.setFolderPath(asset);
|
|
1910
|
+
this.setFolderPath(asset, true);
|
|
1831
1911
|
}
|
|
1832
1912
|
|
|
1833
1913
|
if (asset.slots) {
|
|
@@ -42,9 +42,10 @@ class DataExtension extends MetadataType {
|
|
|
42
42
|
* if create or update operation is needed.
|
|
43
43
|
*
|
|
44
44
|
* @param {DataExtensionMap} metadataMap dataExtensions mapped by their customerKey
|
|
45
|
-
* @
|
|
45
|
+
* @param {string} deployDir directory where deploy metadata are saved
|
|
46
|
+
* @returns {Promise.<MetadataTypeMap>} keyField => metadata map
|
|
46
47
|
*/
|
|
47
|
-
static async upsert(metadataMap) {
|
|
48
|
+
static async upsert(metadataMap, deployDir) {
|
|
48
49
|
// get existing DE-fields for DE-keys in deployment package to properly handle add/update/delete of fields
|
|
49
50
|
// we need to use IN here because it would fail otherwise if we try to deploy too many DEs at the same time
|
|
50
51
|
/** @type {SoapRequestParams} */
|
|
@@ -66,6 +67,11 @@ class DataExtension extends MetadataType {
|
|
|
66
67
|
for (const metadataKey in metadataMap) {
|
|
67
68
|
try {
|
|
68
69
|
metadataMap[metadataKey] = await this.preDeployTasks(metadataMap[metadataKey]);
|
|
70
|
+
metadataMap[metadataKey] = await this.validation(
|
|
71
|
+
'deploy',
|
|
72
|
+
metadataMap[metadataKey],
|
|
73
|
+
deployDir
|
|
74
|
+
);
|
|
69
75
|
} catch (ex) {
|
|
70
76
|
// output error & remove from deploy list
|
|
71
77
|
Util.logger.error(
|
|
@@ -187,7 +193,7 @@ class DataExtension extends MetadataType {
|
|
|
187
193
|
DataExtension.oldFields[metadataMap[metadataKey][this.definition.keyField]] =
|
|
188
194
|
await DataExtensionField.prepareDeployColumnsOnUpdate(
|
|
189
195
|
metadataMap[metadataKey].Fields,
|
|
190
|
-
metadataKey
|
|
196
|
+
Util.matchedByName?.[this.definition.type]?.[metadataKey] || metadataKey
|
|
191
197
|
);
|
|
192
198
|
|
|
193
199
|
if (
|
|
@@ -893,7 +899,7 @@ class DataExtension extends MetadataType {
|
|
|
893
899
|
if (metadata[field?.DataExtension?.CustomerKey]) {
|
|
894
900
|
metadata[field.DataExtension.CustomerKey].Fields.push(field);
|
|
895
901
|
} else {
|
|
896
|
-
|
|
902
|
+
// field was retrieved for which we do not have the right dataExtension. This might be due to us having to resort to not using a DE filter to avoid the "String or binary data would be truncated." error
|
|
897
903
|
}
|
|
898
904
|
}
|
|
899
905
|
|
|
@@ -1632,6 +1638,70 @@ class DataExtension extends MetadataType {
|
|
|
1632
1638
|
return super.getFilesToCommit(keyArr);
|
|
1633
1639
|
}
|
|
1634
1640
|
}
|
|
1641
|
+
/**
|
|
1642
|
+
* helper for {@link MetadataType.createOrUpdate}
|
|
1643
|
+
*
|
|
1644
|
+
* @param {MetadataTypeItem} metadataItem to be deployed item
|
|
1645
|
+
* @returns {MetadataTypeItem} cached item or undefined
|
|
1646
|
+
*/
|
|
1647
|
+
static getCacheMatchedByName(metadataItem) {
|
|
1648
|
+
let cacheMatchedByName;
|
|
1649
|
+
|
|
1650
|
+
if (Util.OPTIONS.matchName) {
|
|
1651
|
+
// make sure to run the search ONLY if OPTIONS.matchName is true and definition.allowMatchingByName signals support
|
|
1652
|
+
const typeCache = cache.getCache()?.[this.definition.type];
|
|
1653
|
+
const potentials = [];
|
|
1654
|
+
for (const key in typeCache) {
|
|
1655
|
+
const cachedItem = typeCache[key];
|
|
1656
|
+
if (
|
|
1657
|
+
cachedItem[this.definition.nameField] ===
|
|
1658
|
+
metadataItem[this.definition.nameField]
|
|
1659
|
+
) {
|
|
1660
|
+
potentials.push(cachedItem);
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
if (potentials.length > 1) {
|
|
1664
|
+
throw new Error(
|
|
1665
|
+
`found multiple name matches in cache for ${this.definition.type} ${metadataItem[this.definition.keyField]} / ${metadataItem[this.definition.nameField]}. Check their keys for more details: ${potentials.map((p) => p[this.definition.keyField]).join(', ')}`
|
|
1666
|
+
);
|
|
1667
|
+
} else if (potentials.length === 1) {
|
|
1668
|
+
// only one item found, confirm that it's in the same folder
|
|
1669
|
+
const deployFolderPath = cache.searchForField(
|
|
1670
|
+
'folder',
|
|
1671
|
+
metadataItem[this.definition.folderIdField],
|
|
1672
|
+
'ID',
|
|
1673
|
+
'Path'
|
|
1674
|
+
);
|
|
1675
|
+
if (
|
|
1676
|
+
potentials[0][this.definition.folderIdField] ===
|
|
1677
|
+
metadataItem[this.definition.folderIdField]
|
|
1678
|
+
) {
|
|
1679
|
+
cacheMatchedByName = potentials[0];
|
|
1680
|
+
|
|
1681
|
+
Util.logger.info(
|
|
1682
|
+
Util.getGrayMsg(
|
|
1683
|
+
` - found ${this.definition.type} ${metadataItem[this.definition.keyField]} in cache by name "${metadataItem[this.definition.nameField]}" and folder "${deployFolderPath}": ${cacheMatchedByName[this.definition.keyField]}`
|
|
1684
|
+
)
|
|
1685
|
+
);
|
|
1686
|
+
} else {
|
|
1687
|
+
const cacheFolderPath = cache.searchForField(
|
|
1688
|
+
'folder',
|
|
1689
|
+
potentials[0][this.definition.folderIdField],
|
|
1690
|
+
'ID',
|
|
1691
|
+
'Path'
|
|
1692
|
+
);
|
|
1693
|
+
throw new Error(
|
|
1694
|
+
`found ${this.definition.type} ${metadataItem[this.definition.keyField]} in cache by name "${metadataItem[this.definition.nameField]}" but in different folders: "${deployFolderPath}" vs "${cacheFolderPath}": ${potentials[0][this.definition.keyField]}`
|
|
1695
|
+
);
|
|
1696
|
+
}
|
|
1697
|
+
} else {
|
|
1698
|
+
Util.logger.debug(
|
|
1699
|
+
` - no name-match found for ${this.definition.type} ${metadataItem[this.definition.keyField]}. Creating new ${this.definition.type} instead.`
|
|
1700
|
+
);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
return cacheMatchedByName;
|
|
1704
|
+
}
|
|
1635
1705
|
}
|
|
1636
1706
|
|
|
1637
1707
|
// Assign definition to static attributes
|
|
@@ -48,7 +48,13 @@ class DataExtensionField extends MetadataType {
|
|
|
48
48
|
* @returns {Promise.<{metadata: DataExtensionFieldMap, type: string}>} Promise of items
|
|
49
49
|
*/
|
|
50
50
|
static async retrieveForCacheDE(requestParams, additionalFields) {
|
|
51
|
-
|
|
51
|
+
let response;
|
|
52
|
+
response = await super.retrieveSOAP(null, requestParams, null, additionalFields);
|
|
53
|
+
if (!response) {
|
|
54
|
+
// try again but without filters as a workaround for the "String or binary data would be truncated." issue
|
|
55
|
+
response = await super.retrieveSOAP(null, {}, null, additionalFields);
|
|
56
|
+
}
|
|
57
|
+
return response;
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
/**
|