mcdev 7.1.4 → 7.2.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/.fork/custom-commands.json +123 -21
- package/.github/ISSUE_TEMPLATE/bug.yml +1 -0
- package/.github/dependabot.yml +1 -0
- package/.husky/post-checkout +6 -1
- package/.husky/post-merge +5 -0
- package/@types/lib/metadataTypes/Journey.d.ts +0 -1
- package/@types/lib/metadataTypes/Journey.d.ts.map +1 -1
- package/@types/lib/metadataTypes/TransactionalEmail.d.ts.map +1 -1
- package/@types/lib/metadataTypes/definitions/Journey.definition.d.ts +0 -1
- package/@types/lib/util/file.d.ts.map +1 -1
- package/lib/metadataTypes/Journey.js +280 -141
- package/lib/metadataTypes/TransactionalEmail.js +20 -3
- package/lib/metadataTypes/definitions/Journey.definition.js +0 -1
- package/lib/util/file.js +53 -49
- package/package.json +12 -12
- package/test/general.test.js +13 -13
- package/test/mockRoot/.mcdevrc.json +1 -1
- package/test/resourceFactory.js +12 -3
- package/test/resources/9999999/dataExtension/retrieve-response.xml +29 -0
- package/test/resources/9999999/interaction/v1/interactions/get-response.json +38 -0
- package/test/resources/9999999/interaction/v1/interactions/key_testExisting_temail_notPublished/get-response.json +226 -0
- package/test/resources/9999999/interaction/v1/interactions/transactional/create/post-response.json +3 -0
- package/test/resources/9999999/messaging/v1/email/definitions/get-response.json +7 -0
- package/test/resources/9999999/messaging/v1/email/definitions/testExisting_temail_notPublished/get-response.json +26 -0
- package/test/type.automation.test.js +1 -1
- package/test/type.dataExtension.test.js +4 -4
- package/test/type.journey.test.js +84 -21
- package/test/type.transactionalEmail.test.js +7 -7
|
@@ -6,6 +6,7 @@ import { Util } from '../util/util.js';
|
|
|
6
6
|
import cache from '../util/cache.js';
|
|
7
7
|
import File from '../util/file.js';
|
|
8
8
|
import ReplaceCbReference from '../util/replaceContentBlockReference.js';
|
|
9
|
+
import Retriever from '../Retriever.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* @typedef {import('../../types/mcdev.d.js').BuObject} BuObject
|
|
@@ -427,50 +428,60 @@ class Journey extends MetadataType {
|
|
|
427
428
|
// ! transactional (email) journeys only have one activity (type=EMAILV2) which links back to the transactionalEmail ()
|
|
428
429
|
switch (metadata.channel) {
|
|
429
430
|
case 'email': {
|
|
430
|
-
if (
|
|
431
|
-
metadata.activities?.length > 0 &&
|
|
432
|
-
metadata.activities[0].configurationArguments?.triggeredSendKey
|
|
433
|
-
) {
|
|
431
|
+
if (metadata.activities?.length > 0) {
|
|
434
432
|
const activity = metadata.activities[0];
|
|
435
433
|
// trigger found; there can only be one entry in this array
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
tEmailKey != activity.configurationArguments?.triggeredSendKey
|
|
445
|
-
) {
|
|
446
|
-
throw new Error(
|
|
447
|
-
` - ${this.definition.type} ${
|
|
448
|
-
metadata[this.definition.nameField]
|
|
449
|
-
} (${
|
|
450
|
-
metadata[this.definition.keyField]
|
|
451
|
-
}): transactionalEmailId not matching Id found on transactionalEmail with key in transactionalEmailKey`
|
|
434
|
+
|
|
435
|
+
if (activity.configurationArguments?.triggeredSendId) {
|
|
436
|
+
try {
|
|
437
|
+
const tEmailKey = cache.searchForField(
|
|
438
|
+
'transactionalEmail',
|
|
439
|
+
activity.configurationArguments?.triggeredSendId,
|
|
440
|
+
'definitionId',
|
|
441
|
+
'definitionKey'
|
|
452
442
|
);
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
443
|
+
if (
|
|
444
|
+
activity.configurationArguments?.triggeredSendKey &&
|
|
445
|
+
tEmailKey !=
|
|
446
|
+
activity.configurationArguments?.triggeredSendKey
|
|
447
|
+
) {
|
|
448
|
+
Util.logger.debug(
|
|
449
|
+
`triggeredSendKey not matching triggeredSendId. Overwriting '${activity.configurationArguments.triggeredSendKey}' with the correct key '${tEmailKey}'.`
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
activity.configurationArguments.r__transactionalEmail_key =
|
|
453
|
+
activity.configurationArguments.triggeredSendKey;
|
|
454
|
+
delete activity.configurationArguments.triggeredSendKey;
|
|
455
|
+
delete activity.configurationArguments.triggeredSendId;
|
|
456
|
+
} catch (ex) {
|
|
457
|
+
Util.logger.warn(
|
|
460
458
|
` - ${this.definition.type} ${
|
|
461
459
|
metadata[this.definition.nameField]
|
|
462
|
-
} (${
|
|
463
|
-
metadata[this.definition.keyField]
|
|
464
|
-
}): metaData.highThroughput.definitionKey not matching key in configurationArguments.transactionalEmailKey`
|
|
460
|
+
} (${metadata[this.definition.keyField]}): ${ex.message}.`
|
|
465
461
|
);
|
|
466
462
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
463
|
+
}
|
|
464
|
+
if (
|
|
465
|
+
activity.metaData?.highThroughput?.definitionKey &&
|
|
466
|
+
activity.configurationArguments?.r__transactionalEmail_key &&
|
|
467
|
+
activity.metaData?.highThroughput?.definitionKey !=
|
|
468
|
+
activity.configurationArguments.r__transactionalEmail_key
|
|
469
|
+
) {
|
|
470
|
+
Util.logger.warn(
|
|
471
|
+
` - ${this.definition.type} ${
|
|
472
|
+
metadata[this.definition.nameField]
|
|
473
|
+
} (${metadata[this.definition.keyField]}): activities[0].metaData.highThroughput.definitionKey not matching key in activities[0].configurationArguments.r__transactionalEmail_key.`
|
|
474
|
+
);
|
|
475
|
+
} else if (
|
|
476
|
+
activity.configurationArguments?.r__transactionalEmail_key &&
|
|
477
|
+
metadata.status === 'Published'
|
|
478
|
+
) {
|
|
479
|
+
// as long as status is Draft, we wont have r__transactionalEmail_key set as that record will not have been created
|
|
471
480
|
delete activity.metaData.highThroughput.definitionKey;
|
|
481
|
+
}
|
|
472
482
|
|
|
473
|
-
|
|
483
|
+
if (activity.metaData?.highThroughput?.dataExtensionId) {
|
|
484
|
+
try {
|
|
474
485
|
activity.metaData.highThroughput.r__dataExtension_key =
|
|
475
486
|
cache.searchForField(
|
|
476
487
|
'dataExtension',
|
|
@@ -479,13 +490,13 @@ class Journey extends MetadataType {
|
|
|
479
490
|
'CustomerKey'
|
|
480
491
|
);
|
|
481
492
|
delete activity.metaData.highThroughput.dataExtensionId;
|
|
493
|
+
} catch (ex) {
|
|
494
|
+
Util.logger.warn(
|
|
495
|
+
` - ${this.definition.type} ${
|
|
496
|
+
metadata[this.definition.nameField]
|
|
497
|
+
} (${metadata[this.definition.keyField]}): ${ex.message}.`
|
|
498
|
+
);
|
|
482
499
|
}
|
|
483
|
-
} catch (ex) {
|
|
484
|
-
Util.logger.warn(
|
|
485
|
-
` - ${this.definition.type} ${
|
|
486
|
-
metadata[this.definition.nameField]
|
|
487
|
-
} (${metadata[this.definition.keyField]}): ${ex.message}.`
|
|
488
|
-
);
|
|
489
500
|
}
|
|
490
501
|
}
|
|
491
502
|
// ~~~ ACTIVITIES ~~~~
|
|
@@ -1032,15 +1043,32 @@ class Journey extends MetadataType {
|
|
|
1032
1043
|
const activity = metadata.activities[0];
|
|
1033
1044
|
if (activity.configurationArguments?.r__transactionalEmail_key) {
|
|
1034
1045
|
// trigger found; there can only be one entry in this array
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1046
|
+
try {
|
|
1047
|
+
activity.configurationArguments.triggeredSendId =
|
|
1048
|
+
cache.searchForField(
|
|
1049
|
+
'transactionalEmail',
|
|
1050
|
+
activity.configurationArguments.r__transactionalEmail_key,
|
|
1051
|
+
'definitionKey',
|
|
1052
|
+
'definitionId'
|
|
1053
|
+
);
|
|
1054
|
+
activity.configurationArguments.triggeredSendKey =
|
|
1055
|
+
activity.configurationArguments.r__transactionalEmail_key;
|
|
1056
|
+
} catch (ex) {
|
|
1057
|
+
const isCreateMode = !cache.getByKey('journey', metadata.key);
|
|
1058
|
+
if (isCreateMode && !Util.OPTIONS.publish) {
|
|
1059
|
+
// no need to add a log entry if the publish-option was provided
|
|
1060
|
+
Util.logger.info(
|
|
1061
|
+
` - ${this.definition.type} ${metadata[this.definition.nameField]} (${
|
|
1062
|
+
metadata[this.definition.keyField]
|
|
1063
|
+
}): To activate this transactional journey (and create the associated transactionalEmail record), please run 'mcdev publish ${this.buObject.credential}/${this.buObject.businessUnit} journey ${metadata.key}' or click on "Activate" in the GUI.`
|
|
1064
|
+
);
|
|
1065
|
+
} else if (!isCreateMode) {
|
|
1066
|
+
// block deployment if we are in update mode
|
|
1067
|
+
throw ex;
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1043
1070
|
if (activity.metaData?.highThroughput) {
|
|
1071
|
+
// this is crucial for pinging the /interaction/v1/interactions/transactional/create endpoint that creates the transactionalEmail
|
|
1044
1072
|
activity.metaData.highThroughput.definitionKey =
|
|
1045
1073
|
activity.configurationArguments.r__transactionalEmail_key;
|
|
1046
1074
|
}
|
|
@@ -1508,113 +1536,224 @@ class Journey extends MetadataType {
|
|
|
1508
1536
|
* @returns {Promise.<string[]>} Returns list of updated keys/ids that were published. Success could only be seen with a delay in the UI because the publish-endpoint is async
|
|
1509
1537
|
*/
|
|
1510
1538
|
static async publish(keyArr) {
|
|
1511
|
-
const
|
|
1539
|
+
const resultsJourney = [];
|
|
1540
|
+
const resultsTransactional = [];
|
|
1512
1541
|
// works only with objectId
|
|
1513
|
-
let objectId;
|
|
1514
|
-
let idFound = false;
|
|
1515
|
-
let versionFound = false;
|
|
1516
1542
|
const statusUrls = [];
|
|
1543
|
+
const executedKeyArr = [];
|
|
1544
|
+
const metadataMap = await this.retrieveForCache();
|
|
1545
|
+
|
|
1517
1546
|
for (let key of keyArr) {
|
|
1547
|
+
let objectId;
|
|
1518
1548
|
let version;
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1549
|
+
let journey;
|
|
1550
|
+
if (!key) {
|
|
1551
|
+
continue;
|
|
1552
|
+
}
|
|
1553
|
+
if (key.startsWith('%23')) {
|
|
1554
|
+
// if the key started with %23 assume an ID was copied from the URL but the user forgot to prefix it with id:
|
|
1555
|
+
// correct the format
|
|
1556
|
+
key = 'id:' + key.slice(3);
|
|
1557
|
+
}
|
|
1558
|
+
if (key.startsWith('id:')) {
|
|
1559
|
+
// ! allow selecting journeys by ID because that's what users see in the URL
|
|
1560
|
+
// remove id
|
|
1561
|
+
objectId = key.slice(3);
|
|
1562
|
+
if (objectId.startsWith('%23')) {
|
|
1563
|
+
// in the journey URL the Id is prefixed with an HTML-encoded "#" which could accidentally be copied by users
|
|
1564
|
+
// despite the slicing above, this still needs testing here because users might have prefixed the ID with id: but did not know to remove the #23
|
|
1565
|
+
objectId = objectId.slice(3);
|
|
1566
|
+
// correct the format to ensure we show sth readable in the "Downloaded" log
|
|
1567
|
+
// objectId = objectId;
|
|
1568
|
+
// update this here to show it in the log
|
|
1569
|
+
key = 'id:' + objectId;
|
|
1524
1570
|
}
|
|
1525
|
-
if (
|
|
1526
|
-
|
|
1527
|
-
//
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
if
|
|
1531
|
-
|
|
1532
|
-
//
|
|
1533
|
-
|
|
1534
|
-
// correct the format to ensure we show sth readable in the "Downloaded" log
|
|
1535
|
-
objectId = 'id:' + objectId;
|
|
1536
|
-
// update this here to show it in the log
|
|
1537
|
-
key = objectId;
|
|
1538
|
-
}
|
|
1539
|
-
if (objectId.includes('/')) {
|
|
1540
|
-
versionFound = true;
|
|
1541
|
-
version = objectId.split('/')[1];
|
|
1542
|
-
// in the journey URL the version is appended after the ID, separated by a forward-slash. Needs to be removed from the ID for caching as we always aim to retrieve the latest version only
|
|
1543
|
-
objectId = objectId.split('/')[0];
|
|
1544
|
-
} else {
|
|
1545
|
-
// if we didn't find a version we need to cache this from the API after all
|
|
1546
|
-
objectId = null;
|
|
1547
|
-
if (key.includes('/')) {
|
|
1548
|
-
// in the journey URL the version is appended after the ID, separated by a forward-slash. Needs to be removed from the key for caching as we always aim to retrieve the latest version only
|
|
1549
|
-
key = key.split('/')[0];
|
|
1550
|
-
}
|
|
1571
|
+
if (objectId.includes('/')) {
|
|
1572
|
+
version = objectId.split('/')[1];
|
|
1573
|
+
// in the journey URL the version is appended after the ID, separated by a forward-slash. Needs to be removed from the ID for caching as we always aim to retrieve the latest version only
|
|
1574
|
+
objectId = objectId.split('/')[0];
|
|
1575
|
+
} else {
|
|
1576
|
+
// if we didn't find a version we need to cache this from the API after all
|
|
1577
|
+
if (key.includes('/')) {
|
|
1578
|
+
// in the journey URL the version is appended after the ID, separated by a forward-slash. Needs to be removed from the key for caching as we always aim to retrieve the latest version only
|
|
1579
|
+
key = key.split('/')[0];
|
|
1551
1580
|
}
|
|
1552
1581
|
}
|
|
1553
|
-
|
|
1582
|
+
journey = Object.values(metadataMap.metadata).find((el) => el.id === objectId);
|
|
1583
|
+
if (!journey) {
|
|
1554
1584
|
Util.logger.info(
|
|
1555
|
-
`
|
|
1585
|
+
` ☇ skipping ${this.definition.type} ${key}: not found on server (1)`
|
|
1556
1586
|
);
|
|
1557
|
-
|
|
1558
|
-
const journey = Object.values(metadataMap.metadata);
|
|
1559
|
-
if (!journey.length) {
|
|
1560
|
-
Util.logger.info(`Skipping ${key} - did not find an item with such key`);
|
|
1561
|
-
continue;
|
|
1562
|
-
}
|
|
1563
|
-
objectId = journey[0].id;
|
|
1564
|
-
version = journey[0].version;
|
|
1565
|
-
if (!objectId || !version) {
|
|
1566
|
-
Util.logger.info(`Skipping ${key} - did not find an item with such key`);
|
|
1567
|
-
continue;
|
|
1568
|
-
}
|
|
1587
|
+
continue;
|
|
1569
1588
|
}
|
|
1589
|
+
} else {
|
|
1590
|
+
// key assumed
|
|
1591
|
+
journey = metadataMap.metadata[key];
|
|
1570
1592
|
}
|
|
1571
1593
|
|
|
1572
|
-
|
|
1573
|
-
(
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1594
|
+
if (!journey) {
|
|
1595
|
+
Util.logger.info(
|
|
1596
|
+
` ☇ skipping ${this.definition.type} ${key}: not found on server (2)`
|
|
1597
|
+
);
|
|
1598
|
+
continue;
|
|
1599
|
+
}
|
|
1600
|
+
if (!version) {
|
|
1601
|
+
version = journey.version;
|
|
1602
|
+
}
|
|
1603
|
+
if (journey.status === 'Published') {
|
|
1604
|
+
// api would return error code 30000 and ask to open a support case when in fact we simply already have a transactionalEmail created based on this status
|
|
1605
|
+
Util.logger.error(
|
|
1606
|
+
` ☇ skipping ${this.definition.type} ${
|
|
1607
|
+
journey[this.definition.nameField]
|
|
1608
|
+
} (${journey[this.definition.keyField]}): already published`
|
|
1609
|
+
);
|
|
1610
|
+
continue;
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
switch (journey.definitionType) {
|
|
1614
|
+
case 'Transactional': {
|
|
1615
|
+
resultsTransactional.push(
|
|
1616
|
+
(async () => {
|
|
1617
|
+
try {
|
|
1618
|
+
const response = await this.client.rest.post(
|
|
1619
|
+
`/interaction/v1/interactions/transactional/create`,
|
|
1620
|
+
{ definitionId: journey.id }
|
|
1621
|
+
);
|
|
1622
|
+
if (response.errors?.length) {
|
|
1623
|
+
throw new Error(JSON.stringify(response));
|
|
1624
|
+
} else {
|
|
1625
|
+
Util.logger.info(
|
|
1626
|
+
` - published ${this.definition.type}: ${
|
|
1627
|
+
journey[this.definition.nameField]
|
|
1628
|
+
} (${journey[this.definition.keyField]} by creating the matching transactionalEmail`
|
|
1629
|
+
);
|
|
1630
|
+
statusUrls.push({ key, statusUrl: response.statusUrl });
|
|
1631
|
+
}
|
|
1632
|
+
return key;
|
|
1633
|
+
} catch (ex) {
|
|
1634
|
+
if (
|
|
1635
|
+
ex.response.status === 400 &&
|
|
1636
|
+
ex.response?.data?.errors?.length === 1 &&
|
|
1637
|
+
ex.response?.data?.errors?.[0]?.errorCode === '121500'
|
|
1638
|
+
) {
|
|
1639
|
+
Util.logger.error(
|
|
1640
|
+
`Failed to publish ${
|
|
1641
|
+
journey[this.definition.nameField]
|
|
1642
|
+
} (${journey[this.definition.keyField]}): Make sure the Event Definition Key, Data Extension and E-Mail are saved to the journey`
|
|
1643
|
+
);
|
|
1644
|
+
} else {
|
|
1645
|
+
Util.logger.error(
|
|
1646
|
+
`Failed to publish ${
|
|
1647
|
+
journey[this.definition.nameField]
|
|
1648
|
+
} (${journey[this.definition.keyField]}): ${ex.message}`
|
|
1649
|
+
);
|
|
1650
|
+
if (ex.response?.data?.errors?.length) {
|
|
1651
|
+
Util.logger.error(
|
|
1652
|
+
JSON.stringify(ex.response?.data?.errors, null, 2)
|
|
1653
|
+
);
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
})()
|
|
1658
|
+
);
|
|
1659
|
+
break;
|
|
1660
|
+
}
|
|
1661
|
+
case 'Multistep':
|
|
1662
|
+
case 'Quicksend': {
|
|
1663
|
+
resultsJourney.push(
|
|
1664
|
+
(async () => {
|
|
1665
|
+
try {
|
|
1666
|
+
const response = await this.client.rest.post(
|
|
1667
|
+
`/interaction/v1/interactions/publishAsync/${journey.id}?versionNumber=${version}`,
|
|
1668
|
+
{}
|
|
1669
|
+
); // payload is empty for this request
|
|
1670
|
+
if (response.statusUrl && response.statusId) {
|
|
1671
|
+
Util.logger.info(
|
|
1672
|
+
` - queued for publishing ${this.definition.type}: ${key}`
|
|
1673
|
+
);
|
|
1674
|
+
statusUrls.push({ key, statusUrl: response.statusUrl });
|
|
1675
|
+
} else {
|
|
1676
|
+
throw new Error(response);
|
|
1677
|
+
}
|
|
1678
|
+
return journey.key;
|
|
1679
|
+
} catch (ex) {
|
|
1680
|
+
if (
|
|
1681
|
+
ex.message === 'Cannot publish interaction in Published status.'
|
|
1682
|
+
) {
|
|
1683
|
+
Util.logger.info(
|
|
1684
|
+
` - ${this.definition.type} ${key} is already published`
|
|
1685
|
+
);
|
|
1686
|
+
} else if (
|
|
1687
|
+
ex.message === 'Cannot publish interaction in Stopped status.'
|
|
1688
|
+
) {
|
|
1689
|
+
Util.logger.warn(
|
|
1690
|
+
` - ${this.definition.type} ${key} is already published but stopped. Please resume it manually.`
|
|
1691
|
+
);
|
|
1692
|
+
} else {
|
|
1693
|
+
Util.logger.error(
|
|
1694
|
+
`Failed to publish ${this.definition.type} ${key}: ${ex.message}`
|
|
1695
|
+
);
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
})()
|
|
1699
|
+
);
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
} // for loop
|
|
1703
|
+
if (resultsJourney.length) {
|
|
1704
|
+
Util.logger.info(`Found ${resultsJourney.length} journey results`);
|
|
1705
|
+
executedKeyArr.push(...(await Promise.all(resultsJourney)).filter(Boolean));
|
|
1706
|
+
|
|
1707
|
+
if (!Util.OPTIONS.skipStatusCheck && statusUrls.length) {
|
|
1708
|
+
Util.logger.info(
|
|
1709
|
+
`Checking status of ${statusUrls.length} published item${statusUrls.length === 1 ? '' : 's'}`
|
|
1710
|
+
);
|
|
1711
|
+
executedKeyArr.length = 0;
|
|
1712
|
+
await Util.sleep(5000);
|
|
1713
|
+
for (const item of statusUrls) {
|
|
1714
|
+
executedKeyArr.push(await this._checkPublishStatus(item.statusUrl, item.key));
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1605
1717
|
}
|
|
1606
|
-
|
|
1718
|
+
if (resultsTransactional.length) {
|
|
1719
|
+
Util.logger.info(`Found ${resultsTransactional.length} journey results`);
|
|
1720
|
+
const transactionalKeyArr = (await Promise.all(resultsTransactional)).filter(Boolean);
|
|
1721
|
+
executedKeyArr.push(...transactionalKeyArr);
|
|
1722
|
+
|
|
1723
|
+
Util.logger.info('Retrieving relevant journeys');
|
|
1724
|
+
const retriever = new Retriever(this.properties, this.buObject);
|
|
1725
|
+
|
|
1726
|
+
try {
|
|
1727
|
+
const updatedJourneyRetrieve = await retriever.retrieve(
|
|
1728
|
+
['journey'],
|
|
1729
|
+
transactionalKeyArr
|
|
1730
|
+
);
|
|
1607
1731
|
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1732
|
+
/** @type {MetadataTypeItem[]} */
|
|
1733
|
+
const updatedJourneys = Object.values(updatedJourneyRetrieve?.journey[0]);
|
|
1734
|
+
if (updatedJourneys) {
|
|
1735
|
+
const updatedTransactionalEmails = [];
|
|
1736
|
+
for (const journey of updatedJourneys) {
|
|
1737
|
+
updatedTransactionalEmails.push(
|
|
1738
|
+
journey.activities?.[0]?.configurationArguments
|
|
1739
|
+
?.r__transactionalEmail_key
|
|
1740
|
+
);
|
|
1741
|
+
}
|
|
1742
|
+
if (updatedTransactionalEmails.filter(Boolean).length) {
|
|
1743
|
+
Util.logger.info('Retrieving relevant transactionalEmails');
|
|
1744
|
+
await retriever.retrieve(
|
|
1745
|
+
['transactionalEmail'],
|
|
1746
|
+
updatedTransactionalEmails.filter(Boolean)
|
|
1747
|
+
);
|
|
1748
|
+
} else {
|
|
1749
|
+
Util.logger.error(
|
|
1750
|
+
`Could not find transactional Emails for the published journeys`
|
|
1751
|
+
);
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
} catch (ex) {
|
|
1755
|
+
Util.logger.errorStack(ex, 'retrieve failed');
|
|
1616
1756
|
}
|
|
1617
|
-
// return executedKeyArr;
|
|
1618
1757
|
}
|
|
1619
1758
|
Util.logger.info(
|
|
1620
1759
|
`Published ${executedKeyArr.filter(Boolean).length} of ${keyArr.length} items`
|
|
@@ -47,6 +47,24 @@ class TransactionalEmail extends TransactionalMessage {
|
|
|
47
47
|
return super.update(metadata);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Updates a single item
|
|
52
|
+
*
|
|
53
|
+
* @param {MetadataTypeItem} metadata how the item shall look after the update
|
|
54
|
+
* @returns {Promise} Promise
|
|
55
|
+
*/
|
|
56
|
+
static create(metadata) {
|
|
57
|
+
if (metadata.definitionType === 'Transactional' && metadata.channel === 'email') {
|
|
58
|
+
// only send this during create or else we might end up with an unexpected outcome
|
|
59
|
+
Util.logger.warn(
|
|
60
|
+
` - ${this.definition.type} ${metadata[this.definition.nameField]} (${
|
|
61
|
+
metadata[this.definition.keyField]
|
|
62
|
+
}): While possible, it is not recommended to create transactional journeys via transactionalEmail. Instead, create the journey and then publish it (mcdev deploy cred/bu journey --publish)`
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
return super.create(metadata);
|
|
66
|
+
}
|
|
67
|
+
|
|
50
68
|
/**
|
|
51
69
|
* prepares for deployment
|
|
52
70
|
*
|
|
@@ -124,9 +142,8 @@ class TransactionalEmail extends TransactionalMessage {
|
|
|
124
142
|
static async postDeployTasks() {
|
|
125
143
|
if (this._createdJourneyKeys?.length) {
|
|
126
144
|
Util.logger.warn(
|
|
127
|
-
`Please download related journeys via: mcdev
|
|
128
|
-
|
|
129
|
-
} journey "${this._createdJourneyKeys.join(',')}"`
|
|
145
|
+
`Please download related journeys via: mcdev retrieve ${this.buObject.credential}/${this.buObject.businessUnit} -m
|
|
146
|
+
${this._createdJourneyKeys.map((el) => `"journey:${el}"`).join(' ')}`
|
|
130
147
|
);
|
|
131
148
|
}
|
|
132
149
|
delete this._createdJourneyKeys;
|
|
@@ -23,7 +23,6 @@ export default {
|
|
|
23
23
|
dependencyGraph: {
|
|
24
24
|
// classic email cannot be deployed anymore
|
|
25
25
|
event: ['triggers.metaData.r__event_key'],
|
|
26
|
-
transactionalEmail: ['activities.configurationArguments.r__transactionalEmail_key'],
|
|
27
26
|
dataExtension: [
|
|
28
27
|
'activities.metaData.highThroughput.r__dataExtension_key',
|
|
29
28
|
'activities.configurationArguments.triggeredSend.r__dataExtension_key.domainExclusions',
|
package/lib/util/file.js
CHANGED
|
@@ -260,57 +260,61 @@ const File = {
|
|
|
260
260
|
// will throw an error falsely assuming bad syntax
|
|
261
261
|
return await this.beautify_beautyAmp(content, true);
|
|
262
262
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
263
|
+
|
|
264
|
+
if (!FileFs.prettierConfig.parser) {
|
|
265
|
+
// load the right prettier config relative to our file
|
|
266
|
+
switch (filetype) {
|
|
267
|
+
case 'htm':
|
|
268
|
+
case 'html': {
|
|
269
|
+
FileFs.prettierConfig.parser = 'html';
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
case 'ssjs':
|
|
273
|
+
case 'js': {
|
|
274
|
+
FileFs.prettierConfig.parser = 'babel';
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
case 'json': {
|
|
278
|
+
FileFs.prettierConfig.parser = 'json';
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
case 'yaml':
|
|
282
|
+
case 'yml': {
|
|
283
|
+
FileFs.prettierConfig.parser = 'yaml';
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
case 'ts': {
|
|
287
|
+
FileFs.prettierConfig.parser = 'babel-ts';
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
case 'css': {
|
|
291
|
+
FileFs.prettierConfig.parser = 'css';
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
case 'less': {
|
|
295
|
+
FileFs.prettierConfig.parser = 'less';
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
case 'sass':
|
|
299
|
+
case 'scss': {
|
|
300
|
+
FileFs.prettierConfig.parser = 'scss';
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
case 'md': {
|
|
304
|
+
FileFs.prettierConfig.parser = 'markdown';
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
case 'sql': {
|
|
308
|
+
FileFs.prettierConfig.parser = 'sql';
|
|
309
|
+
FileFs.prettierConfig.plugins = ['prettier-plugin-sql'];
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
default: {
|
|
313
|
+
FileFs.prettierConfig.parser = 'babel';
|
|
314
|
+
}
|
|
312
315
|
}
|
|
313
316
|
}
|
|
317
|
+
|
|
314
318
|
formatted = await prettier.format(content, FileFs.prettierConfig);
|
|
315
319
|
} catch (ex) {
|
|
316
320
|
// save prettier errror into log file
|