mcdev 5.1.0 → 5.3.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 (256) hide show
  1. package/.eslintrc.json +4 -4
  2. package/.fork/custom-commands.json +12 -0
  3. package/.github/ISSUE_TEMPLATE/bug.yml +2 -0
  4. package/.github/PULL_REQUEST_TEMPLATE/pr_template_release.md +19 -0
  5. package/.github/PULL_REQUEST_TEMPLATE.md +2 -2
  6. package/.github/workflows/coverage-develop-branch.yml +0 -2
  7. package/.github/workflows/coverage-main-branch.yml +0 -2
  8. package/.github/workflows/coverage.yml +0 -2
  9. package/.husky/post-checkout +1 -0
  10. package/.husky/post-merge +1 -0
  11. package/.vscode/extensions.json +4 -0
  12. package/docs/dist/documentation.md +1034 -296
  13. package/lib/Deployer.js +25 -25
  14. package/lib/MetadataTypeDefinitions.js +2 -1
  15. package/lib/MetadataTypeInfo.js +2 -1
  16. package/lib/Retriever.js +1 -1
  17. package/lib/cli.js +165 -10
  18. package/lib/index.js +398 -95
  19. package/lib/metadataTypes/Asset.js +10 -11
  20. package/lib/metadataTypes/AttributeGroup.js +76 -2
  21. package/lib/metadataTypes/AttributeSet.js +367 -0
  22. package/lib/metadataTypes/Automation.js +483 -137
  23. package/lib/metadataTypes/DataExtension.js +465 -68
  24. package/lib/metadataTypes/DataExtensionField.js +31 -14
  25. package/lib/metadataTypes/Event.js +2 -3
  26. package/lib/metadataTypes/Folder.js +1 -1
  27. package/lib/metadataTypes/Journey.js +13 -7
  28. package/lib/metadataTypes/MetadataType.js +212 -54
  29. package/lib/metadataTypes/MobileKeyword.js +9 -9
  30. package/lib/metadataTypes/MobileMessage.js +5 -5
  31. package/lib/metadataTypes/Query.js +26 -10
  32. package/lib/metadataTypes/Script.js +3 -3
  33. package/lib/metadataTypes/TransactionalEmail.js +94 -17
  34. package/lib/metadataTypes/TransactionalMessage.js +3 -2
  35. package/lib/metadataTypes/TransactionalSMS.js +5 -5
  36. package/lib/metadataTypes/TriggeredSend.js +25 -50
  37. package/lib/metadataTypes/User.js +7 -4
  38. package/lib/metadataTypes/Verification.js +230 -0
  39. package/lib/metadataTypes/definitions/AttributeGroup.definition.js +119 -108
  40. package/lib/metadataTypes/definitions/{SetDefinition.definition.js → AttributeSet.definition.js} +123 -43
  41. package/lib/metadataTypes/definitions/Automation.definition.js +23 -15
  42. package/lib/metadataTypes/definitions/ImportFile.definition.js +36 -6
  43. package/lib/metadataTypes/definitions/TransactionalEmail.definition.js +19 -1
  44. package/lib/metadataTypes/definitions/TriggeredSend.definition.js +1 -0
  45. package/lib/metadataTypes/definitions/Verification.definition.js +88 -0
  46. package/lib/util/cache.js +9 -4
  47. package/lib/util/cli.js +40 -0
  48. package/lib/util/file.js +2 -2
  49. package/lib/util/init.js +84 -0
  50. package/lib/util/util.js +121 -13
  51. package/package.json +13 -13
  52. package/test/mockRoot/.mcdevrc.json +1 -1
  53. package/test/mockRoot/deploy/testInstance/_ParentBU_/dataExtension/testExisting_dataExtensionShared.dataExtension-meta.json +59 -0
  54. package/test/mockRoot/deploy/testInstance/_ParentBU_/dataExtension/testNew_dataExtensionShared.dataExtension-meta.json +23 -0
  55. package/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json +1 -2
  56. package/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json +9 -6
  57. package/test/mockRoot/deploy/testInstance/testBU/dataExtension/testExisting_dataExtension.dataExtension-meta.json +1 -0
  58. package/test/mockRoot/deploy/testInstance/testBU/dataExtract/testExisting_dataExtract.dataExtract-meta.json +35 -0
  59. package/test/mockRoot/deploy/testInstance/testBU/dataExtract/testNew_dataExtract.dataExtract-meta.json +35 -0
  60. package/test/mockRoot/deploy/testInstance/testBU/fileTransfer/testExisting_fileTransfer.fileTransfer-meta.json +17 -0
  61. package/test/mockRoot/deploy/testInstance/testBU/fileTransfer/testNew_fileTransfer.fileTransfer-meta.json +17 -0
  62. package/test/mockRoot/deploy/testInstance/testBU/importFile/testExisting_importFile.importFile-meta.json +29 -0
  63. package/test/mockRoot/deploy/testInstance/testBU/importFile/testNew_importFile.importFile-meta.json +29 -0
  64. package/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json +11 -0
  65. package/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql +6 -0
  66. package/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.json +6 -0
  67. package/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.ssjs +1 -0
  68. package/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.json +6 -0
  69. package/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.ssjs +1 -0
  70. package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testExisting_temail.transactionalEmail-meta.json +3 -4
  71. package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testNew_temail.transactionalEmail-meta.json +1 -6
  72. package/test/mockRoot/deploy/testInstance/testBU/triggeredSend/testExisting_triggeredSend.triggeredSend-meta.json +29 -0
  73. package/test/mockRoot/deploy/testInstance/testBU/triggeredSend/testNew_triggeredSend.triggeredSend-meta.json +29 -0
  74. package/test/mockRoot/deploy/testInstance/testBU/verification/testExisting_39f6a488-20eb-4ba0-b0b9.verification-meta.json +11 -0
  75. package/test/mockRoot/deploy/testInstance/testBU/verification/testNew_39f6a488-20eb-4ba0-b0b9.verification-meta.json +11 -0
  76. package/test/resourceFactory.js +77 -12
  77. package/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDCustomerKey=testExisting_userANDEmaillike@-response.xml +27 -0
  78. package/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDEmaillike@-response.xml +156 -0
  79. package/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml +87 -0
  80. package/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmaillike@-response.xml +156 -0
  81. package/test/resources/1111111/accountUser/retrieve-CustomerKey=testExisting_userANDActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml +27 -0
  82. package/test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserID=700301950-response.xml +60 -0
  83. package/test/resources/1111111/data/v1/customobjectdata/key/testExisting_dataExtensionShared/rowset/get-response.json +13 -0
  84. package/test/resources/1111111/dataExtension/create-expected.json +23 -0
  85. package/test/resources/1111111/dataExtension/create-response.xml +59 -0
  86. package/test/resources/1111111/dataExtension/retrieve-expected.json +55 -0
  87. package/test/resources/1111111/dataExtension/retrieve-expected.md +18 -0
  88. package/test/resources/1111111/dataExtension/retrieve-response.xml +27 -1
  89. package/test/resources/1111111/dataExtension/update-expected.json +55 -0
  90. package/test/resources/1111111/dataExtension/update-response.xml +57 -0
  91. package/test/resources/1111111/dataExtensionField/retrieve-CustomerKey=[testExisting_dataExtensionShared].[TriggerUpdate_randomNumber_]-response.xml +45 -0
  92. package/test/resources/1111111/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtensionShared-response.xml +98 -0
  93. package/test/resources/1111111/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionSharedORDataExtension.CustomerKey=testExisting_dataExtensionShared-response.xml +98 -0
  94. package/test/resources/1111111/dataExtensionField/retrieve-response.xml +98 -0
  95. package/test/resources/1111111/dataExtensionTemplate/retrieve-response.xml +303 -0
  96. package/test/resources/1111111/dataFolder/retrieve-ContentType=synchronizeddataextensionORContentType=shared_salesforcedataextensionORContentType=shared_dataextensionORContentType=shared_dataORContentType=salesforcedataextensionORContentType=dataextensionORContentType=hidden-response.xml +387 -0
  97. package/test/resources/1111111/dataFolder/retrieve-response.xml +353 -9
  98. package/test/resources/1111111/user/retrieve-expected.md +4 -2
  99. package/test/resources/9999999/attributeGroup/retrieve-expected.json +25 -0
  100. package/test/resources/9999999/attributeSet/retrieve-expected.json +143 -0
  101. package/test/resources/9999999/automation/build-expected.json +5 -2
  102. package/test/resources/9999999/automation/create-expected.json +11 -8
  103. package/test/resources/9999999/automation/create-testNew_automation-expected.md +5 -4
  104. package/test/resources/9999999/automation/patch_fixKeys-pause-expected.json +44 -0
  105. package/test/resources/9999999/automation/patch_fixKeys-schedule-expected.json +44 -0
  106. package/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +42 -0
  107. package/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-fixKey_pause-response.xml +42 -0
  108. package/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-fixKey_schedule-response.xml +42 -0
  109. package/test/resources/9999999/automation/perform-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +42 -0
  110. package/test/resources/9999999/automation/retrieve-expected.json +5 -2
  111. package/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md +3 -2
  112. package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +52 -0
  113. package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-pause-response.xml +38 -0
  114. package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-fixKey_pause-response.xml +52 -0
  115. package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-fixKey_schedule-response.xml +52 -0
  116. package/test/resources/9999999/automation/schedule-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +52 -0
  117. package/test/resources/9999999/automation/template-expected.json +5 -2
  118. package/test/resources/9999999/automation/update-expected.json +1 -2
  119. package/test/resources/9999999/automation/update-testExisting_automation-expected.md +2 -2
  120. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json +7 -0
  121. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/get-response.json +85 -0
  122. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json +85 -0
  123. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_pause/get-response.json +85 -0
  124. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_pause/patch-response.json +85 -0
  125. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_schedule/get-response.json +85 -0
  126. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_schedule/patch-response.json +85 -0
  127. package/test/resources/9999999/automation/v1/automations/a8afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json +1 -1
  128. package/test/resources/9999999/automation/v1/automations/post-response.json +27 -19
  129. package/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/patch-response.json +38 -0
  130. package/test/resources/9999999/automation/v1/dataextracts/post-response.json +38 -0
  131. package/test/resources/9999999/automation/v1/dataextracttypes/get-response.json +50 -0
  132. package/test/resources/9999999/automation/v1/dataverifications/post-response.json +12 -0
  133. package/test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/delete-response.json +0 -0
  134. package/test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/get-response.json +12 -0
  135. package/test/resources/9999999/automation/v1/dataverifications/testExisting_39f6a488-20eb-4ba0-b0b9/patch-response.json +12 -0
  136. package/test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/patch-response.json +18 -0
  137. package/test/resources/9999999/automation/v1/filetransfers/post-response.json +18 -0
  138. package/test/resources/9999999/automation/v1/ftplocations/get-response.json +18 -0
  139. package/test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/patch-response.json +31 -0
  140. package/test/resources/9999999/automation/v1/imports/get-response.json +1 -1
  141. package/test/resources/9999999/automation/v1/imports/post-response.json +30 -0
  142. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dae/actions/start/post-response.txt +1 -0
  143. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json +17 -0
  144. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/patch-response.json +18 -0
  145. package/test/resources/9999999/automation/v1/queries/get-response.json +18 -1
  146. package/test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/patch-response.json +10 -0
  147. package/test/resources/9999999/automation/v1/scripts/get-response.json +12 -2
  148. package/test/resources/9999999/automation/v1/scripts/post-response.json +10 -0
  149. package/test/resources/9999999/dataExtension/build-expected.json +16 -0
  150. package/test/resources/9999999/dataExtension/delete-response.xml +42 -0
  151. package/test/resources/9999999/dataExtension/retrieve-Name=testExisting_dataExtension-response.xml +52 -0
  152. package/test/resources/9999999/dataExtension/retrieve-expected.json +16 -0
  153. package/test/resources/9999999/dataExtension/retrieve-expected.md +3 -1
  154. package/test/resources/9999999/dataExtension/template-expected.json +16 -0
  155. package/test/resources/9999999/dataExtension/update-expected.json +17 -1
  156. package/test/resources/9999999/dataExtensionField/retrieve-CustomerKey=[testExisting_dataExtension].[LastName]-response.xml +44 -0
  157. package/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtension-response.xml +133 -0
  158. package/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionORDataExtension.CustomerKey=testExisting_dataExtension-response.xml +99 -0
  159. package/test/resources/9999999/dataExtensionField/retrieve-response.xml +36 -1
  160. package/test/resources/9999999/dataExtract/build-expected.json +35 -0
  161. package/test/resources/9999999/dataExtract/get-expected.json +39 -0
  162. package/test/resources/9999999/dataExtract/patch-expected.json +37 -0
  163. package/test/resources/9999999/dataExtract/post-expected.json +37 -0
  164. package/test/resources/9999999/dataExtract/template-expected.json +35 -0
  165. package/test/resources/9999999/dataFolder/retrieve-ContentType=contextual_suppression_listORContentType=publicationORContentType=suppression_listORContentType=mysubsORContentType=list-response.xml +136 -0
  166. package/test/resources/9999999/dataFolder/retrieve-ContentType=ssjsactivity-response.xml +48 -0
  167. package/test/resources/9999999/dataFolder/retrieve-ContentType=synchronizeddataextensionORContentType=shared_salesforcedataextensionORContentType=shared_dataextensionORContentType=shared_dataORContentType=salesforcedataextensionORContentType=dataextensionORContentType=hidden-response.xml +117 -0
  168. package/test/resources/9999999/dataFolder/retrieve-ContentType=triggered_send_journeybuilderORContentType=triggered_sendORContentType=hidden-response.xml +276 -0
  169. package/test/resources/9999999/dataFolder/retrieve-response.xml +23 -0
  170. package/test/resources/9999999/email/retrieve-response.xml +203 -0
  171. package/test/resources/9999999/fileTransfer/build-expected.json +15 -0
  172. package/test/resources/9999999/fileTransfer/get-expected.json +17 -0
  173. package/test/resources/9999999/fileTransfer/patch-expected.json +17 -0
  174. package/test/resources/9999999/fileTransfer/post-expected.json +17 -0
  175. package/test/resources/9999999/fileTransfer/template-expected.json +15 -0
  176. package/test/resources/9999999/hub/v1/contacts/schema/attributeGroups/get-response.json +628 -0
  177. package/test/resources/9999999/hub/v1/contacts/schema/setDefinitions/get-response.json +20194 -0
  178. package/test/resources/9999999/importFile/build-expected.json +27 -0
  179. package/test/resources/9999999/importFile/get-expected.json +29 -0
  180. package/test/resources/9999999/importFile/patch-expected.json +29 -0
  181. package/test/resources/9999999/importFile/post-expected.json +29 -0
  182. package/test/resources/9999999/importFile/template-expected.json +27 -0
  183. package/test/resources/9999999/interaction/v1/interactions/233d4413-922c-4568-85a5-e5cc77efc3be/delete-response.json +1 -0
  184. package/test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/get-response.json +1 -1
  185. package/test/resources/9999999/messaging/v1/email/definitions/post-response.json +1 -1
  186. package/test/resources/9999999/messaging/v1/email/definitions/testExisting_temail/delete-response.json +6 -0
  187. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixKey_pause-response.xml +32 -0
  188. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixKey_schedule-response.xml +32 -0
  189. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixedKey_paused-response.xml +32 -0
  190. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixedKey_scheduled-response.xml +32 -0
  191. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_pause-response.xml +30 -0
  192. package/test/resources/9999999/program/retrieve-response.xml +21 -3
  193. package/test/resources/9999999/query/patch_fixKeys-expected.json +11 -0
  194. package/test/resources/9999999/query/patch_fixKeys-expected.sql +6 -0
  195. package/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixKeysANDStatus=Active-response.xml +30 -0
  196. package/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixedKeysANDStatus=Active-response.xml +30 -0
  197. package/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testNew_queryANDStatus=Active-response.xml +30 -0
  198. package/test/resources/9999999/script/build-expected.json +6 -0
  199. package/test/resources/9999999/script/build-expected.ssjs +1 -0
  200. package/test/resources/9999999/script/get-expected.json +8 -0
  201. package/test/resources/9999999/script/get-expected.ssjs +1 -0
  202. package/test/resources/9999999/script/get_noScriptTag-expected.html +1 -0
  203. package/test/resources/9999999/script/get_noScriptTag-expected.json +8 -0
  204. package/test/resources/9999999/script/patch-expected.json +8 -0
  205. package/test/resources/9999999/script/patch-expected.ssjs +1 -0
  206. package/test/resources/9999999/script/post-expected.json +8 -0
  207. package/test/resources/9999999/script/post-expected.ssjs +1 -0
  208. package/test/resources/9999999/script/template-expected.json +6 -0
  209. package/test/resources/9999999/script/template-expected.ssjs +1 -0
  210. package/test/resources/9999999/transactionalEmail/build-expected.json +3 -7
  211. package/test/resources/9999999/transactionalEmail/get-expected.json +3 -7
  212. package/test/resources/9999999/transactionalEmail/patch-expected.json +3 -7
  213. package/test/resources/9999999/transactionalEmail/post-expected.json +3 -7
  214. package/test/resources/9999999/transactionalEmail/template-expected.json +3 -7
  215. package/test/resources/9999999/triggeredSend/build-expected.json +29 -0
  216. package/test/resources/9999999/triggeredSend/get-expected.json +29 -0
  217. package/test/resources/9999999/triggeredSend/patch-expected.json +29 -0
  218. package/test/resources/9999999/triggeredSend/post-expected.json +29 -0
  219. package/test/resources/9999999/triggeredSend/template-expected.json +29 -0
  220. package/test/resources/9999999/triggeredSendDefinition/create-response.xml +75 -0
  221. package/test/resources/9999999/triggeredSendDefinition/delete-response.xml +36 -0
  222. package/test/resources/9999999/triggeredSendDefinition/{retrieve-response.xml → retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml} +4 -4
  223. package/test/resources/9999999/triggeredSendDefinition/update-response.xml +74 -0
  224. package/test/resources/9999999/verification/build-expected.json +11 -0
  225. package/test/resources/9999999/verification/get-expected.json +11 -0
  226. package/test/resources/9999999/verification/patch-expected.json +11 -0
  227. package/test/resources/9999999/verification/post-expected.json +11 -0
  228. package/test/resources/9999999/verification/template-expected.json +11 -0
  229. package/test/type.attributeGroup.test.js +55 -0
  230. package/test/type.attributeSet.test.js +55 -0
  231. package/test/type.automation.test.js +650 -17
  232. package/test/type.dataExtension.test.js +205 -46
  233. package/test/type.dataExtract.test.js +194 -0
  234. package/test/type.fileTransfer.test.js +192 -0
  235. package/test/type.importFile.test.js +193 -0
  236. package/test/type.journey.test.js +38 -11
  237. package/test/type.mobileKeyword.test.js +6 -5
  238. package/test/type.mobileMessage.test.js +6 -4
  239. package/test/type.query.test.js +470 -17
  240. package/test/type.script.test.js +372 -0
  241. package/test/type.transactionalEmail.test.js +12 -11
  242. package/test/type.transactionalPush.test.js +2 -4
  243. package/test/type.transactionalSMS.test.js +2 -4
  244. package/test/type.triggeredSend.test.js +154 -0
  245. package/test/type.user.test.js +22 -10
  246. package/test/type.verification.test.js +173 -0
  247. package/test/utils.js +11 -2
  248. package/types/mcdev.d.js +14 -0
  249. package/lib/metadataTypes/SetDefinition.js +0 -37
  250. /package/test/resources/1111111/accountUser/{retrieve-response.xml → retrieve-ActiveFlag=trueANDCustomerKey=testExisting_userANDEmaillike@-response.xml} +0 -0
  251. /package/test/resources/1111111/accountUserAccount/{retrieve-response.xml → retrieve-AccountUser.AccountUserIDIN700301950,700301951,7471228-response.xml} +0 -0
  252. /package/test/resources/1111111/businessUnit/{retrieve-response.xml → retrieve-ID=1111111-response.xml} +0 -0
  253. /package/test/resources/1111111/list/{retrieve-response.xml → retrieve-CustomerKey=All SubscribersORListName=All Subscribers-response.xml} +0 -0
  254. /package/test/resources/1111111/role/{retrieve-response.xml → retrieve-IsPrivate=false-response.xml} +0 -0
  255. /package/test/resources/9999999/emailSendDefinition/{retrieve-response.xml → retrieve-IsPlatformObject=falseANDDescriptionnotEqualsSFSendDefinition-response.xml} +0 -0
  256. /package/test/resources/9999999/queryDefinition/{retrieve-response.xml → retrieve-CustomerKey=testExisting_queryANDStatus=Active-response.xml} +0 -0
