mcdev 7.0.4 → 7.1.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.
Files changed (335) hide show
  1. package/.github/ISSUE_TEMPLATE/bug.yml +1 -0
  2. package/.husky/post-checkout +1 -1
  3. package/.husky/post-merge +7 -1
  4. package/.husky/pre-commit +2 -0
  5. package/@types/lib/Builder.d.ts.map +1 -1
  6. package/@types/lib/Deployer.d.ts +3 -0
  7. package/@types/lib/Deployer.d.ts.map +1 -1
  8. package/@types/lib/index.d.ts +70 -19
  9. package/@types/lib/index.d.ts.map +1 -1
  10. package/@types/lib/metadataTypes/Asset.d.ts +53 -16
  11. package/@types/lib/metadataTypes/Asset.d.ts.map +1 -1
  12. package/@types/lib/metadataTypes/AttributeGroup.d.ts +3 -0
  13. package/@types/lib/metadataTypes/AttributeGroup.d.ts.map +1 -1
  14. package/@types/lib/metadataTypes/AttributeSet.d.ts +5 -0
  15. package/@types/lib/metadataTypes/AttributeSet.d.ts.map +1 -1
  16. package/@types/lib/metadataTypes/Automation.d.ts +11 -0
  17. package/@types/lib/metadataTypes/Automation.d.ts.map +1 -1
  18. package/@types/lib/metadataTypes/Campaign.d.ts +1 -0
  19. package/@types/lib/metadataTypes/Campaign.d.ts.map +1 -1
  20. package/@types/lib/metadataTypes/ContentArea.d.ts +1 -0
  21. package/@types/lib/metadataTypes/ContentArea.d.ts.map +1 -1
  22. package/@types/lib/metadataTypes/DataExtension.d.ts +5 -2
  23. package/@types/lib/metadataTypes/DataExtension.d.ts.map +1 -1
  24. package/@types/lib/metadataTypes/DataExtensionField.d.ts +3 -4
  25. package/@types/lib/metadataTypes/DataExtensionField.d.ts.map +1 -1
  26. package/@types/lib/metadataTypes/DataExtensionTemplate.d.ts +1 -0
  27. package/@types/lib/metadataTypes/DataExtensionTemplate.d.ts.map +1 -1
  28. package/@types/lib/metadataTypes/DataExtract.d.ts +1 -0
  29. package/@types/lib/metadataTypes/DataExtract.d.ts.map +1 -1
  30. package/@types/lib/metadataTypes/DataExtractType.d.ts +1 -0
  31. package/@types/lib/metadataTypes/DataExtractType.d.ts.map +1 -1
  32. package/@types/lib/metadataTypes/DeliveryProfile.d.ts +1 -0
  33. package/@types/lib/metadataTypes/DeliveryProfile.d.ts.map +1 -1
  34. package/@types/lib/metadataTypes/Discovery.d.ts +1 -0
  35. package/@types/lib/metadataTypes/Discovery.d.ts.map +1 -1
  36. package/@types/lib/metadataTypes/Email.d.ts +1 -0
  37. package/@types/lib/metadataTypes/Email.d.ts.map +1 -1
  38. package/@types/lib/metadataTypes/EmailSend.d.ts +8 -0
  39. package/@types/lib/metadataTypes/EmailSend.d.ts.map +1 -1
  40. package/@types/lib/metadataTypes/Event.d.ts +3 -0
  41. package/@types/lib/metadataTypes/Event.d.ts.map +1 -1
  42. package/@types/lib/metadataTypes/FileLocation.d.ts +1 -0
  43. package/@types/lib/metadataTypes/FileLocation.d.ts.map +1 -1
  44. package/@types/lib/metadataTypes/FileTransfer.d.ts +1 -0
  45. package/@types/lib/metadataTypes/FileTransfer.d.ts.map +1 -1
  46. package/@types/lib/metadataTypes/Filter.d.ts +1 -0
  47. package/@types/lib/metadataTypes/Filter.d.ts.map +1 -1
  48. package/@types/lib/metadataTypes/Folder.d.ts +39 -25
  49. package/@types/lib/metadataTypes/Folder.d.ts.map +1 -1
  50. package/@types/lib/metadataTypes/ImportFile.d.ts +5 -0
  51. package/@types/lib/metadataTypes/ImportFile.d.ts.map +1 -1
  52. package/@types/lib/metadataTypes/Journey.d.ts +42 -3
  53. package/@types/lib/metadataTypes/Journey.d.ts.map +1 -1
  54. package/@types/lib/metadataTypes/List.d.ts +1 -0
  55. package/@types/lib/metadataTypes/List.d.ts.map +1 -1
  56. package/@types/lib/metadataTypes/MetadataType.d.ts +50 -3
  57. package/@types/lib/metadataTypes/MetadataType.d.ts.map +1 -1
  58. package/@types/lib/metadataTypes/MobileCode.d.ts +1 -0
  59. package/@types/lib/metadataTypes/MobileCode.d.ts.map +1 -1
  60. package/@types/lib/metadataTypes/MobileKeyword.d.ts +9 -0
  61. package/@types/lib/metadataTypes/MobileKeyword.d.ts.map +1 -1
  62. package/@types/lib/metadataTypes/MobileMessage.d.ts +4 -0
  63. package/@types/lib/metadataTypes/MobileMessage.d.ts.map +1 -1
  64. package/@types/lib/metadataTypes/Query.d.ts +3 -0
  65. package/@types/lib/metadataTypes/Query.d.ts.map +1 -1
  66. package/@types/lib/metadataTypes/Role.d.ts +1 -0
  67. package/@types/lib/metadataTypes/Role.d.ts.map +1 -1
  68. package/@types/lib/metadataTypes/Script.d.ts +3 -1
  69. package/@types/lib/metadataTypes/Script.d.ts.map +1 -1
  70. package/@types/lib/metadataTypes/SendClassification.d.ts +3 -0
  71. package/@types/lib/metadataTypes/SendClassification.d.ts.map +1 -1
  72. package/@types/lib/metadataTypes/SenderProfile.d.ts +1 -6
  73. package/@types/lib/metadataTypes/SenderProfile.d.ts.map +1 -1
  74. package/@types/lib/metadataTypes/TransactionalEmail.d.ts +6 -0
  75. package/@types/lib/metadataTypes/TransactionalEmail.d.ts.map +1 -1
  76. package/@types/lib/metadataTypes/TransactionalMessage.d.ts +1 -0
  77. package/@types/lib/metadataTypes/TransactionalMessage.d.ts.map +1 -1
  78. package/@types/lib/metadataTypes/TransactionalPush.d.ts +3 -0
  79. package/@types/lib/metadataTypes/TransactionalPush.d.ts.map +1 -1
  80. package/@types/lib/metadataTypes/TransactionalSMS.d.ts +4 -0
  81. package/@types/lib/metadataTypes/TransactionalSMS.d.ts.map +1 -1
  82. package/@types/lib/metadataTypes/TriggeredSend.d.ts +6 -6
  83. package/@types/lib/metadataTypes/TriggeredSend.d.ts.map +1 -1
  84. package/@types/lib/metadataTypes/User.d.ts +1 -0
  85. package/@types/lib/metadataTypes/User.d.ts.map +1 -1
  86. package/@types/lib/metadataTypes/Verification.d.ts +3 -0
  87. package/@types/lib/metadataTypes/Verification.d.ts.map +1 -1
  88. package/@types/lib/metadataTypes/definitions/Asset.definition.d.ts +24 -14
  89. package/@types/lib/metadataTypes/definitions/AttributeGroup.definition.d.ts +3 -0
  90. package/@types/lib/metadataTypes/definitions/AttributeSet.definition.d.ts +5 -0
  91. package/@types/lib/metadataTypes/definitions/Automation.definition.d.ts +16 -0
  92. package/@types/lib/metadataTypes/definitions/Campaign.definition.d.ts +1 -0
  93. package/@types/lib/metadataTypes/definitions/ContentArea.definition.d.ts +1 -0
  94. package/@types/lib/metadataTypes/definitions/DataExtension.definition.d.ts +1 -0
  95. package/@types/lib/metadataTypes/definitions/DataExtensionField.definition.d.ts +1 -0
  96. package/@types/lib/metadataTypes/definitions/DataExtensionTemplate.definition.d.ts +1 -0
  97. package/@types/lib/metadataTypes/definitions/DataExtract.definition.d.ts +1 -0
  98. package/@types/lib/metadataTypes/definitions/DataExtractType.definition.d.ts +1 -0
  99. package/@types/lib/metadataTypes/definitions/DeliveryProfile.definition.d.ts +1 -0
  100. package/@types/lib/metadataTypes/definitions/Discovery.definition.d.ts +1 -0
  101. package/@types/lib/metadataTypes/definitions/Email.definition.d.ts +1 -0
  102. package/@types/lib/metadataTypes/definitions/EmailSend.definition.d.ts +8 -0
  103. package/@types/lib/metadataTypes/definitions/Event.definition.d.ts +3 -0
  104. package/@types/lib/metadataTypes/definitions/FileLocation.definition.d.ts +1 -0
  105. package/@types/lib/metadataTypes/definitions/FileTransfer.definition.d.ts +1 -0
  106. package/@types/lib/metadataTypes/definitions/Filter.definition.d.ts +1 -0
  107. package/@types/lib/metadataTypes/definitions/Folder.definition.d.ts +1 -0
  108. package/@types/lib/metadataTypes/definitions/ImportFile.definition.d.ts +5 -0
  109. package/@types/lib/metadataTypes/definitions/Journey.definition.d.ts +13 -0
  110. package/@types/lib/metadataTypes/definitions/List.definition.d.ts +1 -0
  111. package/@types/lib/metadataTypes/definitions/MobileCode.definition.d.ts +1 -0
  112. package/@types/lib/metadataTypes/definitions/MobileKeyword.definition.d.ts +9 -0
  113. package/@types/lib/metadataTypes/definitions/MobileMessage.definition.d.ts +4 -0
  114. package/@types/lib/metadataTypes/definitions/Query.definition.d.ts +3 -0
  115. package/@types/lib/metadataTypes/definitions/Role.definition.d.ts +1 -0
  116. package/@types/lib/metadataTypes/definitions/Script.definition.d.ts +1 -0
  117. package/@types/lib/metadataTypes/definitions/SendClassification.definition.d.ts +3 -0
  118. package/@types/lib/metadataTypes/definitions/SenderProfile.definition.d.ts +1 -0
  119. package/@types/lib/metadataTypes/definitions/TransactionalEmail.definition.d.ts +6 -0
  120. package/@types/lib/metadataTypes/definitions/TransactionalMessage.definition.d.ts +1 -0
  121. package/@types/lib/metadataTypes/definitions/TransactionalPush.definition.d.ts +3 -0
  122. package/@types/lib/metadataTypes/definitions/TransactionalSMS.definition.d.ts +4 -0
  123. package/@types/lib/metadataTypes/definitions/TriggeredSend.definition.d.ts +6 -0
  124. package/@types/lib/metadataTypes/definitions/User.definition.d.ts +1 -0
  125. package/@types/lib/metadataTypes/definitions/Verification.definition.d.ts +3 -0
  126. package/@types/lib/util/cache.d.ts +10 -0
  127. package/@types/lib/util/cache.d.ts.map +1 -1
  128. package/@types/lib/util/cli.d.ts +3 -6
  129. package/@types/lib/util/cli.d.ts.map +1 -1
  130. package/@types/lib/util/config.d.ts.map +1 -1
  131. package/@types/lib/util/devops.d.ts.map +1 -1
  132. package/@types/lib/util/init.config.d.ts.map +1 -1
  133. package/@types/lib/util/init.d.ts.map +1 -1
  134. package/@types/lib/util/init.git.d.ts.map +1 -1
  135. package/@types/lib/util/replaceContentBlockReference.d.ts +27 -4
  136. package/@types/lib/util/replaceContentBlockReference.d.ts.map +1 -1
  137. package/@types/lib/util/util.d.ts +32 -3
  138. package/@types/lib/util/util.d.ts.map +1 -1
  139. package/@types/types/mcdev.d.d.ts +87 -0
  140. package/@types/types/mcdev.d.d.ts.map +1 -1
  141. package/boilerplate/files/.vscode/settings.json +1 -0
  142. package/boilerplate/forcedUpdates.json +4 -0
  143. package/boilerplate/gitignore-template +0 -1
  144. package/lib/Builder.js +13 -8
  145. package/lib/Deployer.js +12 -7
  146. package/lib/cli.js +179 -14
  147. package/lib/index.js +538 -205
  148. package/lib/metadataTypes/Asset.js +455 -210
  149. package/lib/metadataTypes/Automation.js +34 -0
  150. package/lib/metadataTypes/DataExtension.js +33 -28
  151. package/lib/metadataTypes/DataExtensionField.js +2 -2
  152. package/lib/metadataTypes/Event.js +28 -2
  153. package/lib/metadataTypes/Folder.js +63 -48
  154. package/lib/metadataTypes/Journey.js +330 -56
  155. package/lib/metadataTypes/MetadataType.js +269 -57
  156. package/lib/metadataTypes/MobileKeyword.js +12 -1
  157. package/lib/metadataTypes/Script.js +4 -3
  158. package/lib/metadataTypes/SenderProfile.js +17 -5
  159. package/lib/metadataTypes/TriggeredSend.js +20 -5
  160. package/lib/metadataTypes/definitions/Asset.definition.js +10 -2
  161. package/lib/metadataTypes/definitions/AttributeGroup.definition.js +1 -0
  162. package/lib/metadataTypes/definitions/AttributeSet.definition.js +11 -0
  163. package/lib/metadataTypes/definitions/Automation.definition.js +9 -0
  164. package/lib/metadataTypes/definitions/Campaign.definition.js +1 -0
  165. package/lib/metadataTypes/definitions/ContentArea.definition.js +1 -0
  166. package/lib/metadataTypes/definitions/DataExtension.definition.js +1 -0
  167. package/lib/metadataTypes/definitions/DataExtensionField.definition.js +1 -0
  168. package/lib/metadataTypes/definitions/DataExtensionTemplate.definition.js +1 -0
  169. package/lib/metadataTypes/definitions/DataExtract.definition.js +2 -1
  170. package/lib/metadataTypes/definitions/DataExtractType.definition.js +1 -0
  171. package/lib/metadataTypes/definitions/DeliveryProfile.definition.js +1 -0
  172. package/lib/metadataTypes/definitions/Discovery.definition.js +1 -0
  173. package/lib/metadataTypes/definitions/Email.definition.js +1 -0
  174. package/lib/metadataTypes/definitions/EmailSend.definition.js +8 -0
  175. package/lib/metadataTypes/definitions/Event.definition.js +1 -0
  176. package/lib/metadataTypes/definitions/FileLocation.definition.js +1 -0
  177. package/lib/metadataTypes/definitions/FileTransfer.definition.js +4 -0
  178. package/lib/metadataTypes/definitions/Filter.definition.js +1 -0
  179. package/lib/metadataTypes/definitions/Folder.definition.js +10 -8
  180. package/lib/metadataTypes/definitions/ImportFile.definition.js +8 -1
  181. package/lib/metadataTypes/definitions/Journey.definition.js +28 -0
  182. package/lib/metadataTypes/definitions/List.definition.js +1 -0
  183. package/lib/metadataTypes/definitions/MobileCode.definition.js +1 -0
  184. package/lib/metadataTypes/definitions/MobileKeyword.definition.js +7 -0
  185. package/lib/metadataTypes/definitions/MobileMessage.definition.js +9 -0
  186. package/lib/metadataTypes/definitions/Query.definition.js +3 -0
  187. package/lib/metadataTypes/definitions/Role.definition.js +1 -0
  188. package/lib/metadataTypes/definitions/Script.definition.js +1 -0
  189. package/lib/metadataTypes/definitions/SendClassification.definition.js +4 -0
  190. package/lib/metadataTypes/definitions/SenderProfile.definition.js +1 -0
  191. package/lib/metadataTypes/definitions/TransactionalEmail.definition.js +7 -0
  192. package/lib/metadataTypes/definitions/TransactionalMessage.definition.js +1 -0
  193. package/lib/metadataTypes/definitions/TransactionalPush.definition.js +3 -0
  194. package/lib/metadataTypes/definitions/TransactionalSMS.definition.js +4 -0
  195. package/lib/metadataTypes/definitions/TriggeredSend.definition.js +10 -3
  196. package/lib/metadataTypes/definitions/User.definition.js +3 -0
  197. package/lib/metadataTypes/definitions/Verification.definition.js +1 -0
  198. package/lib/util/cache.js +35 -0
  199. package/lib/util/cli.js +96 -139
  200. package/lib/util/config.js +11 -19
  201. package/lib/util/devops.js +41 -41
  202. package/lib/util/init.config.js +6 -10
  203. package/lib/util/init.git.js +43 -57
  204. package/lib/util/init.js +35 -59
  205. package/lib/util/replaceContentBlockReference.js +107 -60
  206. package/lib/util/util.js +90 -4
  207. package/package.json +14 -13
  208. package/test/general.test.js +1117 -163
  209. package/test/mockRoot/.mcdevrc.json +1 -1
  210. package/test/mockRoot/deploy/testInstance/testBU/event/testNew_event_withExistingDE.event-meta.json +1 -0
  211. package/test/mockRoot/deploy/testInstance/testBU/event/testNew_event_withSchema.event-meta.json +1 -0
  212. package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/4912312345678.TESTNEW_KEYWORD.mobileKeyword-meta.json +1 -0
  213. package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/4912312345678.TESTNEW_KEYWORD_BLOCKED.mobileKeyword-meta.json +1 -0
  214. package/test/resourceFactory.js +43 -11
  215. package/test/resources/1111111/dataFolder/retrieve-ContentTypeINshared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml +364 -0
  216. package/test/resources/9999999/asset/{block-1157-retrieve-expected.html → build-asset_htmlblock-expected.html} +1 -1
  217. package/test/resources/9999999/asset/build-asset_htmlblock-expected.json +29 -0
  218. package/test/resources/9999999/asset/build-templatebasedemail-expected.json +65 -0
  219. package/test/resources/9999999/asset/resolveId-1295064-noPath-expected.json +3 -3
  220. package/test/resources/9999999/asset/resolveId-1295064-withPath-expected.json +3 -3
  221. package/test/resources/9999999/asset/retrieve-templatebasedemail-expected.json +65 -0
  222. package/test/resources/9999999/asset/template-emailTemplate-expected.json +20 -0
  223. package/test/resources/9999999/asset/template-templatebasedemail-expected.json +65 -0
  224. package/test/resources/9999999/asset/template-testExisting_asset_htmlblock-expected.json +29 -0
  225. package/test/resources/9999999/asset/testExisting_asset_htmlblock-retrieve-expected.html +23 -0
  226. package/test/resources/9999999/asset/{block-1157-retrieve-expected.json → testExisting_asset_htmlblock-retrieve-expected.json} +3 -3
  227. package/test/resources/9999999/asset/testExisting_asset_message-html-rcb-key-expected.html +6 -6
  228. package/test/resources/9999999/asset/testExisting_asset_message-preheader-rcb-id-expected.amp +1 -1
  229. package/test/resources/9999999/asset/testExisting_asset_message-preheader-rcb-key-expected.amp +4 -4
  230. package/test/resources/9999999/asset/testExisting_asset_message-preheader-rcb-name-expected.amp +1 -1
  231. package/test/resources/9999999/asset/testExisting_asset_message-text-rcb-key-expected.amp +4 -4
  232. package/test/resources/9999999/asset/v1/content/assets/1295064/get-response.json +4 -4
  233. package/test/resources/9999999/asset/v1/content/assets/1295065/get-response.json +60 -0
  234. package/test/resources/9999999/asset/v1/content/assets/1295066/get-response.json +60 -0
  235. package/test/resources/9999999/asset/v1/content/assets/5289/get-response.json +75 -0
  236. package/test/resources/9999999/asset/v1/content/assets/808714/get-response.json +3 -3
  237. package/test/resources/9999999/asset/v1/content/assets/950143/get-response.json +97 -0
  238. package/test/resources/9999999/asset/v1/content/assets/get-response-customerKey=testExisting_asset.json +1 -1
  239. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN195,196,197,198,199,200,201,202,203,210,211,212,213,3.json +78 -2
  240. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN205,206,230,232,1,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,14,193,194,15,195,196,197,198,199,200,201,202,203,210,211,212,213,3,207,208,209,5,214,4,215,216.json +370 -0
  241. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN205,206,230,232,1,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,14,193,194,15,195,196,197,198,199,200,201,202,203,210,211,212,213,3,215,216,217,218,219,220,221,222.json +243 -0
  242. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN205,206,230,232,1,207,208,209,5.json +229 -0
  243. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN205,206,230,232,1.json +98 -1
  244. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN217,218,219,220,221,222,223,224,225,226,227,228.json +7 -0
  245. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN223,224,225,226,227,228,214,4.json +35 -0
  246. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN223,224,225,226,227,228.json +7 -0
  247. package/test/resources/9999999/asset/v1/content/assets/query/{post-response-customerKey=mcdev-issue-1157.json → post-response-customerKey=testExisting_asset_htmlblock.json} +2 -2
  248. package/test/resources/9999999/automation/v1/queries/get-response-Name=testExisting_query.json +24 -0
  249. package/test/resources/9999999/automation/v1/scripts/get-response-name=testExisting_script.json +17 -0
  250. package/test/resources/9999999/automation/v1/scripts/get-response.json +2 -2
  251. package/test/resources/9999999/dataFolder/retrieve-ContentType=asset-shared-QAA-response.xml +70 -0
  252. package/test/resources/9999999/dataFolder/retrieve-ContentType=asset-shared-response.xml +70 -0
  253. package/test/resources/9999999/dataFolder/retrieve-ContentType=journey-response.xml +48 -0
  254. package/test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-sha,automatio,dataexten,hidden,journey,list,mysubs,publicati,queryacti,salesforc,shared_da,shared_da,shared_sa,ssjsactiv,synchroni,triggered,triggered,useriniti-response.xml +519 -0
  255. package/test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-sha,dataexten,salesforc,shared_da,shared_da,shared_sa,synchroni,automatio,useriniti,journey,mysubs,list,publicati,queryacti,ssjsactiv,triggered,triggered-response.xml +519 -0
  256. package/test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared,journey-response.xml +92 -0
  257. package/test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml +115 -0
  258. package/test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared,ssjsactivity-response.xml +92 -0
  259. package/test/resources/9999999/dataFolder/retrieve-ContentTypeINasset,asset-shared-QAA-response.xml +70 -0
  260. package/test/resources/9999999/dataFolder/retrieve-ContentTypeINasset-shared,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml +431 -0
  261. package/test/resources/9999999/dataFolder/retrieve-ContentTypeINautomations,queryactivity-response.xml +70 -0
  262. package/test/resources/9999999/dataFolder/{retrieve-response.xml → retrieve-ContentTypeINdataextension,hidden,queryactivity,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml} +32 -119
  263. package/test/resources/9999999/dataFolder/retrieve-ContentTypeINdataextension,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml +117 -0
  264. package/test/resources/9999999/dataFolder/retrieve-ContentTypeINhidden,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml +46 -0
  265. package/test/resources/9999999/dataFolder/retrieve-ContentTypeINshared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-QAA-response.xml +251 -0
  266. package/test/resources/9999999/dataFolder/retrieve-response-.xml +519 -0
  267. package/test/resources/9999999/event/build-expected.json +0 -1
  268. package/test/resources/9999999/event/get-expected.json +0 -1
  269. package/test/resources/9999999/event/post_withExistingDE-callout-expected.json +3 -0
  270. package/test/resources/9999999/event/post_withExistingDE-expected.json +2 -0
  271. package/test/resources/9999999/event/post_withSchema-callout-expected.json +3 -0
  272. package/test/resources/9999999/event/post_withSchema-expected.json +2 -0
  273. package/test/resources/9999999/event/put-callout-expected.json +3 -1
  274. package/test/resources/9999999/event/put-expected.json +2 -2
  275. package/test/resources/9999999/event/template-expected.json +0 -1
  276. package/test/resources/9999999/interaction/v1/eventDefinitions/key_testExisting_event/put-response.json +2 -1
  277. package/test/resources/9999999/interaction/v1/eventDefinitions/post_withExistingDE-response.json +2 -0
  278. package/test/resources/9999999/interaction/v1/eventDefinitions/post_withSchema-response.json +2 -0
  279. package/test/resources/9999999/interaction/v1/interactions/3c3f4112-9b43-43ca-8a89-aa0375b2c1a2/get-response.json +4 -4
  280. package/test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_Quicksend/get-response.json +4 -4
  281. package/test/resources/9999999/interaction/v1/interactions/publishAsync/3c3f4112-9b43-43ca-8a89-aa0375b2c1a2/post-response.json +4 -0
  282. package/test/resources/9999999/interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-failed.json +34 -0
  283. package/test/resources/9999999/interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-success.json +5 -0
  284. package/test/resources/9999999/interaction/v1/interactions/publishStatus/45f06c0a-3ed2-48b2-a6a8-b5119253f01c/get-response-successWarnings.json +36 -0
  285. package/test/resources/9999999/journey/build-expected.json +5 -5
  286. package/test/resources/9999999/journey/get-multistep-expected.json +1 -1
  287. package/test/resources/9999999/journey/get-quicksend-expected.json +5 -5
  288. package/test/resources/9999999/journey/get-quicksend-rcb-id-expected.json +1 -1
  289. package/test/resources/9999999/journey/get-quicksend-rcb-key-expected.json +7 -7
  290. package/test/resources/9999999/journey/get-quicksend-rcb-name-expected.json +1 -1
  291. package/test/resources/9999999/journey/post-expected.json +1 -1
  292. package/test/resources/9999999/journey/publish-callout-expected.json +1 -0
  293. package/test/resources/9999999/journey/put-expected.json +1 -1
  294. package/test/resources/9999999/journey/template-expected.json +5 -5
  295. package/test/resources/9999999/mobileKeyword/build-expected.json +1 -0
  296. package/test/resources/9999999/mobileKeyword/get-expected.json +1 -0
  297. package/test/resources/9999999/mobileKeyword/post-create-expected.json +1 -0
  298. package/test/resources/9999999/mobileKeyword/template-expected.json +1 -0
  299. package/test/resources/{1111111/accountUser/retrieve-CustomerKey=testExisting_userANDActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml → 9999999/queryDefinition/retrieve-CustomerKey=badANDStatus=Active-response.xml} +10 -11
  300. package/test/resources/9999999/script/get_ampincluded-rcb-key-expected.html +2 -2
  301. package/test/resources/9999999/script/get_ampscript-expected.html +1 -0
  302. package/test/resources/9999999/script/get_ampscript-rcb-id-expected.html +1 -0
  303. package/test/resources/9999999/script/get_ampscript-rcb-key-expected.html +3 -2
  304. package/test/resources/9999999/script/get_ampscript-rcb-name-expected.html +3 -0
  305. package/test/resources/9999999/script/get_mixed-expected.html +2 -2
  306. package/test/resources/9999999/script/get_mixed-rcb-key-expected.html +2 -2
  307. package/test/resources/9999999/senderProfile/get-rcb-key-expected.json +4 -4
  308. package/test/resources/9999999/senderProfile/retrieve-response.xml +1 -1
  309. package/test/resources/9999999/triggeredSend/get-rcb-key-expected.json +4 -4
  310. package/test/resources/9999999/triggeredSendDefinition/retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml +1 -1
  311. package/test/type.asset.test.js +189 -39
  312. package/test/type.automation.test.js +134 -58
  313. package/test/type.dataExtract.test.js +4 -4
  314. package/test/type.emailSend.test.js +3 -3
  315. package/test/type.event.test.js +0 -2
  316. package/test/type.journey.test.js +322 -9
  317. package/test/type.query.test.js +33 -29
  318. package/test/type.script.test.js +61 -11
  319. package/test/type.senderProfile.test.js +36 -3
  320. package/test/type.transactionalEmail.test.js +3 -3
  321. package/test/type.triggeredSend.test.js +75 -6
  322. package/test/utils.js +13 -3
  323. package/types/mcdev.d.js +27 -1
  324. /package/test/resources/1111111/accountUser/{retrieve-ActiveFlag=falseANDCustomerKey=testExisting_userANDEmaillike@-response.xml → retrieve-ActiveFlag=falseANDCustomerKey=testExisting_userANDEmaillike@-QAA-response.xml} +0 -0
  325. /package/test/resources/1111111/accountUser/{retrieve-ActiveFlag=falseANDEmaillike@-response.xml → retrieve-ActiveFlag=falseANDEmaillike@-QAA-response.xml} +0 -0
  326. /package/test/resources/1111111/accountUser/{retrieve-ActiveFlag=trueANDCustomerKey=testExisting_userANDEmaillike@-response.xml → retrieve-ActiveFlag=trueANDCustomerKey=testExisting_userANDEmaillike@-QAA-response.xml} +0 -0
  327. /package/test/resources/1111111/accountUser/{retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml → retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-QAA-response.xml} +0 -0
  328. /package/test/resources/1111111/accountUser/{retrieve-ActiveFlag=trueANDEmaillike@-response.xml → retrieve-ActiveFlag=trueANDEmaillike@-QAA-response.xml} +0 -0
  329. /package/test/resources/1111111/businessUnit/{retrieve-ID=1111111-response.xml → retrieve-ID=1111111-QAA-response.xml} +0 -0
  330. /package/test/resources/1111111/dataFolder/{retrieve-ContentType=synchronizeddataextensionORContentType=shared_salesforcedataextensionORContentType=shared_dataextensionORContentType=shared_dataORContentType=salesforcedataextensionORContentType=dataextensionORContentType=hidden-response.xml → retrieve-ContentTypeINdataextension,hidden,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml} +0 -0
  331. /package/test/resources/1111111/dataFolder/{retrieve-response.xml → retrieve-response-.xml} +0 -0
  332. /package/test/resources/9999999/dataFolder/{retrieve-ContentType=asset-sharedORContentType=asset-response.xml → retrieve-ContentTypeINasset,asset-shared-response.xml} +0 -0
  333. /package/test/resources/9999999/dataFolder/{retrieve-ContentType=contextual_suppression_listORContentType=publicationORContentType=suppression_listORContentType=mysubsORContentType=list-response.xml → retrieve-ContentTypeINcontextual_suppression_list,list,mysubs,publication,suppression_list-response.xml} +0 -0
  334. /package/test/resources/9999999/dataFolder/{retrieve-ContentType=synchronizeddataextensionORContentType=shared_salesforcedataextensionORContentType=shared_dataextensionORContentType=shared_dataORContentType=salesforcedataextensionORContentType=dataextensionORContentType=hidden-response.xml → retrieve-ContentTypeINdataextension,hidden,salesforcedataextension,shared_data,shared_dataextension,shared_salesforcedataextension,synchronizeddataextension-response.xml} +0 -0
  335. /package/test/resources/9999999/dataFolder/{retrieve-ContentType=triggered_send_journeybuilderORContentType=triggered_sendORContentType=hidden-response.xml → retrieve-ContentTypeINhidden,triggered_send,triggered_send_journeybuilder-response.xml} +0 -0
