mcdev 7.6.1 → 7.6.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.
Files changed (83) hide show
  1. package/.github/ISSUE_TEMPLATE/bug.yml +2 -0
  2. package/.github/workflows/close_issues_on_merge.yml +1 -1
  3. package/.github/workflows/coverage-base-update.yml +2 -2
  4. package/.github/workflows/coverage.yml +1 -1
  5. package/.vscode/extensions.json +1 -0
  6. package/.vscode/settings.json +21 -1
  7. package/@types/lib/index.d.ts +15 -15
  8. package/@types/lib/index.d.ts.map +1 -1
  9. package/@types/lib/metadataTypes/Asset.d.ts.map +1 -1
  10. package/@types/lib/metadataTypes/Automation.d.ts +6 -0
  11. package/@types/lib/metadataTypes/Automation.d.ts.map +1 -1
  12. package/@types/lib/metadataTypes/DataExtract.d.ts +7 -0
  13. package/@types/lib/metadataTypes/DataExtract.d.ts.map +1 -1
  14. package/@types/lib/metadataTypes/Event.d.ts.map +1 -1
  15. package/@types/lib/metadataTypes/FileLocation.d.ts +39 -5
  16. package/@types/lib/metadataTypes/FileLocation.d.ts.map +1 -1
  17. package/@types/lib/metadataTypes/Journey.d.ts +13 -3
  18. package/@types/lib/metadataTypes/Journey.d.ts.map +1 -1
  19. package/@types/lib/metadataTypes/MetadataType.d.ts.map +1 -1
  20. package/@types/lib/metadataTypes/SendClassification.d.ts +7 -0
  21. package/@types/lib/metadataTypes/SendClassification.d.ts.map +1 -1
  22. package/@types/lib/metadataTypes/SenderProfile.d.ts +7 -0
  23. package/@types/lib/metadataTypes/SenderProfile.d.ts.map +1 -1
  24. package/@types/lib/metadataTypes/definitions/Automation.definition.d.ts +6 -0
  25. package/@types/lib/metadataTypes/definitions/FileLocation.definition.d.ts +24 -0
  26. package/@types/lib/util/cache.d.ts +1 -1
  27. package/@types/lib/util/cache.d.ts.map +1 -1
  28. package/@types/lib/util/config.d.ts.map +1 -1
  29. package/@types/lib/util/file.d.ts.map +1 -1
  30. package/LICENSE +1 -1
  31. package/README.md +1 -1
  32. package/boilerplate/config.json +1 -0
  33. package/boilerplate/files/.vscode/extensions.json +1 -0
  34. package/boilerplate/forcedUpdates.json +4 -0
  35. package/lib/index.js +34 -17
  36. package/lib/metadataTypes/Asset.js +31 -8
  37. package/lib/metadataTypes/Automation.js +45 -25
  38. package/lib/metadataTypes/DataExtension.js +1 -1
  39. package/lib/metadataTypes/DataExtract.js +20 -0
  40. package/lib/metadataTypes/Event.js +20 -5
  41. package/lib/metadataTypes/FileLocation.js +43 -5
  42. package/lib/metadataTypes/Journey.js +176 -77
  43. package/lib/metadataTypes/MetadataType.js +22 -9
  44. package/lib/metadataTypes/SendClassification.js +20 -0
  45. package/lib/metadataTypes/SenderProfile.js +20 -0
  46. package/lib/metadataTypes/definitions/Automation.definition.js +6 -0
  47. package/lib/metadataTypes/definitions/FileLocation.definition.js +22 -2
  48. package/lib/util/cache.js +8 -3
  49. package/lib/util/config.js +6 -0
  50. package/lib/util/file.js +17 -14
  51. package/package.json +17 -18
  52. package/prepare-release.js +37 -0
  53. package/test/general.test.js +69 -6
  54. package/test/mockRoot/.mcdevrc.json +2 -1
  55. package/test/mockRoot/deploy/testInstance/testBU/journey/testExisting_journey_Multistep.journey-meta.json +418 -0
  56. package/test/mockRoot/deploy/testInstance/testBU/journey/testExisting_temail.journey-meta.json +212 -0
  57. package/test/mockRoot/deploy/testInstance/testBU/journey/testExisting_temail_notPublished.journey-meta.json +217 -0
  58. package/test/resourceFactory.js +12 -10
  59. package/test/resources/9999999/asset/build-templatebasedemail-expected.json +0 -1
  60. package/test/resources/9999999/asset/retrieve-templatebasedemail-expected.json +0 -1
  61. package/test/resources/9999999/asset/template-templatebasedemail-expected.json +0 -1
  62. package/test/resources/9999999/asset-deploy/block/testNew_asset_badExtension.bad-type-extension.json +39 -0
  63. package/test/resources/9999999/asset-deploy/block/testNew_asset_badName_bad.asset-block-meta.json +39 -0
  64. package/test/resources/9999999/dataExtract/patch-expected.json +3 -1
  65. package/test/resources/9999999/event/get-published-expected.json +30 -0
  66. package/test/resources/9999999/event/post_withExistingDE-callout-expected.json +211 -0
  67. package/test/resources/9999999/event/put-expected.json +12 -11
  68. package/test/resources/9999999/event-deploy/testNew_event_badExtension.bad-type-extension.json +200 -0
  69. package/test/resources/9999999/event-deploy/testNew_event_badName_bad.event-meta.json +200 -0
  70. package/test/resources/9999999/interaction/v1/eventDefinitions/key_DEAudience-2e3c73b6-48cc-2ec0-5522-48636e1a236e/get-response.json +39 -0
  71. package/test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_Multistep/put-response.json +461 -0
  72. package/test/resources/9999999/interaction/v1/interactions/key_testExisting_temail/put-response.json +219 -0
  73. package/test/resources/9999999/interaction/v1/interactions/key_testExisting_temail_notPublished/put-response.json +226 -0
  74. package/test/resources/9999999/journey/get-published-expected.json +217 -0
  75. package/test/resources/9999999/sendClassification/patch-expected.json +3 -1
  76. package/test/resources/9999999/senderProfile/patch-expected.json +12 -8
  77. package/test/resources/9999999/transactionalEmail/get-published-expected.json +20 -0
  78. package/test/type.dataExtract.test.js +1 -1
  79. package/test/type.event.test.js +3 -3
  80. package/test/type.journey.test.js +222 -13
  81. package/test/type.sendClassification.test.js +1 -1
  82. package/test/type.senderProfile.test.js +1 -1
  83. package/test/utils.js +5 -1
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../lib/util/config.js"],"names":[],"mappings":";yBASa,OAAO,wBAAwB,EAAE,UAAU;uBAC3C,OAAO,wBAAwB,EAAE,QAAQ;oBACzC,OAAO,wBAAwB,EAAE,KAAK;0BACtC,OAAO,wBAAwB,EAAE,WAAW;8BAC5C,OAAO,wBAAwB,EAAE,eAAe;2BAChD,OAAO,wBAAwB,EAAE,YAAY;sBAC7C,OAAO,wBAAwB,EAAE,OAAO;+BACxC,OAAO,wBAAwB,EAAE,gBAAgB;mCACjD,OAAO,wBAAwB,EAAE,oBAAoB;kCACrD,OAAO,wBAAwB,EAAE,mBAAmB;8BACpD,OAAO,wBAAwB,EAAE,eAAe;iCAChD,OAAO,wBAAwB,EAAE,kBAAkB;oCACnD,OAAO,wBAAwB,EAAE,qBAAqB;mCACtD,OAAO,wBAAwB,EAAE,oBAAoB;gCACrD,OAAO,wBAAwB,EAAE,iBAAiB;0BAClD,OAAO,wBAAwB,EAAE,WAAW;2BAC5C,OAAO,wBAAwB,EAAE,YAAY;;;IAStD;;;;;;OAMG;IACH,gCAJW,OAAO,WACP,OAAO,GACL,OAAO,CAAE,OAAO,CAAC,CA2D7B;IAED;;;;;;OAMG;IACH,qCAJW,OAAO,WACP,OAAO,GACL,OAAO,CAAE,OAAO,GAAG,MAAM,EAAE,CAAC,CA6LxC;IAED;;;;;OAKG;IACH,iCAFa,OAAO,CAAE,OAAO,CAAC,CAe7B"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../lib/util/config.js"],"names":[],"mappings":";yBASa,OAAO,wBAAwB,EAAE,UAAU;uBAC3C,OAAO,wBAAwB,EAAE,QAAQ;oBACzC,OAAO,wBAAwB,EAAE,KAAK;0BACtC,OAAO,wBAAwB,EAAE,WAAW;8BAC5C,OAAO,wBAAwB,EAAE,eAAe;2BAChD,OAAO,wBAAwB,EAAE,YAAY;sBAC7C,OAAO,wBAAwB,EAAE,OAAO;+BACxC,OAAO,wBAAwB,EAAE,gBAAgB;mCACjD,OAAO,wBAAwB,EAAE,oBAAoB;kCACrD,OAAO,wBAAwB,EAAE,mBAAmB;8BACpD,OAAO,wBAAwB,EAAE,eAAe;iCAChD,OAAO,wBAAwB,EAAE,kBAAkB;oCACnD,OAAO,wBAAwB,EAAE,qBAAqB;mCACtD,OAAO,wBAAwB,EAAE,oBAAoB;gCACrD,OAAO,wBAAwB,EAAE,iBAAiB;0BAClD,OAAO,wBAAwB,EAAE,WAAW;2BAC5C,OAAO,wBAAwB,EAAE,YAAY;;;IAStD;;;;;;OAMG;IACH,gCAJW,OAAO,WACP,OAAO,GACL,OAAO,CAAE,OAAO,CAAC,CA2D7B;IAED;;;;;;OAMG;IACH,qCAJW,OAAO,WACP,OAAO,GACL,OAAO,CAAE,OAAO,GAAG,MAAM,EAAE,CAAC,CAmMxC;IAED;;;;;OAKG;IACH,iCAFa,OAAO,CAAE,OAAO,CAAC,CAe7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../lib/util/file.js"],"names":[],"mappings":";yBAWa,OAAO,wBAAwB,EAAE,UAAU;uBAC3C,OAAO,wBAAwB,EAAE,QAAQ;oBACzC,OAAO,wBAAwB,EAAE,KAAK;0BACtC,OAAO,wBAAwB,EAAE,WAAW;8BAC5C,OAAO,wBAAwB,EAAE,eAAe;2BAChD,OAAO,wBAAwB,EAAE,YAAY;sBAC7C,OAAO,wBAAwB,EAAE,OAAO;+BACxC,OAAO,wBAAwB,EAAE,gBAAgB;mCACjD,OAAO,wBAAwB,EAAE,oBAAoB;kCACrD,OAAO,wBAAwB,EAAE,mBAAmB;8BACpD,OAAO,wBAAwB,EAAE,eAAe;iCAChD,OAAO,wBAAwB,EAAE,kBAAkB;oCACnD,OAAO,wBAAwB,EAAE,qBAAqB;mCACtD,OAAO,wBAAwB,EAAE,oBAAoB;gCACrD,OAAO,wBAAwB,EAAE,iBAAiB;0BAClD,OAAO,wBAAwB,EAAE,WAAW;2BAC5C,OAAO,wBAAwB,EAAE,YAAY;AA4jB1D;;;IA1iBI;;;;;;OAMG;yBAHQ,MAAM,MACN,MAAM,GACJ,OAAO,CAAE;QAAC,MAAM,EAAC,IAAI,GAAC,SAAS,GAAC,QAAQ,CAAC;QAAC,aAAa,EAAC,MAAM,CAAC;QAAC,IAAI,EAAC,MAAM,CAAA;KAAC,CAAC;IAkB1F;;;;;OAKG;iCAFQ,MAAM,GACJ,MAAM;IAiCnB;;;;;OAKG;qCAFQ,MAAM,GACJ,MAAM;IA2BnB;;;;;OAKG;4CAFQ,MAAM,GACJ,MAAM;IAMnB;;;;;OAKG;sCAFQ,MAAM,GAAC,MAAM,EAAE,KACb,MAAM;IAcnB;;;;;;;OAOG;iCAJQ,MAAM,GAAC,MAAM,EAAE,YACf,MAAM,WACN,MAAM;IAcjB;;;;;;;;;;OAUG;mCANQ,MAAM,GAAC,MAAM,EAAE,YACf,MAAM,YACN,MAAM,WACN,MAAM,sBACN,WAAW,KACT,OAAO,CAAE,OAAO,CAAC;IAuB9B;;;;;;OAMG;4CAHQ,MAAM,eACN,OAAO,KACL,OAAO,CAAE,MAAM,CAAC;IAW7B;;;;;;OAMG;kCAHQ,MAAM,eACN,OAAO,KACL,OAAO,CAAE,MAAM,CAAC;IAyB7B;;;;;;;;;OASG;oCALQ,MAAM,GAAC,MAAM,EAAE,YACf,MAAM,YACN,MAAM,WACN,MAAM,KACJ,OAAO,CAAE,MAAM,CAAC;IA2F7B;;;;;;;;;OASG;6BANQ,MAAM,GAAC,MAAM,EAAE,YACf,MAAM,YACN,MAAM,WACN,MAAM,aACN,MAAM,KACJ,OAAO,CAAE,OAAO,CAAC;IAoB9B;;;;;;;OAOG;8BAJQ,MAAM,GAAG,MAAM,EAAE,YACjB,MAAM,aACN,OAAO,KACL,OAAO,CAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IA0B7C;;;;;;;;OAQG;sCALQ,MAAM,GAAG,MAAM,EAAE,YACjB,MAAM,YACN,MAAM,aACN,MAAM,KACJ,OAAO,CAAE,MAAM,CAAC;IAc7B;;;;;;;;;;OAUG;iCALQ,MAAM,SACN,MAAM,gBACN,OAAO,gBACP,MAAM,KACJ,OAAO,CAAE,MAAM,EAAE,CAAC;IA6C/B;;;;;;;;;;;OAWG;qCALQ,MAAM,UACN,MAAM,gBACN,OAAO,gBACP,MAAM,KACJ,MAAM,EAAE,GAAG,IAAI;IA4C5B;;;;;OAKG;+BAFQ,OAAO,GACL,OAAO,CAAE,IAAI,CAAC;IAU3B;;;;;OAKG;4BAFQ,MAAM,GACJ,OAAO,CAAE,OAAO,CAAC;EAgCK;eAtlBxB,UAAU"}
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../lib/util/file.js"],"names":[],"mappings":";yBAWa,OAAO,wBAAwB,EAAE,UAAU;uBAC3C,OAAO,wBAAwB,EAAE,QAAQ;oBACzC,OAAO,wBAAwB,EAAE,KAAK;0BACtC,OAAO,wBAAwB,EAAE,WAAW;8BAC5C,OAAO,wBAAwB,EAAE,eAAe;2BAChD,OAAO,wBAAwB,EAAE,YAAY;sBAC7C,OAAO,wBAAwB,EAAE,OAAO;+BACxC,OAAO,wBAAwB,EAAE,gBAAgB;mCACjD,OAAO,wBAAwB,EAAE,oBAAoB;kCACrD,OAAO,wBAAwB,EAAE,mBAAmB;8BACpD,OAAO,wBAAwB,EAAE,eAAe;iCAChD,OAAO,wBAAwB,EAAE,kBAAkB;oCACnD,OAAO,wBAAwB,EAAE,qBAAqB;mCACtD,OAAO,wBAAwB,EAAE,oBAAoB;gCACrD,OAAO,wBAAwB,EAAE,iBAAiB;0BAClD,OAAO,wBAAwB,EAAE,WAAW;2BAC5C,OAAO,wBAAwB,EAAE,YAAY;AA+jB1D;;;IA7iBI;;;;;;OAMG;yBAHQ,MAAM,MACN,MAAM,GACJ,OAAO,CAAE;QAAC,MAAM,EAAC,IAAI,GAAC,SAAS,GAAC,QAAQ,CAAC;QAAC,aAAa,EAAC,MAAM,CAAC;QAAC,IAAI,EAAC,MAAM,CAAA;KAAC,CAAC;IAkB1F;;;;;OAKG;iCAFQ,MAAM,GACJ,MAAM;IAiCnB;;;;;OAKG;qCAFQ,MAAM,GACJ,MAAM;IA2BnB;;;;;OAKG;4CAFQ,MAAM,GACJ,MAAM;IAMnB;;;;;OAKG;sCAFQ,MAAM,GAAC,MAAM,EAAE,KACb,MAAM;IAcnB;;;;;;;OAOG;iCAJQ,MAAM,GAAC,MAAM,EAAE,YACf,MAAM,WACN,MAAM;IAcjB;;;;;;;;;;OAUG;mCANQ,MAAM,GAAC,MAAM,EAAE,YACf,MAAM,YACN,MAAM,WACN,MAAM,sBACN,WAAW,KACT,OAAO,CAAE,OAAO,CAAC;IAuB9B;;;;;;OAMG;4CAHQ,MAAM,eACN,OAAO,KACL,OAAO,CAAE,MAAM,CAAC;IAW7B;;;;;;OAMG;kCAHQ,MAAM,eACN,OAAO,KACL,OAAO,CAAE,MAAM,CAAC;IAyB7B;;;;;;;;;OASG;oCALQ,MAAM,GAAC,MAAM,EAAE,YACf,MAAM,YACN,MAAM,WACN,MAAM,KACJ,OAAO,CAAE,MAAM,CAAC;IA8F7B;;;;;;;;;OASG;6BANQ,MAAM,GAAC,MAAM,EAAE,YACf,MAAM,YACN,MAAM,WACN,MAAM,aACN,MAAM,KACJ,OAAO,CAAE,OAAO,CAAC;IAoB9B;;;;;;;OAOG;8BAJQ,MAAM,GAAG,MAAM,EAAE,YACjB,MAAM,aACN,OAAO,KACL,OAAO,CAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IA0B7C;;;;;;;;OAQG;sCALQ,MAAM,GAAG,MAAM,EAAE,YACjB,MAAM,YACN,MAAM,aACN,MAAM,KACJ,OAAO,CAAE,MAAM,CAAC;IAc7B;;;;;;;;;;OAUG;iCALQ,MAAM,SACN,MAAM,gBACN,OAAO,gBACP,MAAM,KACJ,OAAO,CAAE,MAAM,EAAE,CAAC;IA6C/B;;;;;;;;;;;OAWG;qCALQ,MAAM,UACN,MAAM,gBACN,OAAO,gBACP,MAAM,KACJ,MAAM,EAAE,GAAG,IAAI;IA4C5B;;;;;OAKG;+BAFQ,OAAO,GACL,OAAO,CAAE,IAAI,CAAC;IAU3B;;;;;OAKG;4BAFQ,MAAM,GACJ,OAAO,CAAE,OAAO,CAAC;EAgCK;eAzlBxB,UAAU"}
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020-2024 Accenture
3
+ Copyright (c) 2020-2025 Accenture
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -73,4 +73,4 @@ The people that lead this project:
73
73
 
