mcdev 7.6.3 → 7.7.1
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/ISSUE_TEMPLATE/task.md +1 -1
- package/.github/workflows/coverage-base-update.yml +2 -2
- package/.github/workflows/coverage-develop-branch.yml +3 -1
- package/.github/workflows/coverage-main-branch.yml +3 -1
- package/.github/workflows/coverage.yml +5 -3
- package/.mcdev-validations.js +0 -0
- package/@types/lib/Builder.d.ts +14 -0
- package/@types/lib/Builder.d.ts.map +1 -1
- package/@types/lib/MetadataTypeDefinitions.d.ts +2 -0
- package/@types/lib/MetadataTypeDefinitions.d.ts.map +1 -1
- package/@types/lib/MetadataTypeInfo.d.ts +2 -0
- package/@types/lib/MetadataTypeInfo.d.ts.map +1 -1
- package/@types/lib/index.d.ts +17 -8
- package/@types/lib/index.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Asset.d.ts +11 -3
- package/@types/lib/metadataTypes/Asset.d.ts.map +1 -1
- package/@types/lib/metadataTypes/DataExtension.d.ts.map +1 -1
- package/@types/lib/metadataTypes/DomainVerification.d.ts +180 -0
- package/@types/lib/metadataTypes/DomainVerification.d.ts.map +1 -0
- package/@types/lib/metadataTypes/Event.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Journey.d.ts +7 -4
- package/@types/lib/metadataTypes/Journey.d.ts.map +1 -1
- package/@types/lib/metadataTypes/MetadataType.d.ts +15 -7
- package/@types/lib/metadataTypes/MetadataType.d.ts.map +1 -1
- package/@types/lib/metadataTypes/MobileKeyword.d.ts +2 -10
- package/@types/lib/metadataTypes/MobileKeyword.d.ts.map +1 -1
- package/@types/lib/metadataTypes/MobileMessage.d.ts +2 -10
- package/@types/lib/metadataTypes/MobileMessage.d.ts.map +1 -1
- package/@types/lib/metadataTypes/SendClassification.d.ts.map +1 -1
- package/@types/lib/metadataTypes/SenderProfile.d.ts +7 -0
- package/@types/lib/metadataTypes/SenderProfile.d.ts.map +1 -1
- package/@types/lib/metadataTypes/TransactionalEmail.d.ts +2 -2
- package/@types/lib/metadataTypes/TransactionalEmail.d.ts.map +1 -1
- package/@types/lib/metadataTypes/TriggeredSend.d.ts +8 -0
- package/@types/lib/metadataTypes/TriggeredSend.d.ts.map +1 -1
- package/@types/lib/metadataTypes/Verification.d.ts +0 -9
- package/@types/lib/metadataTypes/Verification.d.ts.map +1 -1
- package/@types/lib/metadataTypes/definitions/DomainVerification.definition.d.ts +100 -0
- package/@types/lib/metadataTypes/definitions/DomainVerification.definition.d.ts.map +1 -0
- package/@types/lib/metadataTypes/definitions/Journey.definition.d.ts +1 -1
- package/@types/lib/util/devops.d.ts.map +1 -1
- package/@types/lib/util/replaceContentBlockReference.d.ts +2 -1
- package/@types/lib/util/replaceContentBlockReference.d.ts.map +1 -1
- package/@types/lib/util/util.d.ts +42 -1
- package/@types/lib/util/util.d.ts.map +1 -1
- package/@types/lib/util/validations.d.ts.map +1 -1
- package/@types/types/mcdev.d.d.ts +34 -0
- package/@types/types/mcdev.d.d.ts.map +1 -1
- package/boilerplate/config.json +11 -0
- package/boilerplate/files/eslint.config.js +98 -3
- package/boilerplate/forcedUpdates.json +4 -0
- package/boilerplate/gitignore-template +1 -1
- package/boilerplate/npm-dependencies.json +1 -0
- package/eslint.config.js +4 -3
- package/lib/Builder.js +114 -54
- package/lib/Deployer.js +2 -2
- package/lib/MetadataTypeDefinitions.js +2 -0
- package/lib/MetadataTypeInfo.js +2 -0
- package/lib/cli.js +127 -3
- package/lib/index.js +217 -164
- package/lib/metadataTypes/Asset.js +76 -22
- package/lib/metadataTypes/DataExtension.js +10 -2
- package/lib/metadataTypes/DomainVerification.js +246 -0
- package/lib/metadataTypes/Event.js +21 -9
- package/lib/metadataTypes/Journey.js +339 -223
- package/lib/metadataTypes/MetadataType.js +153 -106
- package/lib/metadataTypes/MobileKeyword.js +5 -2
- package/lib/metadataTypes/MobileMessage.js +5 -2
- package/lib/metadataTypes/SendClassification.js +5 -0
- package/lib/metadataTypes/SenderProfile.js +102 -3
- package/lib/metadataTypes/TransactionalEmail.js +3 -1
- package/lib/metadataTypes/Verification.js +3 -1
- package/lib/metadataTypes/definitions/DomainVerification.definition.js +71 -0
- package/lib/metadataTypes/definitions/Journey.definition.js +7 -1
- package/lib/metadataTypes/definitions/SendClassification.definition.js +2 -2
- package/lib/metadataTypes/definitions/SenderProfile.definition.js +1 -1
- package/lib/util/config.js +6 -0
- package/lib/util/devops.js +130 -154
- package/lib/util/file.js +3 -3
- package/lib/util/replaceContentBlockReference.js +10 -3
- package/lib/util/util.js +96 -14
- package/lib/util/validations.js +34 -14
- package/package.json +10 -10
- package/test/general.test.js +339 -96
- package/test/mockRoot/.mcdev-validations.js +66 -0
- package/test/mockRoot/.mcdevrc.json +30 -2
- package/test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_htmlblock.asset-block-meta.html +1 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_htmlblock.asset-block-meta.json +39 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_withCBBK_notexisting.asset-block-meta.html +4 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_withCBBK_notexisting.asset-block-meta.json +39 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_withCBBK_preexisting.asset-block-meta.html +4 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/block/testNew_asset_withCBBK_preexisting.asset-block-meta.json +39 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/message/testNew_assetMessage/testNew_assetMessage.asset-message-meta.json +435 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/message/testNew_assetMessage/views.html.content.asset-message-meta.html +150 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/message/testNew_asset_templatebasedemail/testNew_asset_templatebasedemail.asset-message-meta.json +305 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/message/testNew_asset_templatebasedemail/views.html.content.asset-message-meta.html +150 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/template/testNew_asset_template/content.asset-template-meta.html +150 -0
- package/test/mockRoot/deploy/testInstance/testBU/asset/template/testNew_asset_template/testNew_asset_template.asset-template-meta.json +116 -0
- package/test/mockRoot/deploy/testInstance/testBU/domainVerification/joern.berkefeld.New@accenture.com.domainVerification-meta.json +6 -0
- package/test/mockRoot/deploy/testInstance/testBU/domainVerification/joern.berkefeld@accenture.com.domainVerification-meta.json +6 -0
- package/test/mockRoot/deploy/testInstance/testBU/domainVerification/mcdev.accenture.com.domainVerification-meta.json +6 -0
- package/test/mockRoot/deploy/testInstance/testBU/journey/testNew_temail_notPublished.journey-meta.json +213 -0
- package/test/mockRoot/deploy/testInstance/testBU/senderProfile/testExisting_senderProfile.senderProfile-meta.json +1 -0
- package/test/mockRoot/deploy/testInstance/testBU/senderProfile/testNew_senderProfile.senderProfile-meta.json +1 -0
- package/test/resourceFactory.js +7 -24
- package/test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_assetMessage.json +441 -0
- package/test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_asset_htmlblock.json +59 -0
- package/test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_asset_template.json +147 -0
- package/test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_asset_templatebasedemail.json +322 -0
- package/test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_asset_withCBBK_notexisting.json +59 -0
- package/test/resources/9999999/asset/v1/content/assets/post-response-key=testNew_asset_withCBBK_preexisting.json +59 -0
- package/test/resources/9999999/asset-deploy2/block/testBlacklist_asset_htmlblock.asset-block-meta.html +1 -0
- package/test/resources/9999999/asset-deploy2/block/testBlacklist_asset_htmlblock.asset-block-meta.json +39 -0
- package/test/resources/9999999/automation/clone-expected.json +61 -0
- package/test/resources/9999999/dataExtension/retrieve-CustomerKey=testExisting_dataExtension-response.xml +52 -0
- package/test/resources/9999999/dataExtension-deploy/testBlacklist_dataExtension.dataExtension-meta.json +20 -0
- package/test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared,dataextension,hidden,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml +137 -0
- package/test/resources/9999999/domainVerification/create-expected.json +3 -0
- package/test/resources/9999999/domainVerification/get-sap-expected.json +6 -0
- package/test/resources/9999999/domainVerification/update-expected.json +6 -0
- package/test/resources/9999999/interaction/v1/interactions/key_testExisting_temail/put-response-paused.json +219 -0
- package/test/resources/9999999/interaction/v1/interactions/key_testNew_temail_notPublished/get-response.json +218 -0
- package/test/resources/9999999/interaction/v1/interactions/post-response.json +216 -0
- package/test/resources/9999999/journey/create-transactionaEmail-publish-expected.json +217 -0
- package/test/resources/9999999/messaging/v1/domainverification/delete/post-response.txt +1 -0
- package/test/resources/9999999/messaging/v1/domainverification/get-response.json +43 -0
- package/test/resources/9999999/messaging/v1/domainverification/post-response.txt +1 -0
- package/test/resources/9999999/messaging/v1/domainverification/update/post-response.txt +1 -0
- package/test/resources/9999999/messaging/v1/email/definitions/get-response.json +7 -0
- package/test/resources/9999999/messaging/v1/email/definitions/testNew_temail_notPublished/get-response.json +26 -0
- package/test/resources/9999999/query/clone-expected.json +8 -0
- package/test/resources/9999999/query/clone-expected.sql +7 -0
- package/test/resources/9999999/senderProfile/create-response.xml +1 -1
- package/test/resources/9999999/senderProfile/post-expected.json +1 -1
- package/test/resources/9999999/transactionalEmail/create-publish-expected.json +20 -0
- package/test/type.asset.test.js +216 -9
- package/test/type.automation.test.js +1 -1
- package/test/type.domainVerification.test.js +169 -0
- package/test/type.journey.test.js +107 -21
- package/test/type.script.test.js +1 -1
- package/test/type.sendClassification.test.js +3 -3
- package/test/type.senderProfile.test.js +26 -6
- package/test/type.transactionalEmail.test.js +5 -5
- package/test/type.triggeredSend.test.js +1 -1
- package/test/utils.js +8 -0
- package/types/mcdev.d.js +12 -0
|
@@ -188,13 +188,13 @@ class Asset extends MetadataType {
|
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
/**
|
|
191
|
-
* Returns Order in which metadata needs to be retrieved/deployed
|
|
191
|
+
* Returns Order in which metadata needs to be retrieved/deployed and skips components with missing components
|
|
192
192
|
*
|
|
193
|
-
* @param {AssetMap} metadataMap metadata
|
|
193
|
+
* @param {AssetMap} metadataMap metadata thats about to be deployed
|
|
194
194
|
* @param {string} deployDir directory where deploy metadata are saved
|
|
195
195
|
* @returns {Promise.<AssetMap>} keyField => metadata map but sorted to ensure dependencies are deployed in correct order
|
|
196
196
|
*/
|
|
197
|
-
static async
|
|
197
|
+
static async _getUpsertOrderAndSkipMissing(metadataMap, deployDir) {
|
|
198
198
|
/**
|
|
199
199
|
* one entry for each dependency with the first item being the key thats required by the second item
|
|
200
200
|
*
|
|
@@ -207,29 +207,44 @@ class Asset extends MetadataType {
|
|
|
207
207
|
Util.OPTIONS.referenceTo = 'key';
|
|
208
208
|
// loop through all metadata types which are being retrieved/deployed
|
|
209
209
|
for (const key in metadataMap) {
|
|
210
|
+
const errors = [];
|
|
210
211
|
const findAssetKeys = new Set();
|
|
212
|
+
// find asset references in metadata
|
|
213
|
+
const findAssetKeyMeta = Util.findLeafVals(metadataMap[key], 'r__asset_key');
|
|
214
|
+
for (const metaKey of findAssetKeyMeta) {
|
|
215
|
+
if (metadataMap[key] || cache.getByKey(this.definition.type, metaKey)) {
|
|
216
|
+
findAssetKeys.add(metaKey);
|
|
217
|
+
} else {
|
|
218
|
+
errors.push(
|
|
219
|
+
`content block ${metaKey} that is referenced via r__asset_key was not found on BU nor in deployment package`
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
211
223
|
try {
|
|
212
224
|
// find asset references in code
|
|
213
225
|
await this.replaceCbReference(metadataMap[key], deployDir, findAssetKeys);
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
226
|
+
} catch (ex) {
|
|
227
|
+
if (ex.code === 200) {
|
|
228
|
+
// no dependent keys found
|
|
229
|
+
// good from this perspective
|
|
230
|
+
} else {
|
|
231
|
+
errors.push(
|
|
232
|
+
`content block ${ex.message} that is referenced via ContentBlockByX was not found on BU nor in deployment package`
|
|
233
|
+
);
|
|
218
234
|
}
|
|
219
|
-
|
|
235
|
+
}
|
|
236
|
+
if (errors.length) {
|
|
237
|
+
Util.logger.error(
|
|
238
|
+
` ☇ skipping ${this.definition.type} ${key}:${errors.length > 1 ? '\n ·' : ''} ${errors.join('\n · ')}`
|
|
239
|
+
);
|
|
240
|
+
} else {
|
|
220
241
|
const dependentKeys = [...findAssetKeys];
|
|
221
242
|
if (dependentKeys.length > 0) {
|
|
222
243
|
dependencies.push(...dependentKeys.map((depKey) => [depKey, key]));
|
|
223
244
|
} else {
|
|
224
|
-
Util.logger.debug('Asset._getUpsertOrder:
|
|
245
|
+
Util.logger.debug('Asset._getUpsertOrder: no dependent keys found for ' + key);
|
|
225
246
|
dependencies.push([undefined, key]);
|
|
226
247
|
}
|
|
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
248
|
}
|
|
234
249
|
}
|
|
235
250
|
|
|
@@ -240,7 +255,9 @@ class Asset extends MetadataType {
|
|
|
240
255
|
const metadataTypeMapSorted = {};
|
|
241
256
|
// group subtypes per type
|
|
242
257
|
for (const key of flatList) {
|
|
243
|
-
|
|
258
|
+
if (metadataMap[key]) {
|
|
259
|
+
metadataTypeMapSorted[key] = metadataMap[key];
|
|
260
|
+
}
|
|
244
261
|
}
|
|
245
262
|
return metadataTypeMapSorted;
|
|
246
263
|
}
|
|
@@ -253,12 +270,13 @@ class Asset extends MetadataType {
|
|
|
253
270
|
* @returns {Promise.<AssetMap>} keyField => metadata map
|
|
254
271
|
*/
|
|
255
272
|
static async upsert(metadataMap, deployDir) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
273
|
+
// add already existing, cached items to our cache map to ensure we can find them
|
|
274
|
+
ReplaceCbReference.createCacheForMap(cache.getCache().asset);
|
|
275
|
+
// await ReplaceCbReference.createCache(this.properties, this.buObject, true);
|
|
276
|
+
// fill the cache map with our deployment package to ensure we can find
|
|
277
|
+
ReplaceCbReference.createCacheForMap(metadataMap);
|
|
278
|
+
// 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
|
|
279
|
+
metadataMap = await this._getUpsertOrderAndSkipMissing(metadataMap, deployDir);
|
|
262
280
|
return super.upsert(metadataMap, deployDir, true);
|
|
263
281
|
}
|
|
264
282
|
|
|
@@ -274,6 +292,32 @@ class Asset extends MetadataType {
|
|
|
274
292
|
return super.createREST(metadata, uri);
|
|
275
293
|
}
|
|
276
294
|
|
|
295
|
+
/**
|
|
296
|
+
* helper for {@link MetadataType.createREST}
|
|
297
|
+
*
|
|
298
|
+
* @param {MetadataTypeItem} metadataEntry a single metadata Entry
|
|
299
|
+
* @param {object} apiResponse varies depending on the API call
|
|
300
|
+
* @returns {Promise.<object>} apiResponse, potentially modified
|
|
301
|
+
*/
|
|
302
|
+
static async postCreateTasks(metadataEntry, apiResponse) {
|
|
303
|
+
if (apiResponse[this.definition.idField]) {
|
|
304
|
+
// this also happens inside of MetadataType.upsert but we need it for createCacheMap()
|
|
305
|
+
// ensure we have the ID in the cache
|
|
306
|
+
metadataEntry[this.definition.idField] = apiResponse[this.definition.idField];
|
|
307
|
+
}
|
|
308
|
+
if (apiResponse.objectID) {
|
|
309
|
+
// ensure we have the asset objectId in the cache
|
|
310
|
+
metadataEntry.objectID = apiResponse.objectID;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// make this newly created item available in cache for other itmes that might reference it
|
|
314
|
+
/** @type {MetadataTypeMap} */
|
|
315
|
+
const newObject = {};
|
|
316
|
+
newObject[metadataEntry[this.definition.keyField]] = metadataEntry;
|
|
317
|
+
ReplaceCbReference.createCacheForMap(newObject);
|
|
318
|
+
return apiResponse;
|
|
319
|
+
}
|
|
320
|
+
|
|
277
321
|
/**
|
|
278
322
|
* Updates a single asset
|
|
279
323
|
*
|
|
@@ -799,6 +843,16 @@ class Asset extends MetadataType {
|
|
|
799
843
|
// folder
|
|
800
844
|
this.setFolderId(metadata);
|
|
801
845
|
|
|
846
|
+
if (
|
|
847
|
+
metadata.assetType.name === 'webpage' &&
|
|
848
|
+
!cache.getByKey(this.definition.type, metadata[this.definition.keyField])
|
|
849
|
+
) {
|
|
850
|
+
// we are attempting to CREATE a cloudpage asset which needs to be prevented.
|
|
851
|
+
throw new Error(
|
|
852
|
+
'CloudPages cannot be created via mcdev. Please create it via the UI first, then change its key to the value required by you, and finally, re-run this deployment.'
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
|
|
802
856
|
// template-based emails
|
|
803
857
|
if (
|
|
804
858
|
metadata.assetType.name === 'templatebasedemail' &&
|
|
@@ -53,7 +53,15 @@ class DataExtension extends MetadataType {
|
|
|
53
53
|
let filteredByPreDeploy = 0;
|
|
54
54
|
for (const metadataKey in metadataMap) {
|
|
55
55
|
try {
|
|
56
|
-
await this.validation(
|
|
56
|
+
metadataMap[metadataKey] = await this.validation(
|
|
57
|
+
'deploy',
|
|
58
|
+
metadataMap[metadataKey],
|
|
59
|
+
deployDir
|
|
60
|
+
);
|
|
61
|
+
if (!metadataMap[metadataKey]) {
|
|
62
|
+
filteredByPreDeploy++;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
57
65
|
metadataMap[metadataKey] = await this.preDeployTasks(metadataMap[metadataKey]);
|
|
58
66
|
|
|
59
67
|
await this.createOrUpdate(
|
|
@@ -394,7 +402,7 @@ class DataExtension extends MetadataType {
|
|
|
394
402
|
}
|
|
395
403
|
|
|
396
404
|
// find all shared data extensions
|
|
397
|
-
if (!this.deployedSharedKeys
|
|
405
|
+
if (!this.deployedSharedKeys?.length) {
|
|
398
406
|
Util.logger.debug(
|
|
399
407
|
`Skipping fixShared logic because no Shared Data Extensions were updated`
|
|
400
408
|
);
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import MetadataType from './MetadataType.js';
|
|
4
|
+
import { Util } from '../util/util.js';
|
|
5
|
+
import cache from '../util/cache.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import('../../types/mcdev.d.js').BuObject} BuObject
|
|
9
|
+
* @typedef {import('../../types/mcdev.d.js').CodeExtract} CodeExtract
|
|
10
|
+
* @typedef {import('../../types/mcdev.d.js').CodeExtractItem} CodeExtractItem
|
|
11
|
+
* @typedef {import('../../types/mcdev.d.js').MetadataTypeItem} MetadataTypeItem
|
|
12
|
+
* @typedef {import('../../types/mcdev.d.js').MetadataTypeItemDiff} MetadataTypeItemDiff
|
|
13
|
+
* @typedef {import('../../types/mcdev.d.js').MetadataTypeItemObj} MetadataTypeItemObj
|
|
14
|
+
* @typedef {import('../../types/mcdev.d.js').MetadataTypeMap} MetadataTypeMap
|
|
15
|
+
* @typedef {import('../../types/mcdev.d.js').MetadataTypeMapObj} MetadataTypeMapObj
|
|
16
|
+
* @typedef {import('../../types/mcdev.d.js').SoapRequestParams} SoapRequestParams
|
|
17
|
+
* @typedef {import('../../types/mcdev.d.js').TemplateMap} TemplateMap
|
|
18
|
+
* @typedef {import('../../types/mcdev.d.js').DomainVerificationItem} DomainVerificationItem
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* DomainVerification MetadataType
|
|
23
|
+
*
|
|
24
|
+
* @augments MetadataType
|
|
25
|
+
*/
|
|
26
|
+
class DomainVerification extends MetadataType {
|
|
27
|
+
/**
|
|
28
|
+
* Retrieves Metadata ofDomainVerification.
|
|
29
|
+
* Endpoint /automation/v1/dataextracts/ returns all items
|
|
30
|
+
*
|
|
31
|
+
* @param {string} retrieveDir Directory where retrieved metadata directory will be saved
|
|
32
|
+
* @param {void | string[]} [_] unused parameter
|
|
33
|
+
* @param {void | string[]} [__] unused parameter
|
|
34
|
+
* @param {string} [key] customer key of single item to retrieve
|
|
35
|
+
* @returns {Promise.<MetadataTypeMapObj>} Promise of metadata
|
|
36
|
+
*/
|
|
37
|
+
static async retrieve(retrieveDir, _, __, key) {
|
|
38
|
+
return super.retrieveREST(retrieveDir, '/messaging/v1/domainverification/', null, key);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Retrieves Metadata of DomainVerification for caching
|
|
43
|
+
*
|
|
44
|
+
* @returns {Promise.<MetadataTypeMapObj>} Promise of metadata
|
|
45
|
+
*/
|
|
46
|
+
static async retrieveForCache() {
|
|
47
|
+
return super.retrieveREST(null, '/messaging/v1/domainverification/');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Creates a single item
|
|
52
|
+
*
|
|
53
|
+
* @param {DomainVerificationItem} metadataItem a single item
|
|
54
|
+
* @returns {Promise} Promise
|
|
55
|
+
*/
|
|
56
|
+
static create(metadataItem) {
|
|
57
|
+
return super.createREST(metadataItem, '/messaging/v1/domainverification/');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* helper for {@link MetadataType.createREST}
|
|
62
|
+
*
|
|
63
|
+
* @param {DomainVerificationItem} metadataEntry a single metadata Entry
|
|
64
|
+
* @param {object} apiResponse varies depending on the API call
|
|
65
|
+
* @returns {Promise.<DomainVerificationItem>} apiResponse
|
|
66
|
+
*/
|
|
67
|
+
static async postCreateTasks(metadataEntry, apiResponse) {
|
|
68
|
+
if (apiResponse && apiResponse === `${metadataEntry.domain} successfully added.`) {
|
|
69
|
+
return metadataEntry;
|
|
70
|
+
} else {
|
|
71
|
+
throw new Error(apiResponse);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* helper for {@link update}
|
|
77
|
+
*
|
|
78
|
+
* @param {DomainVerificationItem} metadataEntry a single metadata Entry
|
|
79
|
+
* @param {object} apiResponse varies depending on the API call
|
|
80
|
+
* @returns {Promise.<DomainVerificationItem>} apiResponse, potentially modified
|
|
81
|
+
*/
|
|
82
|
+
static async postUpdateTasks(metadataEntry, apiResponse) {
|
|
83
|
+
if (apiResponse && apiResponse === `1 records successfully updated!`) {
|
|
84
|
+
metadataEntry.domain = metadataEntry.emailAddress;
|
|
85
|
+
return metadataEntry;
|
|
86
|
+
} else {
|
|
87
|
+
throw new Error(apiResponse);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Updates a single item; replaces super.updateREST because we need to send metadataItem as an array for some reason and also get an array back
|
|
93
|
+
*
|
|
94
|
+
* @param {DomainVerificationItem} metadataItem a single item
|
|
95
|
+
* @returns {Promise.<DomainVerificationItem>} Promise
|
|
96
|
+
*/
|
|
97
|
+
static async update(metadataItem) {
|
|
98
|
+
const uri = '/messaging/v1/domainverification/update';
|
|
99
|
+
|
|
100
|
+
this.removeNotUpdateableFields(metadataItem);
|
|
101
|
+
try {
|
|
102
|
+
// set to empty object in case API returned nothing to be able to update it in helper classes
|
|
103
|
+
let response = (await this.client.rest.post(uri, [metadataItem])) || {};
|
|
104
|
+
this.getErrorsREST(response);
|
|
105
|
+
response = await this.postUpdateTasks(metadataItem, response);
|
|
106
|
+
// some times, e.g. automation dont return a key in their update response and hence we need to fall back to name
|
|
107
|
+
Util.logger.info(` - updated ${Util.getTypeKeyName(this.definition, metadataItem)}`);
|
|
108
|
+
return metadataItem;
|
|
109
|
+
} catch (ex) {
|
|
110
|
+
const parsedErrors = this.getErrorsREST(ex);
|
|
111
|
+
Util.logger.error(
|
|
112
|
+
` ☇ error updating ${Util.getTypeKeyName(this.definition, metadataItem)}:`
|
|
113
|
+
);
|
|
114
|
+
for (const msg of parsedErrors) {
|
|
115
|
+
Util.logger.error(' • ' + msg);
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* manages post retrieve steps
|
|
122
|
+
*
|
|
123
|
+
* @param {DomainVerificationItem} metadataItem a single item
|
|
124
|
+
* @returns {DomainVerificationItem} metadata
|
|
125
|
+
*/
|
|
126
|
+
static postRetrieveTasks(metadataItem) {
|
|
127
|
+
if (metadataItem.status !== 'Verified') {
|
|
128
|
+
Util.logger.warn(
|
|
129
|
+
Util.getMsgPrefix(this.definition, metadataItem) +
|
|
130
|
+
` is not verified. Current status: ${metadataItem.status}`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
if (!metadataItem.isSendable) {
|
|
134
|
+
Util.logger.warn(
|
|
135
|
+
Util.getMsgPrefix(this.definition, metadataItem) + ` is not sendable.`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
return metadataItem;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Gets executed after deployment of metadata type
|
|
143
|
+
*
|
|
144
|
+
* @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create
|
|
145
|
+
* @returns {Promise.<void>} -
|
|
146
|
+
*/
|
|
147
|
+
static async postDeployTasks(upsertResults) {
|
|
148
|
+
// re-retrieve all upserted items to ensure we have all fields (createdDate and modifiedDate are otherwise not present)
|
|
149
|
+
Util.logger.debug(
|
|
150
|
+
`Caching all ${this.definition.type} post-deploy to ensure we have all fields`
|
|
151
|
+
);
|
|
152
|
+
const typeCache = await this.retrieveForCache();
|
|
153
|
+
// update values in upsertResults with retrieved values before saving to disk
|
|
154
|
+
for (const key of Object.keys(upsertResults)) {
|
|
155
|
+
if (typeCache.metadata[key]) {
|
|
156
|
+
upsertResults[key] = typeCache.metadata[key];
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* prepares a single item for deployment
|
|
163
|
+
*
|
|
164
|
+
* @param {DomainVerificationItem} metadata a single item
|
|
165
|
+
* @returns {Promise.<DomainVerificationItem>} Promise
|
|
166
|
+
*/
|
|
167
|
+
static async preDeployTasks(metadata) {
|
|
168
|
+
if (metadata.domainType && metadata.domainType !== 'UserDomain') {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`Can only delete entries of type 'UserDomain'. Found: ${metadata.domainType}`
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
// prep for update which uses emailAddress instead of domain
|
|
174
|
+
metadata.emailAddress = metadata.domain;
|
|
175
|
+
|
|
176
|
+
return metadata;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Gets executed before deleting a list of keys for the current type
|
|
181
|
+
*
|
|
182
|
+
* @returns {Promise.<void>} -
|
|
183
|
+
*/
|
|
184
|
+
static async preDeleteTasks() {
|
|
185
|
+
if (!cache.getCache()) {
|
|
186
|
+
cache.initCache(this.buObject);
|
|
187
|
+
}
|
|
188
|
+
if (!cache.getCache()?.[this.definition.type]) {
|
|
189
|
+
const cached = await this.retrieveForCache();
|
|
190
|
+
if (cached) {
|
|
191
|
+
cache.setMetadata(this.definition.type, cached?.metadata);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Delete a metadata item from the specified business unit
|
|
198
|
+
*
|
|
199
|
+
* @param {string} key Identifier of data extension
|
|
200
|
+
* @returns {Promise.<boolean>} deletion success flag
|
|
201
|
+
*/
|
|
202
|
+
static async deleteByKey(key) {
|
|
203
|
+
const metadataItem = cache.getByKey(this.definition.type, key);
|
|
204
|
+
if (!metadataItem) {
|
|
205
|
+
Util.logger.error(` - ${this.definition.type} ${key} not found`);
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
if (metadataItem.domainType !== 'UserDomain') {
|
|
209
|
+
Util.logger.error(
|
|
210
|
+
` - ${this.definition.type} ${key}: Can only delete entries of type UserDomain. Found: ${metadataItem.domainType}`
|
|
211
|
+
);
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
const response = await this.client.rest.post(
|
|
216
|
+
'/messaging/v1/domainverification/delete',
|
|
217
|
+
[
|
|
218
|
+
{
|
|
219
|
+
emailAddress: metadataItem.domain,
|
|
220
|
+
domainType: metadataItem.domainType,
|
|
221
|
+
},
|
|
222
|
+
]
|
|
223
|
+
);
|
|
224
|
+
if (response === '1 records successfully updated!') {
|
|
225
|
+
Util.logger.info(` - deleted ${this.definition.type}: ${key}`);
|
|
226
|
+
this.postDeleteTasks(key);
|
|
227
|
+
return true;
|
|
228
|
+
} else {
|
|
229
|
+
Util.logger.error(
|
|
230
|
+
` - Deleting ${this.definition.type} '${key}' failed: ` + response
|
|
231
|
+
);
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
} catch (ex) {
|
|
235
|
+
Util.logger.errorStack(ex, ` - Deleting ${this.definition.type} '${key}' failed`);
|
|
236
|
+
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Assign definition to static attributes
|
|
243
|
+
import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
|
|
244
|
+
DomainVerification.definition = MetadataTypeDefinitions.domainVerification;
|
|
245
|
+
|
|
246
|
+
export default DomainVerification;
|
|
@@ -46,7 +46,6 @@ class Event extends MetadataType {
|
|
|
46
46
|
* @returns {Promise.<MetadataTypeMapObj>} Promise of metadata
|
|
47
47
|
*/
|
|
48
48
|
static async retrieve(retrieveDir, _, __, key) {
|
|
49
|
-
Util.logBeta(this.definition.type);
|
|
50
49
|
try {
|
|
51
50
|
return await super.retrieveREST(
|
|
52
51
|
retrieveDir,
|
|
@@ -87,7 +86,6 @@ class Event extends MetadataType {
|
|
|
87
86
|
* @returns {Promise.<MetadataTypeItemObj>} Promise of metadata
|
|
88
87
|
*/
|
|
89
88
|
static async retrieveAsTemplate(templateDir, name, templateVariables) {
|
|
90
|
-
Util.logBeta(this.definition.type);
|
|
91
89
|
const res = await this.client.rest.get(
|
|
92
90
|
'/interaction/v1/eventDefinitions?name=' + encodeURIComponent(name)
|
|
93
91
|
);
|
|
@@ -141,13 +139,27 @@ class Event extends MetadataType {
|
|
|
141
139
|
* @param {string} key Identifier of item
|
|
142
140
|
* @returns {Promise.<boolean>} deletion success status
|
|
143
141
|
*/
|
|
144
|
-
static deleteByKey(key) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
142
|
+
static async deleteByKey(key) {
|
|
143
|
+
let response = false;
|
|
144
|
+
try {
|
|
145
|
+
response = await super.deleteByKeyREST(
|
|
146
|
+
'/interaction/v1/eventDefinitions/key:' + encodeURIComponent(key),
|
|
147
|
+
key,
|
|
148
|
+
true
|
|
149
|
+
);
|
|
150
|
+
Util.logger.info(` - deleted ${this.definition.type}: ${key}`);
|
|
151
|
+
} catch (ex) {
|
|
152
|
+
if (ex.code === 30000) {
|
|
153
|
+
Util.logger.warn(
|
|
154
|
+
` ☇ skipping deletion of ${this.definition.type} ${key}: not found on server`
|
|
155
|
+
);
|
|
156
|
+
} else {
|
|
157
|
+
Util.logger.errorStack(ex, ` - Deleting ${this.definition.type} '${key}' failed`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
return response;
|
|
151
163
|
}
|
|
152
164
|
|
|
153
165
|
/**
|