package/lib/index.js CHANGED
@@ -17,6 +17,8 @@ import Retriever from './Retriever.js';
17
17
  import cache from './util/cache.js';
18
18
  import ReplaceContentBlockReference from './util/replaceContentBlockReference.js';
19
19
 
20
+ import { confirm } from '@inquirer/prompts';
21
+
20
22
  /**
21
23
  * @typedef {import('../types/mcdev.d.js').BuObject} BuObject
22
24
  * @typedef {import('../types/mcdev.d.js').CodeExtract} CodeExtract
@@ -79,28 +81,34 @@ class Mcdev {
79
81
  static setOptions(argv) {
80
82
  const knownOptions = [
81
83
  'api',
82
- 'keySuffix',
83
84
  'changeKeyField',
84
85
  'changeKeyValue',
85
86
  'commitHistory',
87
+ 'dependencies',
86
88
  'errorLog',
87
89
  'execute',
88
90
  'filter',
89
91
  'fixShared',
90
92
  'fromRetrieve',
91
93
  'json',
94
+ 'keySuffix',
92
95
  'like',
93
96
  'noLogColors',
94
97
  'noLogFile',
95
- 'noMidSuffix',
98
+ 'noUpdate',
99
+ 'autoMidSuffix',
100
+ 'publish',
96
101
  'referenceFrom',
97
102
  'referenceTo',
98
103
  'refresh',
99
- 'skipDeploy',
100
- 'skipRetrieve',
104
+ 'retrieve',
101
105
  'schedule',
106
+ 'skipDeploy',
102
107
  'skipInteraction',
108
+ 'skipRetrieve',
109
+ 'skipStatusCheck',
103
110
  '_runningTest',
111
+ '_welcomeMessageShown',
104
112
  ];
105
113
  for (const option of knownOptions) {
106
114
  if (argv[option] !== undefined) {
@@ -139,16 +147,20 @@ class Mcdev {
139
147
  return null;
140
148
  }
141
149
 
142
- return argv.filter
143
- ? // get source market and source BU from config
144
- DevOps.getDeltaList(properties, argv.range, true, argv.filter, argv.commitHistory)
145
- : // If no custom filter was provided, use deployment marketLists & templating
146
- DevOps.buildDeltaDefinitions(
147
- properties,
148
- argv.range,
149
- argv.diffArr,
150
- argv.commitHistory
151
- );
150
+ try {
151
+ return await (argv.filter
152
+ ? // get source market and source BU from config
153
+ DevOps.getDeltaList(properties, argv.range, true, argv.filter, argv.commitHistory)
154
+ : // If no custom filter was provided, use deployment marketLists & templating
155
+ DevOps.buildDeltaDefinitions(
156
+ properties,
157
+ argv.range,
158
+ argv.diffArr,
159
+ argv.commitHistory
160
+ ));
161
+ } catch (ex) {
162
+ Util.logger.error(ex.message);
163
+ }
152
164
  }
153
165
 
154
166
  /**
@@ -189,6 +201,12 @@ class Mcdev {
189
201
  * helper to show an off-the-logs message to users
190
202
  */