74
74
  ## Copyright
75
75
 
76
- Copyright (c) 2020-2024 Accenture. [MIT licensed](https://github.com/Accenture/sfmc-devtools/blob/main/LICENSE).
76
+ Copyright (c) 2020-2025 Accenture. [MIT licensed](https://github.com/Accenture/sfmc-devtools/blob/main/LICENSE).
@@ -7,6 +7,7 @@
7
7
  },
8
8
  "options": {
9
9
  "formatOnSave": true,
10
+ "formatErrorLog": false,
10
11
  "deployment": {
11
12
  "commitHistory": 10,
12
13
  "sourceTargetMapping": {
@@ -6,6 +6,7 @@
6
6
  "recommendations": [
7
7
  // collaboration
8
8
  "aaron-bond.better-comments",
9
+ "johnpapa.vscode-peacock",
9
10
 
10
11
  // Linters
11
12
  "dbaeumer.vscode-eslint",
@@ -1,4 +1,8 @@
1
1
  [
2
+ {
3
+ "version": "7.6.2",
4
+ "files": [".vscode/extensions.json"]
5
+ },
2
6
  {
3
7
  "version": "7.4.3",
4
8
  "files": ["eslint.config.js", ".prettierrc"]
package/lib/index.js CHANGED
@@ -730,7 +730,7 @@ class Mcdev {
730
730
  * ensures triggered sends are restarted to ensure they pick up on changes of the underlying emails
731
731
  *
732
732
  * @param {string} businessUnit references credentials from properties.json
733
- * @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types
733
+ * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types
734
734
  * @param {string[]} [keys] customerkey of the metadata
735
735
  * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
736
736
  */
@@ -1412,19 +1412,6 @@ class Mcdev {
1412
1412
  }
1413
1413
  }
1414
1414
 
1415
- /**
1416
- * Schedule an item (shortcut for execute --schedule)
1417
- *
1418
- * @param {string} businessUnit name of BU
1419
- * @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types
1420
- * @param {string[]} [keys] customerkey of the metadata
1421
- * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
1422
- */
1423
- static async schedule(businessUnit, selectedTypes, keys) {
1424
- this.setOptions({ schedule: true });
1425
- return this.#runMethod('execute', businessUnit, selectedTypes, keys);
1426
- }
1427
-
1428
1415
  /**
1429
1416
  * Publish an item
1430
1417
  *
@@ -1452,7 +1439,7 @@ class Mcdev {
1452
1439
  * Start/execute an item
1453
1440
  *
1454
1441
  * @param {string} businessUnit name of BU
1455
- * @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types
1442
+ * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types
1456
1443
  * @param {string[]} [keys] customerkey of the metadata
1457
1444
  * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
1458
1445
  */
@@ -1460,11 +1447,24 @@ class Mcdev {
1460
1447
  return this.#runMethod('execute', businessUnit, selectedTypes, keys);
1461
1448
  }
1462
1449
 
1450
+ /**
1451
+ * Schedule an item (shortcut for execute --schedule)
1452
+ *
1453
+ * @param {string} businessUnit name of BU
1454
+ * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types
1455
+ * @param {string[]} [keys] customerkey of the metadata
1456
+ * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
1457
+ */
1458
+ static async schedule(businessUnit, selectedTypes, keys) {
1459
+ this.setOptions({ schedule: true });
1460
+ return this.#runMethod('execute', businessUnit, selectedTypes, keys);
1461
+ }
1462
+
1463
1463
  /**
1464
1464
  * pause an item
1465
1465
  *
1466
1466
  * @param {string} businessUnit name of BU
1467
- * @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types
1467
+ * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types
1468
1468
  * @param {string[]} [keys] customerkey of the metadata
1469
1469
  * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
1470
1470
  */
@@ -1476,7 +1476,7 @@ class Mcdev {
1476
1476
  * stop an item
1477
1477
  *
1478
1478
  * @param {string} businessUnit name of BU
1479
- * @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types
1479
+ * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types
1480
1480
  * @param {string[]} [keys] customerkey of the metadata
1481
1481
  * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
1482
1482
  */
@@ -1671,6 +1671,7 @@ class Mcdev {
1671
1671
  Util.startLogger();
1672
1672
  let lang_past;
1673
1673
  let lang_present;
1674
+ let requireType;
1674
1675
  let requireKeyOrLike;
1675
1676
  let checkMetadataSupport;
1676
1677
  /** @type {Object.<string, Object.<string, string[]>>} */
@@ -1680,6 +1681,7 @@ class Mcdev {
1680
1681
  case 'execute': {
1681
1682
  lang_past = 'executed';
1682
1683
  lang_present = 'executing';
1684
+ requireType = true;
1683
1685
  requireKeyOrLike = true;
1684
1686
  checkMetadataSupport = true;
1685
1687
  break;
@@ -1687,6 +1689,7 @@ class Mcdev {
1687
1689
  case 'pause': {
1688
1690
  lang_past = 'paused';
1689
1691
  lang_present = 'pausing';
1692
+ requireType = true;
1690
1693
  requireKeyOrLike = true;
1691
1694
  checkMetadataSupport = true;
1692
1695
  break;
@@ -1694,6 +1697,7 @@ class Mcdev {
1694
1697
  case 'stop': {
1695
1698
  lang_past = 'stopped';
1696
1699
  lang_present = 'stopping';
1700
+ requireType = true;
1697
1701
  requireKeyOrLike = true;
1698
1702
  checkMetadataSupport = true;
1699
1703
  break;
@@ -1701,6 +1705,7 @@ class Mcdev {
1701
1705
  case 'publish': {
1702
1706
  lang_past = 'published';
1703
1707
  lang_present = 'publishing';
1708
+ requireType = true;
1704
1709
  requireKeyOrLike = true;
1705
1710
  checkMetadataSupport = true;
1706
1711
  break;
@@ -1708,6 +1713,7 @@ class Mcdev {
1708
1713
  case 'validate': {
1709
1714
  lang_past = 'validated';
1710
1715
  lang_present = 'validating';
1716
+ requireType = true;
1711
1717
  requireKeyOrLike = true;
1712
1718
  checkMetadataSupport = true;
1713
1719
  break;
@@ -1715,6 +1721,7 @@ class Mcdev {
1715
1721
  case 'fixKeys': {
1716
1722
  lang_past = 'fixed keys';
1717
1723
  lang_present = 'fixing keys';
1724
+ requireType = false;
1718
1725
  requireKeyOrLike = false;
1719
1726
  checkMetadataSupport = false;
1720
1727
  break;
@@ -1722,6 +1729,7 @@ class Mcdev {
1722
1729
  case 'replaceCbReference': {
1723
1730
  lang_past = 'replaced references';
1724
1731
  lang_present = 'replacing references';
1732
+ requireType = false;
1725
1733
  requireKeyOrLike = false;
1726
1734
  checkMetadataSupport = true;
1727
1735
  break;
@@ -1729,6 +1737,7 @@ class Mcdev {
1729
1737
  case 'refresh': {
1730
1738
  lang_past = 'refreshed';
1731
1739
  lang_present = 'refreshing';
1740
+ requireType = true;
1732
1741
  requireKeyOrLike = false;
1733
1742
  checkMetadataSupport = true;
1734
1743
  break;
@@ -1767,6 +1776,14 @@ class Mcdev {
1767
1776
  selectedTypesObj = selectedTypes;
1768
1777
  }
1769
1778
  }
1779
+ if (
1780
+ requireType &&
1781
+ !Array.isArray(selectedTypesArr) &&
1782
+ (!selectedTypesObj || !Object.keys(selectedTypesObj).length)
1783
+ ) {
1784
+ Util.logger.error('At least one metadata type needs to be defined.');
1785
+ return resultObj;
1786
+ }
1770
1787
  const properties = await config.getProperties();
1771
1788
  if (!(await config.checkProperties(properties))) {
1772
1789
  // return null here to avoid seeing 2 error messages for the same issue
@@ -1196,9 +1196,8 @@ class Asset extends MetadataType {
1196
1196
  };
1197
1197
  }
1198
1198
  if (asset.r__folder_Path) {
1199
- // more often than not, folders get replaced but that change is not updated in the snapshot of the content block here in another contentblock
1200
- // therefore, if we couldn't resolve the folder during retrieve (and hence no r__folder_Path was set), we would also fail here
1201
- this.setFolderId(asset);
1199
+ // if we convert this into a folder path then renamed folders might end up blocking deployments, therefore, we instead omit this detail from now on
1200
+ delete asset.r__folder_Path;
1202
1201
  }
1203
1202
  await this._preDeployTasksBocks(asset);
1204
1203
  }
@@ -1886,7 +1885,8 @@ class Asset extends MetadataType {
1886
1885
  }
1887
1886
  }
1888
1887
  if (asset.category?.id) {
1889
- this.setFolderPath(asset, true);
1888
+ // if we convert this into a folder path then renamed folders might end up blocking deployments, therefore, we instead omit this detail from now on
1889
+ delete asset.category;
1890
1890
  }
1891
1891
 
1892
1892
  if (asset.slots) {
@@ -1954,11 +1954,34 @@ class Asset extends MetadataType {
1954
1954
  subtype,
1955
1955
  fileName2FileContent
1956
1956
  );
1957
- } else if (fileName.endsWith(fileEnding)) {
1957
+ } else if (fileName.endsWith('.json')) {
1958
+ const errorDir = currentdir.split('\\').join('/');
1958
1959
  const fileContent = await File.readJSONFile(currentdir, fileName, false);
1959
- // subtype will change the metadata suffix length
1960
- const fileNameWithoutEnding = fileName.slice(0, -fileEndingLength);
1961
- fileName2FileContent[fileNameWithoutEnding] = fileContent;
1960
+ // ! convert numbers to string to allow numeric keys to be checked properly
1961
+ const key = Number.isInteger(fileContent[this.definition.keyField])
1962
+ ? fileContent[this.definition.keyField].toString()
1963
+ : fileContent[this.definition.keyField];
1964
+ if (fileName.endsWith(fileEnding)) {
1965
+ // subtype will change the metadata suffix length
1966
+ const fileNameWithoutEnding = File.reverseFilterIllegalFilenames(
1967
+ fileName.slice(0, -fileEndingLength)
1968
+ );
1969
+ if (key === fileNameWithoutEnding) {
1970
+ fileName2FileContent[fileNameWithoutEnding] = fileContent;
1971
+ } else {
1972
+ Util.logger.error(
1973
+ ` ☇ skipping ${this.definition.type} ${key}: Name of the metadata file and the JSON-key (${this.definition.keyField}) must match. Expected: ${key}${fileEnding}. Actual: ` +
1974
+ Util.getGrayMsg(`${errorDir}/`) +
1975
+ fileName
1976
+ );
1977
+ }
1978
+ } else {
1979
+ Util.logger.error(
1980
+ ` ☇ skipping ${this.definition.type} ${key}: Name of the metadata file must end on the extended metadata suffix. Expected: ${key}${fileEnding}. Actual: ` +
1981
+ Util.getGrayMsg(`${errorDir}/`) +
1982
+ fileName
1983
+ );
1984
+ }
1962
1985
  }
1963
1986
  } catch (ex) {
1964
1987
  // by catching this in the loop we gracefully handle the issue and move on to the next file
@@ -485,20 +485,32 @@ class Automation extends MetadataType {
485
485
  // folder
486
486
  this.setFolderPath(metadata);
487
487
  // automations are often skipped due to lack of support.
488
- if (
489
- metadata.type == 'automationtriggered' &&
490
- metadata.automationTrigger?.fileTransferLocationId
491
- ) {
492
- try {
493
- metadata.automationTrigger.r__fileLocation_name = cache.searchForField(
494
- 'fileLocation',
495
- metadata.automationTrigger.fileTransferLocationId,
496
- 'id',
497
- 'name'
498
- );
499
- delete metadata.automationTrigger.fileTransferLocationId;
500
- } catch (ex) {
501
- Util.logger.warn(` - automation ${metadata.key}: ${ex.message}`);
488
+ if (metadata.type == 'automationtriggered' && metadata.automationTrigger) {
489
+ const automationTrigger = metadata.automationTrigger;
490
+ if (automationTrigger.fileTransferLocationId) {
491
+ try {
492
+ automationTrigger.r__fileLocation_name = cache.searchForField(
493
+ 'fileLocation',
494
+ automationTrigger.fileTransferLocationId,
495
+ 'id',
496
+ 'name'
497
+ );
498
+ delete automationTrigger.fileTransferLocationId;
499
+ } catch (ex) {
500
+ Util.logger.warn(` - automation ${metadata.key}: ${ex.message}`);
501
+ }
502
+ }
503
+ if (automationTrigger.fileNamePatternType) {
504
+ try {
505
+ automationTrigger.fileNamePatternType = Util.inverseGet(
506
+ this.definition.fileNameOperatorMapping,
507
+ automationTrigger.fileNamePatternType
508
+ );
509
+ } catch {
510
+ Util.logger.warn(
511
+ ` - Unknown File naming Pattern '${automationTrigger.fileNamePatternType}' in Automation '${metadata.name}'`
512
+ );
513
+ }
502
514
  }
503
515
  }
504
516
  try {
@@ -921,17 +933,25 @@ class Automation extends MetadataType {
921
933
  this.notificationUpdates[metadata.key] = [];
922
934
  }
923
935
  }
924
- if (
925
- metadata.type == 'automationtriggered' &&
926
- metadata.automationTrigger?.r__fileLocation_name
927
- ) {
928
- metadata.automationTrigger.fileTransferLocationId = cache.searchForField(
929
- 'fileLocation',
930
- metadata.automationTrigger.r__fileLocation_name,
931
- 'name',
932
- 'id'
933
- );
934
- delete metadata.automationTrigger.r__fileLocation_name;
936
+ if (metadata.type == 'automationtriggered' && metadata.automationTrigger) {
937
+ const automationTrigger = metadata.automationTrigger;
938
+
939
+ if (automationTrigger.r__fileLocation_name) {
940
+ automationTrigger.fileTransferLocationId = cache.searchForField(
941
+ 'fileLocation',
942
+ automationTrigger.r__fileLocation_name,
943
+ 'name',
944
+ 'id'
945
+ );
946
+ delete automationTrigger.r__fileLocation_name;
947
+ }
948
+ if (
949
+ automationTrigger.fileNamePatternType &&
950
+ typeof automationTrigger.fileNamePatternType === 'string'
951
+ ) {
952
+ automationTrigger.fileNamePatternType =
953
+ this.definition.fileNameOperatorMapping[automationTrigger.fileNamePatternType];
954
+ }
935
955
  }
936
956
  if (this.validateDeployMetadata(metadata)) {
937
957
  // folder
@@ -304,7 +304,7 @@ class DataExtension extends MetadataType {
304
304
  delete Util.changedKeysMap?.[this.definition.type]?.[key];
305
305
 
306
306
  const cachedVersion = createdUpdated.updated
307
- ? cache.getByKey(this.definition.type, oldKey)
307
+ ? cache.getByKey(this.definition.type, key)
308
308
  : null;
309
309
  if (cachedVersion) {
310
310
  // UPDATE
@@ -139,6 +139,26 @@ class DataExtract extends MetadataType {
139
139
  return metadata;
140
140
  }
141
141
 
142
+ /**
143
+ * Gets executed after deployment of metadata type
144
+ *
145
+ * @param {MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create
146
+ * @returns {Promise.<void>} -
147
+ */
148
+ static async postDeployTasks(upsertResults) {
149
+ // re-retrieve all upserted items to ensure we have all fields (createdDate and modifiedDate are otherwise not present)
150
+ Util.logger.debug(
151
+ `Caching all ${this.definition.type} post-deploy to ensure we have all fields`
152
+ );
153
+ const typeCache = await this.retrieveForCache();
154
+ // update values in upsertResults with retrieved values before saving to disk
155
+ for (const key of Object.keys(upsertResults)) {
156
+ if (typeCache.metadata[key]) {
157
+ upsertResults[key] = typeCache.metadata[key];
158
+ }
159
+ }
160
+ }
161
+
142
162
  /**
143
163
  * manages post retrieve steps
144
164
  *
@@ -327,6 +327,7 @@ class Event extends MetadataType {
327
327
  }
328
328
  }
329
329
  } else if (createOrUpdateAction === 'create') {
330
+ let deFound;
330
331
  try {
331
332
  if (metadataItem.r__dataExtension_key) {
332
333
  metadataItem.dataExtensionId = cache.searchForField(
@@ -342,16 +343,18 @@ class Event extends MetadataType {
342
343
  'Name'
343
344
  );
344
345
  if (metadataItem.schema) {
345
- delete metadataItem.schema;
346
346
  Util.logger.info(
347
347
  ` - ${this.definition.type} ${metadataItem[this.definition.keyField]}: dataExtension ${metadataItem.r__dataExtension_key} found, ignoring schema-section in ${this.definition.type} json`
348
348
  );
349
349
  }
350
+ deFound = true;
351
+ } else {
352
+ deFound = false;
350
353
  }
351
354
  } catch {
352
- // no action
355
+ deFound = false;
353
356
  }
354
- if (metadataItem.schema) {
357
+ if (!deFound) {
355
358
  if (metadataItem.r__dataExtension_key) {
356
359
  metadataItem.schema.name = metadataItem.r__dataExtension_key;
357
360
  }
@@ -377,7 +380,7 @@ class Event extends MetadataType {
377
380
  * @returns {Promise.<void>} -
378
381
  */
379
382
  static async postDeployTasks(upsertResults, originalMetadata, createdUpdated) {
380
- // CREATE ONLY - if dataExtensions were auto-
383
+ // CREATE ONLY - if dataExtensions were auto-created
381
384
  if (this.reCacheDataExtensions.length && createdUpdated.created > 0) {
382
385
  Util.logger.warn(' - Re-caching dependent Metadata: dataExtension');
383
386
  const deRetrieve = await DataExtension.retrieveForCache();
@@ -443,6 +446,18 @@ class Event extends MetadataType {
443
446
  await retriever.retrieve(['dataExtension'], reDownloadDeKeys);
444
447
  }
445
448
  }
449
+
450
+ // re-retrieve all upserted items to ensure we have all fields (createdDate and modifiedDate are otherwise not present)
451
+ Util.logger.debug(
452
+ `Caching all ${this.definition.type} post-deploy to ensure we have all fields`
453
+ );
454
+ const typeCache = await this.retrieveForCache();
455
+ // update values in upsertResults with retrieved values before saving to disk
456
+ for (const key of Object.keys(upsertResults)) {
457
+ if (typeCache.metadata[key]) {
458
+ upsertResults[key] = typeCache.metadata[key];
459
+ }
460
+ }
446
461
  }
447
462
 
448
463
  /**
@@ -557,7 +572,7 @@ class Event extends MetadataType {
557
572
  try {
558
573
  await this.compareSalesforceEntryEvents_dataExtension(
559
574
  metadata.type,
560
- metadata.configurationArguments.eventDataSummary,
575
+ metadata.configurationArguments?.eventDataSummary,
561
576
  metadata.r__dataExtension_key
562
577
  );
563
578
  } catch (ex) {
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  import MetadataType from './MetadataType.js';
4
+ import { Util } from '../util/util.js';
4
5
 
5
6
  /**
6
7
  * @typedef {import('../../types/mcdev.d.js').BuObject} BuObject
@@ -20,10 +21,10 @@ import MetadataType from './MetadataType.js';
20
21
  *
21
22
  * @augments MetadataType
22
23
  */
23
- class FtpLocation extends MetadataType {
24
+ class FileLocation extends MetadataType {
24
25
  /**
25
- * Retrieves Metadata of FtpLocation
26
- * Endpoint /automation/v1/ftplocations/ return all FtpLocations
26
+ * Retrieves Metadata of FileLocation
27
+ * Endpoint /automation/v1/ftplocations/ return all FileLocations
27
28
  *
28
29
  * @param {string} retrieveDir Directory where retrieved metadata directory will be saved
29
30
  * @param {void | string[]} [_] unused parameter
@@ -43,10 +44,47 @@ class FtpLocation extends MetadataType {
43
44
  static async retrieveForCache() {
44
45
  return super.retrieveREST(null, '/automation/v1/ftplocations/');
45
46
  }
47
+
48
+ /**
49
+ * prepares a import definition for deployment
50
+ *
51
+ * @param {MetadataTypeItem} metadata a single importDef
52
+ * @returns {Promise.<MetadataTypeItem>} Promise
53
+ */
54
+ static async preDeployTasks(metadata) {
55
+ if (metadata.c__locationType) {
56
+ metadata.locationTypeId = this.definition.locationTypeMapping[metadata.c__locationType];
57
+ }
58
+ return metadata;
59
+ }
60
+
61
+ /**
62
+ * manages post retrieve steps
63
+ *
64
+ * @param {MetadataTypeItem} metadata a single item
65
+ * @returns {MetadataTypeItem} parsed metadata
66
+ */
67
+ static postRetrieveTasks(metadata) {
68
+ if (metadata.locationTypeId) {
69
+ try {
70
+ metadata.c__locationType = Util.inverseGet(
71
+ this.definition.locationTypeMapping,
72
+ metadata.locationTypeId
73
+ );
74
+ delete metadata.locationTypeId;
75
+ } catch {
76
+ Util.logger.info(
77
+ 'Please report this new & unknown locationTypeId to the mcdev developer team via github: ' +
78
+ metadata.locationTypeId
79
+ );
80
+ }
81
+ }
82
+ return metadata;
83
+ }
46
84
  }
47
85
 
48
86
  // Assign definition to static attributes
49
87
  import MetadataTypeDefinitions from '../MetadataTypeDefinitions.js';
50
- FtpLocation.definition = MetadataTypeDefinitions.fileLocation;
88
+ FileLocation.definition = MetadataTypeDefinitions.fileLocation;
51
89
 
52
- export default FtpLocation;
90
+ export default FileLocation;