package/lib/index.js CHANGED
@@ -51,15 +51,21 @@ class Mcdev {
51
51
  static setOptions(argv) {
52
52
  const knownOptions = [
53
53
  'api',
54
- 'commitHistory',
55
54
  'changeKeyField',
56
55
  'changeKeyValue',
56
+ 'commitHistory',
57
+ 'execute',
57
58
  'filter',
59
+ 'fixShared',
58
60
  'fromRetrieve',
59
61
  'json',
62
+ 'like',
63
+ 'noLogColors',
64
+ 'noLogFile',
60
65
  'refresh',
66
+ '_runningTest',
67
+ 'schedule',
61
68
  'skipInteraction',
62
- 'noLogFile',
63
69
  ];
64
70
  for (const option of knownOptions) {
65
71
  if (argv[option] !== undefined) {
@@ -153,6 +159,7 @@ class Mcdev {
153
159
  * @returns {Promise.<object>} -
154
160
  */
155
161
  static async retrieve(businessUnit, selectedTypesArr, keys, changelogOnly) {
162
+ console.time('Time'); // eslint-disable-line no-console
156
163
  Util.startLogger();
157
164
  Util.logger.info('mcdev:: Retrieve');
158
165
  const properties = await config.getProperties();
@@ -171,22 +178,32 @@ class Mcdev {
171
178
  }
172
179
  }
173
180
  }
174
-
181
+ const resultsObj = {};
175
182
  if (businessUnit === '*') {
176
- Util.logger.info('\n :: Retrieving all BUs for all credentials');
183
+ Util.logger.info(':: Retrieving all BUs for all credentials');
177
184
  let counter_credTotal = 0;
178
185
  for (const cred in properties.credentials) {
179
- Util.logger.info(`\n :: Retrieving all BUs for ${cred}`);
186
+ Util.logger.info(`:: Retrieving all BUs for ${cred}`);
180
187
  let counter_credBu = 0;
181
188
  for (const bu in properties.credentials[cred].businessUnits) {
182
- await this._retrieveBU(cred, bu, selectedTypesArr, keys);
189
+ resultsObj[`${cred}/${bu}`] = await this.#retrieveBU(
190
+ cred,
191
+ bu,
192
+ selectedTypesArr,
193
+ keys
194
+ );
183
195
  counter_credBu++;
184
196
  Util.startLogger(true);
185
197
  }
186
198
  counter_credTotal += counter_credBu;
187
- Util.logger.info(`\n :: ${counter_credBu} BUs for ${cred}\n`);
199
+ Util.logger.info(`:: ${counter_credBu} BUs of ${cred}\n`);
188
200
  }
189
- Util.logger.info(`\n :: ${counter_credTotal} BUs in total\n`);
201
+ const credentialCount = Object.keys(properties.credentials).length;
202
+ Util.logger.info(
203
+ `:: Done for ${counter_credTotal} BUs of ${credentialCount} credential${
204
+ credentialCount === 1 ? '' : 's'
205
+ } in total\n`
206
+ );
190
207
  } else {
191
208
  let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null];
192
209
  // to allow all-BU via user selection we need to run this here already
@@ -210,17 +227,22 @@ class Mcdev {
210
227
  }
211
228
 
212
229
  if (bu === '*' && properties.credentials && properties.credentials[cred]) {
213
- Util.logger.info(`\n :: Retrieving all BUs for ${cred}`);
230
+ Util.logger.info(`:: Retrieving all BUs for ${cred}`);
214
231
  let counter_credBu = 0;
215
232
  for (const bu in properties.credentials[cred].businessUnits) {
216
- await this._retrieveBU(cred, bu, selectedTypesArr, keys);
233
+ resultsObj[`${cred}/${bu}`] = await this.#retrieveBU(
234
+ cred,
235
+ bu,
236
+ selectedTypesArr,
237
+ keys
238
+ );
217
239
  counter_credBu++;
218
240
  Util.startLogger(true);
219
241
  }
220
- Util.logger.info(`\n :: ${counter_credBu} BUs for ${cred}\n`);
242
+ Util.logger.info(`:: Done for ${counter_credBu} BUs of ${cred}\n`);
221
243
  } else {
222
244
  // retrieve a single BU; return
223
- const retrieveChangelog = await this._retrieveBU(
245
+ const retrieveChangelog = await this.#retrieveBU(
224
246
  cred,
225
247
  bu,
226
248
  selectedTypesArr,
@@ -228,14 +250,33 @@ class Mcdev {
228
250
  changelogOnly
229
251
  );
230
252
  if (changelogOnly) {
253
+ console.timeEnd('Time'); // eslint-disable-line no-console
231
254
  return retrieveChangelog;
255
+ } else {
256
+ resultsObj[`${cred}/${bu}`] = retrieveChangelog;
232
257
  }
233
258
  Util.logger.info(`:: Done\n`);
234
259
  }
235
260
  }
261
+
262
+ // merge all results into one object
263
+ for (const credBu in resultsObj) {
264
+ for (const type in resultsObj[credBu]) {
265
+ const base = resultsObj[credBu][type][0];
266
+
267
+ for (let i = 1; i < resultsObj[credBu][type].length; i++) {
268
+ // merge all items into the first array
269
+ Object.assign(base, resultsObj[credBu][type][i]);
270
+ }
271
+ resultsObj[credBu][type] = resultsObj[credBu][type][0];
272
+ }
273
+ }
274
+ console.timeEnd('Time'); // eslint-disable-line no-console
275
+
276
+ return resultsObj;
236
277
  }
237
278
  /**
238
- * helper for {@link retrieve}
279
+ * helper for {@link Mcdev.retrieve}
239
280
  *
240
281
  * @private
241
282
  * @param {string} cred name of Credential
@@ -245,7 +286,7 @@ class Mcdev {
245
286
  * @param {boolean} [changelogOnly] skip saving, only create json in memory
246
287
  * @returns {Promise.<object>} ensure that BUs are worked on sequentially
247
288
  */
248
- static async _retrieveBU(cred, bu, selectedTypesArr, keys, changelogOnly) {
289
+ static async #retrieveBU(cred, bu, selectedTypesArr, keys, changelogOnly) {
249
290
  const properties = await config.getProperties();
250
291
  if (!(await config.checkProperties(properties))) {
251
292
  return null;
@@ -263,6 +304,7 @@ class Mcdev {
263
304
  // clean up old folders after types were renamed
264
305
  // TODO: Remove renamedTypes-logic 6 months after version 5 release
265
306
  const renamedTypes = {
307
+ attributeSet: 'setDefinition',
266
308
  emailSend: 'emailSendDefinition',
267
309
  event: 'eventDefinition',
268
310
  fileLocation: 'ftpLocation',
@@ -270,7 +312,8 @@ class Mcdev {
270
312
  triggeredSend: 'triggeredSendDefinition',
271
313
  user: 'accountUser',
272
314
  };
273
- Util.logger.info(`\n :: Retrieving ${cred}/${bu}\n`);
315
+ Util.logger.info('');
316
+ Util.logger.info(`:: Retrieving ${cred}/${bu}`);
274
317
  const retrieveTypesArr = [];
275
318
  if (selectedTypesArr) {
276
319
  for (const selectedType of Array.isArray(selectedTypesArr)
@@ -337,9 +380,7 @@ class Mcdev {
337
380
  null,
338
381
  changelogOnly
339
382
  );
340
- if (changelogOnly) {
341
- return retrieveChangelog;
342
- }
383
+ return retrieveChangelog;
343
384
  } catch (ex) {
344
385
  Util.logger.errorStack(ex, 'mcdev.retrieve failed');
345
386
  }
@@ -352,12 +393,14 @@ class Mcdev {
352
393
  * @param {string} businessUnit references credentials from properties.json
353
394
  * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit deployment to given metadata type
354
395
  * @param {string[]} [keyArr] limit deployment to given metadata keys
355
- * @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder
356
396
  * @returns {Promise.<Object.<string,TYPE.MultiMetadataTypeMap>>} deployed metadata per BU (first key: bu name, second key: metadata type)
357
397
  */
358
- static async deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve = false) {
398
+ static async deploy(businessUnit, selectedTypesArr, keyArr) {
399
+ console.time('Time'); // eslint-disable-line no-console
359
400
  Util.startLogger();
360
- return Deployer.deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve);
401
+ const deployResult = await Deployer.deploy(businessUnit, selectedTypesArr, keyArr);
402
+ console.timeEnd('Time'); // eslint-disable-line no-console
403
+ return deployResult;
361
404
  }
362
405
 
363
406
  /**
@@ -701,56 +744,159 @@ class Mcdev {
701
744
  }
702
745
  }
703
746
  /**
704
- * Start an item (query)
747
+ * Schedule an item (shortcut for execute --schedule)
748
+ *
749
+ * @param {string} businessUnit name of BU
750
+ * @param {TYPE.SupportedMetadataTypes} [selectedType] limit to given metadata types
751
+ * @param {string[]} [keys] customerkey of the metadata
752
+ * @returns {Promise.<Object.<string, string[]>>} key: business unit name, value: list of scheduled item keys
753
+ */
754
+ static async schedule(businessUnit, selectedType, keys) {
755
+ this.setOptions({ schedule: true });
756
+ return this.#runMethod('execute', businessUnit, selectedType, keys);
757
+ }
758
+ /**
759
+ * Start/execute an item
760
+ *
761
+ * @param {string} businessUnit name of BU
762
+ * @param {TYPE.SupportedMetadataTypes} [selectedType] limit to given metadata types
763
+ * @param {string[]} [keys] customerkey of the metadata
764
+ * @returns {Promise.<Object.<string, string[]>>} key: business unit name, value: list of executed item keys
765
+ */
766
+ static async execute(businessUnit, selectedType, keys) {
767
+ return this.#runMethod('execute', businessUnit, selectedType, keys);
768
+ }
769
+ /**
770
+ * pause an item
771
+ *
772
+ * @param {string} businessUnit name of BU
773
+ * @param {TYPE.SupportedMetadataTypes} [selectedType] limit to given metadata types
774
+ * @param {string[]} [keys] customerkey of the metadata
775
+ * @returns {Promise.<Object.<string, string[]>>} key: business unit name, value: list of paused item keys
776
+ */
777
+ static async pause(businessUnit, selectedType, keys) {
778
+ return this.#runMethod('pause', businessUnit, selectedType, keys);
779
+ }
780
+ /**
781
+ * Updates the key to match the name field
782
+ *
783
+ * @param {string} businessUnit name of BU
784
+ * @param {TYPE.SupportedMetadataTypes} selectedType limit to given metadata types
785
+ * @param {string[]} [keys] customerkey of the metadata
786
+ * @returns {Promise.<Object.<string, string[]>>} key: business unit name, value: list of paused item keys
787
+ */
788
+ static async fixKeys(businessUnit, selectedType, keys) {
789
+ return this.#runMethod('fixKeys', businessUnit, selectedType, keys);
790
+ }
791
+ /**
792
+ * run a method across BUs
705
793
  *
794
+ * @param {'execute'|'pause'|'fixKeys'} methodName what to run
706
795
  * @param {string} businessUnit name of BU
707
- * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit to given metadata types
708
- * @param {string[]} keys customerkey of the metadata
709
- * @returns {Promise.<boolean>} true if all started successfully, false if not
796
+ * @param {TYPE.SupportedMetadataTypes} [selectedType] limit to given metadata types
797
+ * @param {string[]} [keys] customerkey of the metadata
798
+ * @returns {Promise.<Object.<string, string[]>>} key: business unit name, value: list of affected item keys
710
799
  */
711
- static async execute(businessUnit, selectedTypesArr, keys) {
800
+ static async #runMethod(methodName, businessUnit, selectedType, keys) {
712
801
  Util.startLogger();
713
- Util.logger.info('mcdev:: Execute');
802
+ let lang_past;
803
+ let lang_present;
804
+ let requireKeyOrLike;
805
+ let checkMetadataSupport;
806
+ const resultObj = {};
807
+
808
+ switch (methodName) {
809
+ case 'execute': {
810
+ lang_past = 'executed';
811
+ lang_present = 'executing';
812
+ requireKeyOrLike = true;
813
+ checkMetadataSupport = true;
814
+ break;
815
+ }
816
+ case 'pause': {
817
+ lang_past = 'paused';
818
+ lang_present = 'pausing';
819
+ requireKeyOrLike = true;
820
+ checkMetadataSupport = true;
821
+ break;
822
+ }
823
+ case 'fixKeys': {
824
+ lang_past = 'fixed keys';
825
+ lang_present = 'fixing keys';
826
+ requireKeyOrLike = false;
827
+ checkMetadataSupport = false;
828
+ break;
829
+ }
830
+ }
831
+
832
+ Util.logger.info(`mcdev:: ${methodName} ${selectedType}`);
714
833
  const properties = await config.getProperties();
715
834
  let counter_credBu = 0;
716
- let counter_failed = 0;
835
+ let counter_credKeys = 0;
717
836
  if (!(await config.checkProperties(properties))) {
718
837
  // return null here to avoid seeing 2 error messages for the same issue
719
- return null;
838
+ return resultObj;
720
839
  }
721
- if (Array.isArray(selectedTypesArr)) {
722
- // types and keys can be provided but for each type all provided keys are applied as filter
723
- for (const selectedType of Array.isArray(selectedTypesArr)
724
- ? selectedTypesArr
725
- : Object.keys(selectedTypesArr)) {
726
- if (!Util._isValidType(selectedType)) {
727
- return;
728
- }
729
- }
840
+ if (!Util._isValidType(selectedType)) {
841
+ return resultObj;
730
842
  }
843
+ if (
844
+ checkMetadataSupport &&
845
+ !Object.prototype.hasOwnProperty.call(MetadataTypeInfo[selectedType], methodName)
846
+ ) {
847
+ Util.logger.error(
848
+ ` ☇ skipping ${selectedType}: ${methodName} is not supported yet for ${selectedType}`
849
+ );
850
+ return resultObj;
851
+ }
852
+
853
+ if (
854
+ requireKeyOrLike &&
855
+ (!Array.isArray(keys) || !keys.length) &&
856
+ (!Util.OPTIONS.like || !Object.keys(Util.OPTIONS.like).length)
857
+ ) {
858
+ Util.logger.error('At least one key or a --like filter is required.');
859
+ return resultObj;
860
+ } else if (
861
+ Array.isArray(keys) &&
862
+ keys.length &&
863
+ Util.OPTIONS.like &&
864
+ Object.keys(Util.OPTIONS.like).length
865
+ ) {
866
+ Util.logger.error('You can either specify keys OR a --like filter.');
867
+ return resultObj;
868
+ }
869
+
731
870
  if (businessUnit === '*') {
871
+ Util.OPTIONS._multiBuExecution = true;
732
872
  Util.logger.info(
733
- '\n :: Executing the entity on all BUs for all credentials'
873
+ `:: ${lang_present} the ${selectedType} on all BUs for all credentials`
734
874
  );
735
875
  let counter_credTotal = 0;
736
876
  for (const cred in properties.credentials) {
737
- Util.logger.info(`\n :: Executing the entity on all BUs for ${cred}`);
738
-
877
+ Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`);
878
+ // reset counter per cred
879
+ counter_credKeys = 0;
880
+ counter_credBu = 0;
739
881
  for (const bu in properties.credentials[cred].businessUnits) {
740
- if (await this._executeBU(cred, bu, selectedTypesArr, keys)) {
741
- counter_credBu++;
742
- } else {
743
- counter_failed++;
744
- }
882
+ resultObj[cred + '/' + bu] = await this.#runOnBU(
883
+ methodName,
884
+ cred,
885
+ bu,
886
+ selectedType,
887
+ keys
888
+ );
889
+ counter_credBu++;
890
+ counter_credKeys += resultObj[cred + '/' + bu].length;
745
891
  Util.startLogger(true);
746
892
  }
747
893
  counter_credTotal += counter_credBu;
748
894
  Util.logger.info(
749
- `\n :: Executed the entity on ${counter_credBu} BUs for ${cred}\n`
895
+ `:: ${lang_past} for ${counter_credKeys} ${selectedType}s on ${counter_credBu} BUs for ${cred}`
750
896
  );
751
897
  }
752
898
  Util.logger.info(
753
- `\n :: Executed the entity on ${counter_credTotal} BUs in total\n`
899
+ `:: ${lang_past} ${selectedType} on ${counter_credTotal} BUs in total\n`
754
900
  );
755
901
  } else {
756
902
  let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null];
@@ -767,91 +913,248 @@ class Mcdev {
767
913
  true
768
914
  );
769
915
  if (buObject === null) {
770
- return;
916
+ return resultObj;
771
917
  } else {
772
918
  cred = buObject.credential;
773
919
  bu = buObject.businessUnit;
774
920
  }
775
921
  }
776
922
  if (bu === '*' && properties.credentials && properties.credentials[cred]) {
777
- Util.logger.info(`\n :: Executing the entity on all BUs for ${cred}`);
778
- let counter_credBu = 0;
923
+ Util.OPTIONS._multiBuExecution = true;
924
+ Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`);
779
925
  for (const bu in properties.credentials[cred].businessUnits) {
780
- if (await this._executeBU(cred, bu, selectedTypesArr, keys)) {
781
- counter_credBu++;
782
- } else {
783
- counter_failed++;
784
- }
926
+ resultObj[cred + '/' + bu] = await this.#runOnBU(
927
+ methodName,
928
+ cred,
929
+ bu,
930
+ selectedType,
931
+ keys
932
+ );
933
+ counter_credBu++;
934
+ counter_credKeys += resultObj[cred + '/' + bu].length;
785
935
  Util.startLogger(true);
786
936
  }
787
937
  Util.logger.info(
788
- `\n :: Executed the entity on ${counter_credBu} BUs for ${cred}\n`
938
+ `:: ${lang_past} for ${counter_credKeys} ${selectedType}s on ${counter_credBu} BUs for ${cred}`
789
939
  );
790
940
  } else {
791
- // execute the entity on one BU only
792
- if (await this._executeBU(cred, bu, selectedTypesArr, keys)) {
793
- counter_credBu++;
794
- } else {
795
- counter_failed++;
796
- }
797
- Util.logger.info(`\n :: Done\n`);
941
+ // execute runMethod for the entity on one BU only
942
+ resultObj[cred + '/' + bu] = await this.#runOnBU(
943
+ methodName,
944
+ cred,
945
+ bu,
946
+ selectedType,
947
+ keys
948
+ );
949
+ Util.logger.info(`:: Done`);
798
950
  }
799
951
  }
800
- if (counter_credBu !== 0) {
801
- Util.logger.info(`\n :: Executed query on ${counter_credBu} BUs\n`);
802
- }
803
- return counter_failed === 0 ? true : false;
952
+ return resultObj;
804
953
  }
805
954
  /**
806
- * helper for {@link execute}
955
+ * helper for {@link Mcdev.#runMethod}
807
956
  *
957
+ * @param {'execute'|'pause'|'fixKeys'} methodName what to run
808
958
  * @param {string} cred name of Credential
809
959
  * @param {string} bu name of BU
810
- * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit execution to given metadata type
960
+ * @param {TYPE.SupportedMetadataTypes} [type] limit execution to given metadata type
811
961
  * @param {string[]} keyArr customerkey of the metadata
812
- * @returns {Promise.<boolean>} true if all items were executed, false otherwise
962
+ * @returns {Promise.<string[]>} list of keys that were affected
813
963
  */
814
- static async _executeBU(cred, bu, selectedTypesArr, keyArr) {
964
+ static async #runOnBU(methodName, cred, bu, type, keyArr) {
815
965
  const properties = await config.getProperties();
816
- let counter_failed = 0;
966
+ const resultArr = [];
817
967
  const buObject = await Cli.getCredentialObject(
818
968
  properties,
819
969
  cred === null ? null : cred + '/' + bu,
820
970
  null,
821
971
  true
822
972
  );
823
- if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) {
824
- throw new Error('No keys were provided');
973
+ try {
974
+ if (!type) {
975
+ throw new Error('No type was provided');
976
+ }
977
+ if (buObject !== null) {
978
+ cache.initCache(buObject);
979
+ cred = buObject.credential;
980
+ bu = buObject.businessUnit;
981
+ }
982
+ Util.logger.info(`:: ${methodName} ${type} on ${cred}/${bu}`);
983
+ MetadataTypeInfo[type].client = auth.getSDK(buObject);
984
+
985
+ MetadataTypeInfo[type].properties = properties;
986
+ MetadataTypeInfo[type].buObject = buObject;
987
+ switch (methodName) {
988
+ case 'fixKeys': {
989
+ {
990
+ resultArr.push(...(await this.#fixKeys(cred, bu, type, keyArr)));
991
+
992
+ break;
993
+ }
994
+ }
995
+ default: {
996
+ if (Util.OPTIONS.like && Object.keys(Util.OPTIONS.like).length) {
997
+ keyArr = await this.#retrieveKeysWithLike(type, buObject);
998
+ }
999
+ if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) {
1000
+ throw new Error('No keys were provided');
1001
+ } // result will be undefined (false) if methodName is not supported for the type
1002
+ resultArr.push(...(await MetadataTypeInfo[type][methodName](keyArr)));
1003
+ }
1004
+ }
1005
+ } catch (ex) {
1006
+ Util.logger.errorStack(ex, 'mcdev.' + methodName + ' failed');
825
1007
  }
826
- if (!selectedTypesArr || (Array.isArray(selectedTypesArr) && !selectedTypesArr.length)) {
827
- throw new Error('No type was provided');
1008
+
1009
+ return resultArr;
1010
+ }
1011
+
1012
+ /**
1013
+ * helper for {@link Mcdev.#runOnBU}
1014
+ *
1015
+ * @param {TYPE.SupportedMetadataTypes} selectedType limit execution to given metadata type
1016
+ * @param {TYPE.BuObject} buObject properties for auth
1017
+ * @returns {string[]} keyArr
1018
+ */
1019
+ static async #retrieveKeysWithLike(selectedType, buObject) {
1020
+ const properties = await config.getProperties();
1021
+
1022
+ // cache depenencies
1023
+ const deployOrder = Util.getMetadataHierachy([selectedType]);
1024
+ for (const type in deployOrder) {
1025
+ const subTypeArr = deployOrder[type];
1026
+ MetadataTypeInfo[type].client = auth.getSDK(buObject);
1027
+ MetadataTypeInfo[type].properties = properties;
1028
+ MetadataTypeInfo[type].buObject = buObject;
1029
+ Util.logger.info(`Caching dependent Metadata: ${type}`);
1030
+ Util.logSubtypes(subTypeArr);
1031
+ const result = await MetadataTypeInfo[type].retrieveForCache(null, subTypeArr);
1032
+ if (result) {
1033
+ if (Array.isArray(result)) {
1034
+ for (const result_i of result) {
1035
+ if (result_i?.metadata && Object.keys(result_i.metadata).length) {
1036
+ cache.mergeMetadata(type, result_i.metadata);
1037
+ }
1038
+ }
1039
+ } else {
1040
+ cache.setMetadata(type, result.metadata);
1041
+ }
1042
+ }
828
1043
  }
829
- if (buObject !== null) {
830
- cache.initCache(buObject);
831
- cred = buObject.credential;
832
- bu = buObject.businessUnit;
1044
+
1045
+ // find all keys in chosen type that match the like-filter
1046
+ const keyArr = [];
1047
+ const metadataMap = cache.getCache()[selectedType];
1048
+ if (!metadataMap) {
1049
+ throw new Error(`Selected type ${selectedType} could not be cached`);
833
1050
  }
834
1051
  Util.logger.info(
835
- `\n :: Executing ${selectedTypesArr.join(', ')} on ${cred}/${bu}\n`
1052
+ Util.getGrayMsg(`Found ${Object.keys(metadataMap).length} ${selectedType}s`)
1053
+ );
1054
+ for (const originalKey in metadataMap) {
1055
+ // hide postRetrieveOutput
1056
+ Util.setLoggingLevel({ silent: true });
1057
+ metadataMap[originalKey] = MetadataTypeInfo[selectedType].postRetrieveTasks(
1058
+ metadataMap[originalKey]
1059
+ );
1060
+ // reactivate logging
1061
+ Util.setLoggingLevel({});
1062
+ if (Util.fieldsLike(metadataMap[originalKey])) {
1063
+ keyArr.push(originalKey);
1064
+ }
1065
+ }
1066
+ Util.logger.info(
1067
+ Util.getGrayMsg(
1068
+ `Identified ${keyArr.length} ${selectedType}${
1069
+ keyArr.length === 1 ? '' : 's'
1070
+ } that match${keyArr.length === 1 ? 'es' : ''} the like-filter`
1071
+ )
1072
+ );
1073
+
1074
+ return keyArr;
1075
+ }
1076
+ /**
1077
+ * Updates the key to match the name field
1078
+ *
1079
+ * @param {string} cred name of Credential
1080
+ * @param {string} bu name of BU
1081
+ * @param {TYPE.SupportedMetadataTypes} type limit execution to given metadata type
1082
+ * @param {string[]} [keyArr] customerkey of the metadata
1083
+ * @returns {Promise.<string[]>} list of keys that were affected
1084
+ */
1085
+ static async #fixKeys(cred, bu, type, keyArr) {
1086
+ const properties = await config.getProperties();
1087
+ let actuallyFixedKeys = [];
1088
+ const resultArr = [];
1089
+
1090
+ if (
1091
+ MetadataTypeDefinitions[type].keyIsFixed === true ||
1092
+ MetadataTypeDefinitions[type].keyField === MetadataTypeDefinitions[type].idField
1093
+ ) {
1094
+ Util.logger.error(`Key cannot be updated for this type`);
1095
+ return resultArr;
1096
+ }
1097
+
1098
+ const buObject = await Cli.getCredentialObject(
1099
+ properties,
1100
+ cred === null ? null : cred + '/' + bu,
1101
+ null,
1102
+ true
836
1103
  );
837
1104
  try {
838
- // more than one type was provided, iterate types and execute items
839
- for (const type of selectedTypesArr) {
840
- try {
841
- MetadataTypeInfo[type].client = auth.getSDK(buObject);
842
- } catch (ex) {
843
- Util.logger.error(ex.message);
844
- return;
845
- }
846
- // result will be undefined (false) if execute is not supported for the type
847
- if (!(await MetadataTypeInfo[type].execute(keyArr))) {
848
- counter_failed++;
1105
+ Util.logger.info(`Retrieving latest versions of ${type} from server`);
1106
+ const retriever = new Retriever(properties, buObject);
1107
+ const retrieved = await retriever.retrieve([type], keyArr, null, false);
1108
+
1109
+ const metadataMap = Object.values(retrieved)[0][0];
1110
+ const keysForDeploy = MetadataTypeInfo[type].getKeysForFixing(metadataMap);
1111
+ if (keysForDeploy.length < 1) {
1112
+ Util.logger.warn(
1113
+ `No items found with a key-name mismatch that match your criteria.\n`
1114
+ );
1115
+ return resultArr;
1116
+ }
1117
+ this.setOptions({
1118
+ changeKeyField: MetadataTypeDefinitions[type].nameField,
1119
+ fromRetrieve: true,
1120
+ });
1121
+ const deployed = await Deployer.deploy(cred + '/' + bu, [type], keysForDeploy);
1122
+ actuallyFixedKeys = Object.keys(Object.values(Object.values(deployed)[0])[0]);
1123
+ resultArr.push(...actuallyFixedKeys);
1124
+ const dependentTypes = await Util.getDependentMetadata(type);
1125
+ if (actuallyFixedKeys && actuallyFixedKeys.length) {
1126
+ Util.logger.info(
1127
+ `Successfully updated ${actuallyFixedKeys.length} key${
1128
+ actuallyFixedKeys.length === 1 ? '' : 's'
1129
+ } of type ${type}`
1130
+ );
1131
+ if (dependentTypes.length) {
1132
+ Util.logger.warn(
1133
+ `Please re-retrieve the following types as your local copies might now be outdated: ${Util.getGrayMsg(
1134
+ dependentTypes.join(', ')
1135
+ )}`
1136
+ );
1137
+ const reRetrieve = await Cli.postFixKeysReretrieve(type, dependentTypes);
1138
+ if (reRetrieve) {
1139
+ Util.logger.info(
1140
+ `Retrieving latest versions of ${dependentTypes.join(', ')} from server`
1141
+ );
1142
+ const retriever = new Retriever(properties, buObject);
1143
+ await retriever.retrieve(dependentTypes, null, null, false);
1144
+ }
1145
+ } else {
1146
+ Util.logger.info(
1147
+ `No dependent types found that need to be re-retrieved after fixing keys of type ${type}.`
1148
+ );
849
1149
  }
1150
+ } else {
1151
+ Util.logger.warn(`No keys of type ${type} updated.`);
850
1152
  }
851
1153
  } catch (ex) {
852
- Util.logger.errorStack(ex, 'mcdev.execute failed');
1154
+ Util.logger.errorStack(ex, 'mcdev.fixKeys failed');
853
1155
  }
854
- return counter_failed === 0 ? true : false;
1156
+ Util.logger.info(`:: Done\n`);
1157
+ return resultArr;
855
1158
  }
856
1159
  }
857
1160