191
203
  static #welcomeMessage() {
204
+ if (Util.OPTIONS._welcomeMessageShown) {
205
+ // ensure we don't spam the user in case methods are called multiple times
206
+ return;
207
+ }
208
+ Util.OPTIONS._welcomeMessageShown = true;
209
+
192
210
  const color = Util.isRunViaVSCodeExtension
193
211
  ? { reset: '', bgWhite: '', fgBlue: '' }
194
212
  : Util.color;
@@ -482,7 +500,11 @@ class Mcdev {
482
500
  Util.startLogger();
483
501
  Util.logger.info('mcdev:: Setting up project');
484
502
  const properties = await config.getProperties(!!credentialsName, true);
485
- await Init.initProject(properties, credentialsName);
503
+ try {
504
+ await Init.initProject(properties, credentialsName);
505
+ } catch (ex) {
506
+ Util.logger.error(ex.message);
507
+ }
486
508
  }
487
509
  /**
488
510
  * Clones an existing project from git repository and installs it
@@ -492,7 +514,11 @@ class Mcdev {
492
514
  static async joinProject() {
493
515
  Util.startLogger();
494
516
  Util.logger.info('mcdev:: Joining an existing project');
495
- await Init.joinProject();
517
+ try {
518
+ await Init.joinProject();
519
+ } catch (ex) {
520
+ Util.logger.error(ex.message);
521
+ }
496
522
  }
497
523
 
498
524
  /**
@@ -706,6 +732,54 @@ class Mcdev {
706
732
  }
707
733
  }
708
734
  }
735
+ /**
736
+ * method for contributors to get details on SOAP objects
737
+ *
738
+ * @param {string} type references credentials from properties.json
739
+ * @param {string} [businessUnit] defaults to first credential's ParentBU
740
+ * @returns {Promise.<void>} -
741
+ */
742
+ static async describeSoap(type, businessUnit) {
743
+ Util.startLogger();
744
+ Util.logger.info('mcdev:: describe SOAP');
745
+ const properties = await config.getProperties();
746
+ if (!(await config.checkProperties(properties))) {
747
+ return null;
748
+ }
749
+ const credential = Object.keys(properties.credentials)[0];
750
+ businessUnit ||=
751
+ credential + '/' + Object.keys(properties.credentials[credential].businessUnits)[0];
752
+ const buObject = await Cli.getCredentialObject(properties, businessUnit);
753
+ if (!buObject) {
754
+ return;
755
+ }
756
+ try {
757
+ const client = auth.getSDK(buObject);
758
+ const response = await client.soap.describe(type);
759
+ if (response?.ObjectDefinition?.Properties) {
760
+ Util.logger.info(
761
+ `Properties for SOAP object ${response.ObjectDefinition.ObjectType}:`
762
+ );
763
+ const properties = response.ObjectDefinition.Properties.map((prop) => {
764
+ delete prop.PartnerKey;
765
+ delete prop.ObjectID;
766
+ return prop;
767
+ });
768
+ if (Util.OPTIONS.json) {
769
+ console.log(JSON.stringify(properties, null, 2)); // eslint-disable-line no-console
770
+ } else {
771
+ console.table(properties); // eslint-disable-line no-console
772
+ }
773
+ return properties;
774
+ } else {
775
+ throw new Error(
776
+ `Soap object ${type} not found. Please check the spelling and retry`
777
+ );
778
+ }
779
+ } catch (ex) {
780
+ Util.logger.error(ex.message);
781
+ }
782
+ }
709
783
 
710
784
  /**
711
785
  * Converts metadata to legacy format. Output is saved in 'converted' directory
@@ -821,6 +895,172 @@ class Mcdev {
821
895
  }
822
896
  }
823
897
  }
898
+ /**
899
+ * @param {string} businessUnit references credentials from properties.json
900
+ * @param {TypeKeyCombo} selectedTypes limit retrieval to given metadata type
901
+ * @returns {Promise.<TypeKeyCombo>} selected types including dependencies
902
+ */
903
+ static async addDependentCbReferences(businessUnit, selectedTypes) {
904
+ if (!Util.OPTIONS.dependencies) {
905
+ return;
906
+ }
907
+ const initialAssetNumber = selectedTypes['asset']?.length || 0;
908
+ const properties = await config.getProperties();
909
+ const buObject = await Cli.getCredentialObject(properties, businessUnit);
910
+ Util.logger.info(
911
+ 'Searching for additional dependencies that were linked via ContentBlockByKey, ContentBlockByName and ContentBlockById'
912
+ );
913
+
914
+ await ReplaceContentBlockReference.createCacheMap(properties, buObject, true);
915
+
916
+ // because we re-use the replaceReference logic here we need to manually set this value
917
+ /** @type {ContentBlockConversionTypes[]} */
918
+ Util.OPTIONS.referenceFrom = ['key', 'name', 'id'];
919
+ /** @type {ContentBlockConversionTypes} */
920
+ Util.OPTIONS.referenceTo = 'key';
921
+
922
+ /** @type {Set.<string>} */
923
+ const assetDependencies = new Set();
924
+ const retrieveDir = File.filterIllegalPathChars(
925
+ File.normalizePath([
926
+ properties.directories.retrieve,
927
+ buObject.credential,
928
+ buObject.businessUnit,
929
+ ])
930
+ );
931
+ // check all non-asset types for dependencies
932
+ for (const depType in selectedTypes) {
933
+ if (
934
+ !Object.prototype.hasOwnProperty.call(
935
+ MetadataTypeInfo[depType],
936
+ 'replaceCbReference'
937
+ ) ||
938
+ depType === 'asset'
939
+ ) {
940
+ continue;
941
+ }
942
+ MetadataTypeInfo[depType].properties = properties;
943
+ MetadataTypeInfo[depType].buObject = buObject;
944
+ await MetadataTypeInfo[depType].getCbReferenceKeys(
945
+ selectedTypes[depType],
946
+ retrieveDir,
947
+ assetDependencies
948
+ );
949
+ }
950
+ // add dependencies to selectedTypes
951
+ if (assetDependencies.size) {
952
+ const depType = 'asset';
953
+ if (selectedTypes[depType]) {
954
+ selectedTypes[depType].push(...assetDependencies);
955
+ } else {
956
+ selectedTypes[depType] = [...assetDependencies];
957
+ }
958
+ // remove duplicates in main object after adding dependencies
959
+ selectedTypes[depType] = [...new Set(selectedTypes[depType])];
960
+ }
961
+
962
+ // check all assets for dependencies recursively
963
+ if (selectedTypes.asset?.length) {
964
+ const depType = 'asset';
965
+ const Asset = MetadataTypeInfo[depType];
966
+ Asset.properties = properties;
967
+ Asset.buObject = buObject;
968
+ const additionalAssetDependencies = [
969
+ ...(await Asset.getCbReferenceKeys(
970
+ selectedTypes[depType],
971
+ retrieveDir,
972
+ new Set(selectedTypes[depType])
973
+ )),
974
+ ];
975
+ if (additionalAssetDependencies.length) {
976
+ Util.logger.info(
977
+ `Found ${additionalAssetDependencies.length - initialAssetNumber} additional assets linked via ContentBlockByX.`
978
+ );
979
+ }
980
+ // reset cache in case this is used progammatically somehow
981
+ Asset.getJsonFromFSCache = null;
982
+
983
+ // remove duplicates in main object after adding dependencies
984
+ selectedTypes[depType] = [...new Set(selectedTypes[depType])];
985
+ }
986
+
987
+ return selectedTypes;
988
+ }
989
+
990
+ /**
991
+ *
992
+ * @param {string} businessUnit references credentials from properties.json
993
+ * @param {TypeKeyCombo} selectedTypes limit retrieval to given metadata type
994
+ * @returns {Promise.<TypeKeyCombo>} dependencies
995
+ */
996
+ static async addDependencies(businessUnit, selectedTypes) {
997
+ if (!Util.OPTIONS.dependencies) {
998
+ return;
999
+ }
1000
+ Util.logger.info(
1001
+ 'You might see warnings about items not being found if you have not re-retrieved everything lately.'
1002
+ );
1003
+
1004
+ // try re-retrieve without passing selectedTypes to ensure we find all dependencies
1005
+ await this._reRetrieve(businessUnit, true);
1006
+
1007
+ Util.logger.info(
1008
+ 'Searching for selected items and their dependencies in your project folder'
1009
+ );
1010
+ /** @type {TypeKeyCombo} */
1011
+ const dependencies = {};
1012
+ /** @type {TypeKeyCombo} */
1013
+ const notFoundList = {};
1014
+ const initiallySelectedTypesArr = Object.keys(selectedTypes);
1015
+
1016
+ const properties = await config.getProperties();
1017
+ const buObject = await Cli.getCredentialObject(properties, businessUnit);
1018
+ for (const type of initiallySelectedTypesArr) {
1019
+ MetadataTypeInfo[type].properties = properties;
1020
+ MetadataTypeInfo[type].buObject = buObject;
1021
+ await MetadataTypeInfo[type].getDependentFiles(
1022
+ selectedTypes[type],
1023
+ dependencies,
1024
+ notFoundList,
1025
+ true
1026
+ );
1027
+ }
1028
+ if (Util.getTypeKeyCount(notFoundList)) {
1029
+ // if we have missing items, we need to retrieve them
1030
+ Util.logger.warn(
1031
+ `We recommend you retrieve the missing items with the following command and then re-run buildDefinition:`
1032
+ );
1033
+ Util.logger.warn(
1034
+ ` mcdev retrieve ${businessUnit} ${Util.convertTypeKeyToCli(notFoundList)}`
1035
+ );
1036
+ }
1037
+
1038
+ // remove duplicates & empty types
1039
+ for (const type in dependencies) {
1040
+ if (dependencies[type].length) {
1041
+ dependencies[type] = [...new Set(dependencies[type])];
1042
+ } else {
1043
+ delete dependencies[type];
1044
+ }
1045
+ }
1046
+
1047
+ // add dependencies to selectedTypes
1048
+ if (Object.keys(dependencies).length) {
1049
+ Util.logger.info(
1050
+ `Found ${Util.getTypeKeyCount(dependencies)} items across ${Object.keys(dependencies).length} types.`
1051
+ );
1052
+ for (const type in dependencies) {
1053
+ if (selectedTypes[type]) {
1054
+ selectedTypes[type].push(...dependencies[type]);
1055
+ } else {
1056
+ selectedTypes[type] = dependencies[type];
1057
+ }
1058
+ // remove duplicates in main object after adding dependencies
1059
+ selectedTypes[type] = [...new Set(selectedTypes[type])];
1060
+ }
1061
+ }
1062
+ return dependencies;
1063
+ }
824
1064
 
825
1065
  /**
826
1066
  * Build a template based on a list of metadata files in the retrieve folder.
@@ -847,6 +1087,20 @@ class Mcdev {
847
1087
  );
848
1088
  return;
849
1089
  }
1090
+ const properties = await config.getProperties();
1091
+ if (!Util.checkMarket(marketTemplate, properties)) {
1092
+ return;
1093
+ }
1094
+ // check if types are valid
1095
+ for (const type of Object.keys(typeKeyCombo)) {
1096
+ if (!Util._isValidType(type)) {
1097
+ return;
1098
+ }
1099
+ if (!Array.isArray(typeKeyCombo[type])) {
1100
+ // we need an array of keys here
1101
+ return;
1102
+ }
1103
+ }
850
1104
 
851
1105
  Util.logger.info('mcdev:: Build Template & Build Definition');
852
1106
  await this.buildTemplate(businessUnitTemplate, typeKeyCombo, null, marketTemplate);
@@ -864,37 +1118,86 @@ class Mcdev {
864
1118
  * @returns {Promise.<MultiMetadataTypeList>} -
865
1119
  */
866
1120
  static async buildTemplate(businessUnit, selectedTypes, keyArr, market) {
1121
+ this.#welcomeMessage();
1122
+
867
1123
  Util.startLogger();
868
1124
  Util.logger.info('mcdev:: Build Template from retrieved files');
869
- let selectedTypesArr;
1125
+ const properties = await config.getProperties();
1126
+ if (!Util.checkMarket(market, properties)) {
1127
+ return;
1128
+ }
870
1129
  if ('string' === typeof selectedTypes) {
871
- selectedTypesArr = [selectedTypes];
872
- } else {
873
- selectedTypesArr = Object.keys(selectedTypes);
874
- // check if types are valid
875
- for (const selectedType of selectedTypesArr) {
876
- if (!Util._isValidType(selectedType)) {
877
- return;
878
- }
879
- if (!Array.isArray(selectedTypes[selectedType])) {
880
- // we need an array of keys here
881
- return;
882
- }
1130
+ // ensure we have TypeKeyCombo here
1131
+ selectedTypes = Util.createTypeKeyCombo(selectedTypes, keyArr);
1132
+ }
1133
+ // check if types are valid
1134
+ for (const type of Object.keys(selectedTypes)) {
1135
+ if (!Util._isValidType(type)) {
1136
+ return;
1137
+ }
1138
+ if (!Array.isArray(selectedTypes[type])) {
1139
+ // we need an array of keys here
1140
+ return;
883
1141
  }
884
1142
  }
1143
+
1144
+ if (!Util.OPTIONS.dependencies) {
1145
+ await this._reRetrieve(businessUnit, false, selectedTypes);
1146
+ }
1147
+
1148
+ // if dependencies are enabled, we need to search for them and add them to our
1149
+ await this.addDependencies(businessUnit, selectedTypes);
1150
+ await this.addDependentCbReferences(businessUnit, selectedTypes);
1151
+
885
1152
  /** @type {MultiMetadataTypeList} */
886
1153
  const returnObj = {};
887
- for (const selectedType of selectedTypesArr) {
1154
+ for (const type of Object.keys(selectedTypes)) {
888
1155
  const result = await Builder.buildTemplate(
889
1156
  businessUnit,
890
- selectedType,
891
- 'string' === typeof selectedTypes ? keyArr : selectedTypes[selectedType],
1157
+ type,
1158
+ selectedTypes[type],
892
1159
  market
893
1160
  );
894
- returnObj[selectedType] = result[selectedType];
1161
+ returnObj[type] = result[type];
1162
+ }
1163
+ Util.logger.info(`Templated ${Util.getTypeKeyCount(returnObj)} items`);
1164
+ if (Util.OPTIONS.dependencies) {
1165
+ Util.logger.info(
1166
+ `You can now run buildDefinition to create the deployment package. Don't forget to adjust the BU and market!`
1167
+ );
1168
+ Util.logger.info(
1169
+ ` mcdev bd ${businessUnit} ${Util.convertTypeKeyToCli(selectedTypes)} --market ${market}`
1170
+ );
895
1171
  }
896
1172
  return returnObj;
897
1173
  }
1174
+
1175
+ /**
1176
+ * Build a specific metadata file based on a template.
1177
+ *
1178
+ * @param {string} businessUnit references credentials from properties.json
1179
+ * @param {boolean} [alwaysAsk] by default this code only runs if --retrieve is set; this flag allows to always ask
1180
+ * @param {TypeKeyCombo} [selectedTypes] limit retrieval to given metadata type
1181
+ * @returns {Promise.<void>} -
1182
+ */
1183
+ static async _reRetrieve(businessUnit, alwaysAsk = false, selectedTypes) {
1184
+ let runRetrieveNow;
1185
+ if (!Util.OPTIONS.skipInteraction && !Util.OPTIONS.retrieve && alwaysAsk) {
1186
+ runRetrieveNow = await confirm({
1187
+ message: `Do you want to re-retrieve ${selectedTypes ? Util.convertTypeKeyToString(selectedTypes) : 'all metadata'} for ${businessUnit} now?`,
1188
+ default: false,
1189
+ });
1190
+ }
1191
+ if (runRetrieveNow || Util.OPTIONS.retrieve) {
1192
+ Util.logger.info(
1193
+ `Re-retrieving ${businessUnit}: ${selectedTypes ? Util.convertTypeKeyToString(selectedTypes) : 'all metadata'}`
1194
+ );
1195
+ // we need to work with a clone here because retrieve() modifies the object passed in as 2nd parameter
1196
+ const retrieveTypes = structuredClone(selectedTypes);
1197
+ await this.retrieve(businessUnit, retrieveTypes);
1198
+ }
1199
+ }
1200
+
898
1201
  /**
899
1202
  * Build a specific metadata file based on a template.
900
1203
  *
@@ -905,34 +1208,39 @@ class Mcdev {
905
1208
  * @returns {Promise.<MultiMetadataTypeList>} -
906
1209
  */
907
1210
  static async buildDefinition(businessUnit, selectedTypes, nameArr, market) {
1211
+ this.#welcomeMessage();
1212
+
908
1213
  Util.startLogger();
909
1214
  Util.logger.info('mcdev:: Build Definition from Template');
910
- let selectedTypesArr;
1215
+ const properties = await config.getProperties();
1216
+ if (!Util.checkMarket(market, properties)) {
1217
+ return;
1218
+ }
911
1219
  if ('string' === typeof selectedTypes) {
912
- selectedTypesArr = [selectedTypes];
913
- } else {
914
- selectedTypesArr = Object.keys(selectedTypes);
915
- // check if types are valid
916
- for (const selectedType of selectedTypesArr) {
917
- if (!Util._isValidType(selectedType)) {
918
- return;
919
- }
920
- if (!Array.isArray(selectedTypes[selectedType])) {
921
- // we need an array of keys here
922
- return;
923
- }
1220
+ // ensure we have TypeKeyCombo here
1221
+ selectedTypes = Util.createTypeKeyCombo(selectedTypes, nameArr);
1222
+ }
1223
+
1224
+ // check if types are valid
1225
+ for (const type of Object.keys(selectedTypes)) {
1226
+ if (!Util._isValidType(type)) {
1227
+ return;
1228
+ }
1229
+ if (!Array.isArray(selectedTypes[type])) {
1230
+ // we need an array of keys here
1231
+ return;
924
1232
  }
925
1233
  }
926
1234
  /** @type {MultiMetadataTypeList} */
927
1235
  const returnObj = {};
928
- for (const selectedType of selectedTypesArr) {
1236
+ for (const type of Object.keys(selectedTypes)) {
929
1237
  const result = await Builder.buildDefinition(
930
1238
  businessUnit,
931
- selectedType,
932
- 'string' === typeof selectedTypes ? nameArr : selectedTypes[selectedType],
1239
+ type,
1240
+ selectedTypes[type],
933
1241
  market
934
1242
  );
935
- returnObj[selectedType] = result[selectedType];
1243
+ returnObj[type] = result[type];
936
1244
  }
937
1245
  return returnObj;
938
1246
  }
@@ -946,6 +1254,8 @@ class Mcdev {
946
1254
  * @returns {Promise.<object>} -
947
1255
  */
948
1256
  static async buildDefinitionBulk(listName, selectedTypes, nameArr) {
1257
+ this.#welcomeMessage();
1258
+
949
1259
  Util.startLogger();
950
1260
  Util.logger.info('mcdev:: Build Definition from Template Bulk');
951
1261
  let selectedTypesArr;
@@ -1011,35 +1321,46 @@ class Mcdev {
1011
1321
  * Schedule an item (shortcut for execute --schedule)
1012
1322
  *
1013
1323
  * @param {string} businessUnit name of BU
1014
- * @param {string} [selectedType] limit to given metadata types
1324
+ * @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types
1015
1325
  * @param {string[]} [keys] customerkey of the metadata
1016
- * @returns {Promise.<Object.<string, string[]>>} key: business unit name, value: list of scheduled item keys
1326
+ * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
1017
1327
  */
1018
- static async schedule(businessUnit, selectedType, keys) {
1328
+ static async schedule(businessUnit, selectedTypes, keys) {
1019
1329
  this.setOptions({ schedule: true });
1020
- return this.#runMethod('execute', businessUnit, selectedType, keys);
1330
+ return this.#runMethod('execute', businessUnit, selectedTypes, keys);
1331
+ }
1332
+ /**
1333
+ * Publish an item
1334
+ *
1335
+ * @param {string} businessUnit name of BU
1336
+ * @param {string[] | TypeKeyCombo} selectedTypes limit to given metadata types
1337
+ * @param {string[]} [keys] customerkey of the metadata
1338
+ * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
1339
+ */
1340
+ static async publish(businessUnit, selectedTypes, keys) {
1341
+ return this.#runMethod('publish', businessUnit, selectedTypes, keys);
1021
1342
  }
1022
1343
  /**
1023
1344
  * Start/execute an item
1024
1345
  *
1025
1346
  * @param {string} businessUnit name of BU
1026
- * @param {string} [selectedType] limit to given metadata types
1347
+ * @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types
1027
1348
  * @param {string[]} [keys] customerkey of the metadata
1028
- * @returns {Promise.<Object.<string, string[]>>} key: business unit name, value: list of executed item keys
1349
+ * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
1029
1350
  */
1030
- static async execute(businessUnit, selectedType, keys) {
1031
- return this.#runMethod('execute', businessUnit, selectedType, keys);
1351
+ static async execute(businessUnit, selectedTypes, keys) {
1352
+ return this.#runMethod('execute', businessUnit, selectedTypes, keys);
1032
1353
  }
1033
1354
  /**
1034
1355
  * pause an item
1035
1356
  *
1036
1357
  * @param {string} businessUnit name of BU
1037
- * @param {string} [selectedType] limit to given metadata types
1358
+ * @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types
1038
1359
  * @param {string[]} [keys] customerkey of the metadata
1039
- * @returns {Promise.<Object.<string, string[]>>} key: business unit name, value: list of paused item keys
1360
+ * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
1040
1361
  */
1041
- static async pause(businessUnit, selectedType, keys) {
1042
- return this.#runMethod('pause', businessUnit, selectedType, keys);
1362
+ static async pause(businessUnit, selectedTypes, keys) {
1363
+ return this.#runMethod('pause', businessUnit, selectedTypes, keys);
1043
1364
  }
1044
1365
  /**
1045
1366
  * Updates the key to match the name field
@@ -1121,19 +1442,11 @@ class Mcdev {
1121
1442
  ).join(', ')}`
1122
1443
  );
1123
1444
 
1124
- const response = {};
1125
- for (const selectedType of Array.isArray(selectedTypesArr)
1126
- ? selectedTypesArr
1127
- : Object.keys(selectedTypesObj)) {
1128
- const temp = await this.#runMethod(
1129
- 'replaceCbReference',
1130
- businessUnit,
1131
- selectedType,
1132
- Array.isArray(selectedTypesArr) ? null : selectedTypesObj[selectedType]
1133
- );
1134
- response[businessUnit] ||= {};
1135
- response[businessUnit][selectedType] = temp[businessUnit];
1136
- }
1445
+ const response = await this.#runMethod(
1446
+ 'replaceCbReference',
1447
+ businessUnit,
1448
+ selectedTypesArr || selectedTypesObj
1449
+ );
1137
1450
 
1138
1451
  return response;
1139
1452
  }
@@ -1192,30 +1505,20 @@ class Mcdev {
1192
1505
  skipInteraction: { fixKeysReretrieve: false },
1193
1506
  });
1194
1507
  }
1195
-
1196
- const response = {};
1197
- for (const selectedType of selectedTypesArr || Object.keys(selectedTypesObj)) {
1198
- if (selectedType === 'event') {
1199
- Util.logger.warn(
1200
- `Type 'event' is not supported for fixKeys for compatibility reasons. Draft Journeys would otherwise be broken after the key change. If you do need to update an event key, use deploy --changeKeyValue or --changeKeyField instead.`
1201
- );
1202
- if (Array.isArray(selectedTypes)) {
1203
- selectedTypes = selectedTypes.filter((type) => type !== 'event');
1204
- } else {
1205
- delete selectedTypes.event;
1206
- }
1207
- continue;
1208
- }
1209
- const temp = await this.#runMethod(
1210
- 'fixKeys',
1211
- businessUnit,
1212
- selectedType,
1213
- selectedTypesArr ? keys : selectedTypesObj[selectedType]
1214
- );
1215
- response[businessUnit] ||= {};
1216
- response[businessUnit][selectedType] = temp[businessUnit];
1508
+ // `Type 'event' is not supported for fixKeys for compatibility reasons. Draft Journeys would otherwise be broken after the key change. If you do need to update an event key, use deploy --changeKeyValue or --changeKeyField instead.`;
1509
+ if (Array.isArray(selectedTypes) && selectedTypes.includes('event')) {
1510
+ selectedTypesArr = selectedTypes.filter((type) => type !== 'event');
1511
+ } else if (selectedTypesObj && selectedTypesObj.event) {
1512
+ delete selectedTypesObj.event;
1217
1513
  }
1218
1514
 
1515
+ const response = await this.#runMethod(
1516
+ 'fixKeys',
1517
+ businessUnit,
1518
+ selectedTypesArr || selectedTypesObj,
1519
+ keys
1520
+ );
1521
+
1219
1522
  if (reRetrieveAll) {
1220
1523
  // only done if selectedTypesArr is set as fallback
1221
1524
  Util.logger.info(
@@ -1230,19 +1533,19 @@ class Mcdev {
1230
1533
  /**
1231
1534
  * run a method across BUs
1232
1535
  *
1233
- * @param {'execute'|'pause'|'fixKeys'|'replaceCbReference'} methodName what to run
1536
+ * @param {'execute'|'pause'|'publish'|'fixKeys'|'replaceCbReference'} methodName what to run
1234
1537
  * @param {string} businessUnit name of BU
1235
- * @param {string} [selectedType] limit to given metadata types
1538
+ * @param {string[] | TypeKeyCombo} [selectedTypes] limit to given metadata types
1236
1539
  * @param {string[]} [keys] customerkey of the metadata
1237
- * @returns {Promise.<Object.<string, string[]>>} key: business unit name, value: list of affected item keys
1540
+ * @returns {Promise.<Object.<string, Object.<string, string[]>>>} key: business unit name, key2: type, value: list of affected item keys
1238
1541
  */
1239
- static async #runMethod(methodName, businessUnit, selectedType, keys) {
1542
+ static async #runMethod(methodName, businessUnit, selectedTypes, keys) {
1240
1543
  Util.startLogger();
1241
1544
  let lang_past;
1242
1545
  let lang_present;
1243
1546
  let requireKeyOrLike;
1244
1547
  let checkMetadataSupport;
1245
- /** @type {Object.<string, string[]>} */
1548
+ /** @type {Object.<string, Object.<string, string[]>>} */
1246
1549
  const resultObj = {};
1247
1550
 
1248
1551
  switch (methodName) {
@@ -1260,6 +1563,13 @@ class Mcdev {
1260
1563
  checkMetadataSupport = true;
1261
1564
  break;
1262
1565
  }
1566
+ case 'publish': {
1567
+ lang_past = 'published';
1568
+ lang_present = 'publishing';
1569
+ requireKeyOrLike = true;
1570
+ checkMetadataSupport = true;
1571
+ break;
1572
+ }
1263
1573
  case 'fixKeys': {
1264
1574
  lang_past = 'fixed keys';
1265
1575
  lang_present = 'fixing keys';
@@ -1275,125 +1585,148 @@ class Mcdev {
1275
1585
  break;
1276
1586
  }
1277
1587
  }
1278
-
1279
- Util.logger.info(`mcdev:: ${methodName} ${selectedType}`);
1588
+ /** @typedef {string[]} */
1589
+ let selectedTypesArr;
1590
+ /** @typedef {TypeKeyCombo} */
1591
+ let selectedTypesObj;
1592
+ if (selectedTypes) {
1593
+ // check if types are valid
1594
+ for (const selectedType of Array.isArray(selectedTypes)
1595
+ ? selectedTypes
1596
+ : Object.keys(selectedTypes)) {
1597
+ if (!Util._isValidType(selectedType)) {
1598
+ return resultObj;
1599
+ }
1600
+ if (
1601
+ checkMetadataSupport &&
1602
+ !Object.prototype.hasOwnProperty.call(
1603
+ MetadataTypeInfo[selectedType],
1604
+ methodName
1605
+ )
1606
+ ) {
1607
+ Util.logger.error(
1608
+ ` ☇ skipping ${selectedType}: ${methodName} is not supported yet for ${selectedType}`
1609
+ );
1610
+ return resultObj;
1611
+ }
1612
+ }
1613
+ if (Array.isArray(selectedTypes)) {
1614
+ selectedTypesArr = selectedTypes;
1615
+ } else {
1616
+ selectedTypesObj = selectedTypes;
1617
+ }
1618
+ }
1280
1619
  const properties = await config.getProperties();
1281
- let counter_credBu = 0;
1282
- let counter_credKeys = 0;
1283
1620
  if (!(await config.checkProperties(properties))) {
1284
1621
  // return null here to avoid seeing 2 error messages for the same issue
1285
1622
  return resultObj;
1286
1623
  }
1287
- if (!Util._isValidType(selectedType)) {
1288
- return resultObj;
1289
- }
1290
- if (
1291
- checkMetadataSupport &&
1292
- !Object.prototype.hasOwnProperty.call(MetadataTypeInfo[selectedType], methodName)
1293
- ) {
1294
- Util.logger.error(
1295
- ` skipping ${selectedType}: ${methodName} is not supported yet for ${selectedType}`
1296
- );
1297
- return resultObj;
1298
- }
1299
-
1300
- if (
1301
- requireKeyOrLike &&
1302
- (!Array.isArray(keys) || !keys.length) &&
1303
- (!Util.OPTIONS.like || !Object.keys(Util.OPTIONS.like).length)
1304
- ) {
1305
- Util.logger.error('At least one key or a --like filter is required.');
1306
- return resultObj;
1307
- } else if (
1308
- Array.isArray(keys) &&
1309
- keys.length &&
1310
- Util.OPTIONS.like &&
1311
- Object.keys(Util.OPTIONS.like).length
1312
- ) {
1313
- Util.logger.error('You can either specify keys OR a --like filter.');
1314
- return resultObj;
1315
- }
1624
+ for (const selectedType of selectedTypesArr || Object.keys(selectedTypesObj)) {
1625
+ Util.logger.info(`mcdev:: ${methodName} ${selectedType}`);
1626
+ let counter_credBu = 0;
1627
+ let counter_credKeys = 0;
1628
+ const keyArr = selectedTypesArr ? keys : selectedTypesObj[selectedType];
1629
+ if (
1630
+ requireKeyOrLike &&
1631
+ (!Array.isArray(keyArr) || !keyArr.length) &&
1632
+ (!Util.OPTIONS.like || !Object.keys(Util.OPTIONS.like).length)
1633
+ ) {
1634
+ Util.logger.error('At least one key or a --like filter is required.');
1635
+ return resultObj;
1636
+ } else if (
1637
+ Array.isArray(keyArr) &&
1638
+ keyArr.length &&
1639
+ Util.OPTIONS.like &&
1640
+ Object.keys(Util.OPTIONS.like).length
1641
+ ) {
1642
+ Util.logger.error('You can either specify keys OR a --like filter.');
1643
+ return resultObj;
1644
+ }
1316
1645
 
1317
- if (businessUnit === '*') {
1318
- Util.OPTIONS._multiBuExecution = true;
1319
- Util.logger.info(
1320
- `:: ${lang_present} the ${selectedType} on all BUs for all credentials`
1321
- );
1322
- let counter_credTotal = 0;
1323
- for (const cred in properties.credentials) {
1324
- Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`);
1325
- // reset counter per cred
1326
- counter_credKeys = 0;
1327
- counter_credBu = 0;
1328
- for (const bu in properties.credentials[cred].businessUnits) {
1329
- resultObj[cred + '/' + bu] = await this.#runOnBU(
1330
- methodName,
1331
- cred,
1332
- bu,
1333
- selectedType,
1334
- keys
1646
+ if (businessUnit === '*') {
1647
+ Util.OPTIONS._multiBuExecution = true;
1648
+ Util.logger.info(
1649
+ `:: ${lang_present} the ${selectedType} on all BUs for all credentials`
1650
+ );
1651
+ let counter_credTotal = 0;
1652
+ for (const cred in properties.credentials) {
1653
+ Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`);
1654
+ // reset counter per cred
1655
+ counter_credKeys = 0;
1656
+ counter_credBu = 0;
1657
+ for (const bu in properties.credentials[cred].businessUnits) {
1658
+ resultObj[cred + '/' + bu] ||= {};
1659
+ resultObj[cred + '/' + bu][selectedType] = await this.#runOnBU(
1660
+ methodName,
1661
+ cred,
1662
+ bu,
1663
+ selectedType,
1664
+ keyArr
1665
+ );
1666
+ counter_credBu++;
1667
+ counter_credKeys += resultObj[cred + '/' + bu][selectedType].length;
1668
+ Util.startLogger(true);
1669
+ }
1670
+ counter_credTotal += counter_credBu;
1671
+ Util.logger.info(
1672
+ `:: ${lang_past} for ${counter_credKeys} ${selectedType}s on ${counter_credBu} BUs for ${cred}`
1335
1673
  );
1336
- counter_credBu++;
1337
- counter_credKeys += resultObj[cred + '/' + bu].length;
1338
- Util.startLogger(true);
1339
1674
  }
1340
- counter_credTotal += counter_credBu;
1341
1675
  Util.logger.info(
1342
- `:: ${lang_past} for ${counter_credKeys} ${selectedType}s on ${counter_credBu} BUs for ${cred}`
1676
+ `:: ${lang_past} ${selectedType} on ${counter_credTotal} BUs in total\n`
1343
1677
  );
1344
- }
1345
- Util.logger.info(
1346
- `:: ${lang_past} ${selectedType} on ${counter_credTotal} BUs in total\n`
1347
- );
1348
- } else {
1349
- let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null];
1350
- // to allow all-BU via user selection we need to run this here already
1351
- if (
1352
- properties.credentials &&
1353
- (!properties.credentials[cred] ||
1354
- (bu !== '*' && !properties.credentials[cred].businessUnits[bu]))
1355
- ) {
1356
- const buObject = await Cli.getCredentialObject(
1357
- properties,
1358
- cred === null ? null : cred + '/' + bu,
1359
- null,
1360
- true
1361
- );
1362
- if (buObject === null) {
1363
- return resultObj;
1364
- } else {
1365
- cred = buObject.credential;
1366
- bu = buObject.businessUnit;
1678
+ } else {
1679
+ let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null];
1680
+ // to allow all-BU via user selection we need to run this here already
1681
+ if (
1682
+ properties.credentials &&
1683
+ (!properties.credentials[cred] ||
1684
+ (bu !== '*' && !properties.credentials[cred].businessUnits[bu]))
1685
+ ) {
1686
+ const buObject = await Cli.getCredentialObject(
1687
+ properties,
1688
+ cred === null ? null : cred + '/' + bu,
1689
+ null,
1690
+ true
1691
+ );
1692
+ if (buObject === null) {
1693
+ return resultObj;
1694
+ } else {
1695
+ cred = buObject.credential;
1696
+ bu = buObject.businessUnit;
1697
+ }
1367
1698
  }
1368
- }
1369
- if (bu === '*' && properties.credentials && properties.credentials[cred]) {
1370
- Util.OPTIONS._multiBuExecution = true;
1371
- Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`);
1372
- for (const bu in properties.credentials[cred].businessUnits) {
1373
- resultObj[cred + '/' + bu] = await this.#runOnBU(
1699
+ if (bu === '*' && properties.credentials && properties.credentials[cred]) {
1700
+ Util.OPTIONS._multiBuExecution = true;
1701
+ Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`);
1702
+ for (const bu in properties.credentials[cred].businessUnits) {
1703
+ resultObj[cred + '/' + bu] ||= {};
1704
+ resultObj[cred + '/' + bu][selectedType] = await this.#runOnBU(
1705
+ methodName,
1706
+ cred,
1707
+ bu,
1708
+ selectedType,
1709
+ keyArr
1710
+ );
1711
+ counter_credBu++;
1712
+ counter_credKeys += resultObj[cred + '/' + bu][selectedType].length;
1713
+ Util.startLogger(true);
1714
+ }
1715
+ Util.logger.info(
1716
+ `:: ${lang_past} for ${counter_credKeys} ${selectedType}s on ${counter_credBu} BUs for ${cred}`
1717
+ );
1718
+ } else {
1719
+ // execute runMethod for the entity on one BU only
1720
+ resultObj[cred + '/' + bu] ||= {};
1721
+ resultObj[cred + '/' + bu][selectedType] = await this.#runOnBU(
1374
1722
  methodName,
1375
1723
  cred,
1376
1724
  bu,
1377
1725
  selectedType,
1378
- keys
1726
+ keyArr
1379
1727
  );
1380
- counter_credBu++;
1381
- counter_credKeys += resultObj[cred + '/' + bu].length;
1382
- Util.startLogger(true);
1728
+ Util.logger.info(`:: Done`);
1383
1729
  }
1384
- Util.logger.info(
1385
- `:: ${lang_past} for ${counter_credKeys} ${selectedType}s on ${counter_credBu} BUs for ${cred}`
1386
- );
1387
- } else {
1388
- // execute runMethod for the entity on one BU only
1389
- resultObj[cred + '/' + bu] = await this.#runOnBU(
1390
- methodName,
1391
- cred,
1392
- bu,
1393
- selectedType,
1394
- keys
1395
- );
1396
- Util.logger.info(`:: Done`);
1397
1730
  }
1398
1731
  }
1399
1732
  return resultObj;
@@ -1401,7 +1734,7 @@ class Mcdev {
1401
1734
  /**
1402
1735
  * helper for Mcdev.#runMethod
1403
1736
  *
1404
- * @param {'execute'|'pause'|'fixKeys'|'replaceCbReference'} methodName what to run
1737
+ * @param {'execute'|'pause'|'publish'|'fixKeys'|'replaceCbReference'} methodName what to run
1405
1738
  * @param {string} cred name of Credential
1406
1739
  * @param {string} bu name of BU
1407
1740
  * @param {string} [type] limit execution to given metadata type