mcdev 5.0.2 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/.coverage-comment-template.svelte +177 -161
  2. package/.eslintrc.json +4 -4
  3. package/.github/ISSUE_TEMPLATE/bug.yml +2 -0
  4. package/.github/PULL_REQUEST_TEMPLATE.md +2 -2
  5. package/.github/dependabot.yml +8 -0
  6. package/.github/workflows/coverage-base-update.yml +6 -2
  7. package/.github/workflows/coverage-develop-branch.yml +7 -8
  8. package/.github/workflows/coverage-main-branch.yml +7 -8
  9. package/.github/workflows/coverage.yml +7 -4
  10. package/.husky/post-checkout +4 -2
  11. package/.husky/post-merge +1 -0
  12. package/.vscode/extensions.json +4 -0
  13. package/docs/dist/documentation.md +756 -294
  14. package/lib/Deployer.js +28 -28
  15. package/lib/MetadataTypeDefinitions.js +1 -1
  16. package/lib/MetadataTypeInfo.js +1 -1
  17. package/lib/Retriever.js +1 -1
  18. package/lib/cli.js +184 -6
  19. package/lib/index.js +493 -22
  20. package/lib/metadataTypes/Asset.js +10 -11
  21. package/lib/metadataTypes/AttributeGroup.js +76 -2
  22. package/lib/metadataTypes/AttributeSet.js +260 -0
  23. package/lib/metadataTypes/Automation.js +771 -247
  24. package/lib/metadataTypes/DataExtension.js +7 -7
  25. package/lib/metadataTypes/DataExtensionField.js +1 -1
  26. package/lib/metadataTypes/Event.js +2 -3
  27. package/lib/metadataTypes/Folder.js +1 -1
  28. package/lib/metadataTypes/Journey.js +5 -6
  29. package/lib/metadataTypes/MetadataType.js +187 -60
  30. package/lib/metadataTypes/MobileKeyword.js +8 -8
  31. package/lib/metadataTypes/MobileMessage.js +5 -5
  32. package/lib/metadataTypes/Query.js +47 -5
  33. package/lib/metadataTypes/Script.js +3 -3
  34. package/lib/metadataTypes/TransactionalSMS.js +5 -5
  35. package/lib/metadataTypes/TriggeredSend.js +25 -50
  36. package/lib/metadataTypes/User.js +7 -4
  37. package/lib/metadataTypes/definitions/Asset.definition.js +1 -0
  38. package/lib/metadataTypes/definitions/AttributeGroup.definition.js +117 -106
  39. package/lib/metadataTypes/definitions/{SetDefinition.definition.js → AttributeSet.definition.js} +54 -27
  40. package/lib/metadataTypes/definitions/Automation.definition.js +74 -21
  41. package/lib/metadataTypes/definitions/DataExtension.definition.js +1 -0
  42. package/lib/metadataTypes/definitions/DataExtract.definition.js +1 -0
  43. package/lib/metadataTypes/definitions/EmailSend.definition.js +1 -0
  44. package/lib/metadataTypes/definitions/Event.definition.js +1 -0
  45. package/lib/metadataTypes/definitions/Filter.definition.js +1 -0
  46. package/lib/metadataTypes/definitions/ImportFile.definition.js +37 -6
  47. package/lib/metadataTypes/definitions/MobileKeyword.definition.js +1 -0
  48. package/lib/metadataTypes/definitions/Query.definition.js +1 -0
  49. package/lib/metadataTypes/definitions/Role.definition.js +1 -0
  50. package/lib/metadataTypes/definitions/TriggeredSend.definition.js +2 -0
  51. package/lib/metadataTypes/definitions/User.definition.js +1 -0
  52. package/lib/util/cache.js +9 -4
  53. package/lib/util/cli.js +40 -0
  54. package/lib/util/devops.js +13 -11
  55. package/lib/util/file.js +2 -2
  56. package/lib/util/init.js +84 -0
  57. package/lib/util/util.js +268 -137
  58. package/package.json +11 -11
  59. package/test/general.test.js +26 -0
  60. package/test/mockRoot/.mcdevrc.json +1 -1
  61. package/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json +52 -0
  62. package/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json +45 -0
  63. package/test/mockRoot/deploy/testInstance/testBU/dataExtract/testExisting_dataExtract.dataExtract-meta.json +35 -0
  64. package/test/mockRoot/deploy/testInstance/testBU/dataExtract/testNew_dataExtract.dataExtract-meta.json +35 -0
  65. package/test/mockRoot/deploy/testInstance/testBU/fileTransfer/testExisting_fileTransfer.fileTransfer-meta.json +17 -0
  66. package/test/mockRoot/deploy/testInstance/testBU/fileTransfer/testNew_fileTransfer.fileTransfer-meta.json +17 -0
  67. package/test/mockRoot/deploy/testInstance/testBU/importFile/testExisting_importFile.importFile-meta.json +29 -0
  68. package/test/mockRoot/deploy/testInstance/testBU/importFile/testNew_importFile.importFile-meta.json +29 -0
  69. package/test/mockRoot/deploy/testInstance/testBU/query/{testExistingQuery.query-meta.json → testExisting_query.query-meta.json} +2 -2
  70. package/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json +11 -0
  71. package/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql +6 -0
  72. package/test/mockRoot/deploy/testInstance/testBU/query/{testNewQuery.query-meta.json → testNew_query.query-meta.json} +2 -2
  73. package/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.json +6 -0
  74. package/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.ssjs +1 -0
  75. package/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.json +6 -0
  76. package/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.ssjs +1 -0
  77. package/test/mockRoot/deploy/testInstance/testBU/triggeredSend/testExisting_triggeredSend.triggeredSend-meta.json +29 -0
  78. package/test/mockRoot/deploy/testInstance/testBU/triggeredSend/testNew_triggeredSend.triggeredSend-meta.json +29 -0
  79. package/test/resourceFactory.js +132 -24
  80. package/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDCustomerKey=testExisting_userANDEmaillike@-response.xml +27 -0
  81. package/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDEmaillike@-response.xml +156 -0
  82. package/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml +87 -0
  83. package/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmaillike@-response.xml +156 -0
  84. package/test/resources/1111111/accountUser/retrieve-CustomerKey=testExisting_userANDActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml +27 -0
  85. package/test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserID=700301950-response.xml +60 -0
  86. package/test/resources/1111111/user/retrieve-expected.md +4 -2
  87. package/test/resources/9999999/attributeGroup/retrieve-expected.json +25 -0
  88. package/test/resources/9999999/attributeSet/retrieve-expected.json +748 -0
  89. package/test/resources/9999999/automation/build-expected.json +57 -0
  90. package/test/resources/9999999/automation/create-expected.json +45 -0
  91. package/test/resources/9999999/automation/create-testNew_automation-expected.md +28 -0
  92. package/test/resources/9999999/automation/delete-response.xml +40 -0
  93. package/test/resources/9999999/automation/patch_fixKeys-pause-expected.json +44 -0
  94. package/test/resources/9999999/automation/patch_fixKeys-schedule-expected.json +44 -0
  95. package/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +42 -0
  96. package/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-fixKey_pause-response.xml +42 -0
  97. package/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-fixKey_schedule-response.xml +42 -0
  98. package/test/resources/9999999/automation/perform-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +42 -0
  99. package/test/resources/9999999/automation/retrieve-expected.json +57 -0
  100. package/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md +30 -0
  101. package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +52 -0
  102. package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-pause-response.xml +38 -0
  103. package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-fixKey_pause-response.xml +52 -0
  104. package/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-fixKey_schedule-response.xml +52 -0
  105. package/test/resources/9999999/automation/schedule-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml +52 -0
  106. package/test/resources/9999999/automation/template-expected.json +57 -0
  107. package/test/resources/9999999/automation/update-expected.json +45 -0
  108. package/test/resources/9999999/automation/update-testExisting_automation-expected.md +28 -0
  109. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json +85 -0
  110. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-1f7f8788c560/patch-response.json +85 -0
  111. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/get-response.json +85 -0
  112. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json +85 -0
  113. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_pause/get-response.json +85 -0
  114. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_pause/patch-response.json +85 -0
  115. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_schedule/get-response.json +85 -0
  116. package/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-fixKey_schedule/patch-response.json +85 -0
  117. package/test/resources/9999999/automation/v1/automations/a8afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json +85 -0
  118. package/test/resources/9999999/automation/v1/automations/post-response.json +86 -0
  119. package/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/get-response.json +38 -0
  120. package/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/patch-response.json +38 -0
  121. package/test/resources/9999999/automation/v1/dataextracts/get-response.json +20 -0
  122. package/test/resources/9999999/automation/v1/dataextracts/post-response.json +38 -0
  123. package/test/resources/9999999/automation/v1/dataextracttypes/get-response.json +50 -0
  124. package/test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/get-response.json +18 -0
  125. package/test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/patch-response.json +18 -0
  126. package/test/resources/9999999/automation/v1/filetransfers/get-response.json +15 -0
  127. package/test/resources/9999999/automation/v1/filetransfers/post-response.json +18 -0
  128. package/test/resources/9999999/automation/v1/ftplocations/get-response.json +18 -0
  129. package/test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/patch-response.json +31 -0
  130. package/test/resources/9999999/automation/v1/imports/get-response.json +38 -0
  131. package/test/resources/9999999/automation/v1/imports/post-response.json +30 -0
  132. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dae/actions/start/post-response.txt +1 -0
  133. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/actions/start/post-response.txt +1 -0
  134. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json +2 -2
  135. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json +2 -2
  136. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json +17 -0
  137. package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/patch-response.json +18 -0
  138. package/test/resources/9999999/automation/v1/queries/get-response.json +22 -5
  139. package/test/resources/9999999/automation/v1/queries/post-response.json +2 -2
  140. package/test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/patch-response.json +10 -0
  141. package/test/resources/9999999/automation/v1/scripts/get-response.json +27 -0
  142. package/test/resources/9999999/automation/v1/scripts/post-response.json +10 -0
  143. package/test/resources/9999999/dataExtension/retrieve-Name=testExisting_dataExtension-response.xml +52 -0
  144. package/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtension-response.xml +98 -0
  145. package/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionORDataExtension.CustomerKey=testExisting_dataExtension-response.xml +99 -0
  146. package/test/resources/9999999/dataExtract/build-expected.json +35 -0
  147. package/test/resources/9999999/dataExtract/get-expected.json +39 -0
  148. package/test/resources/9999999/dataExtract/patch-expected.json +37 -0
  149. package/test/resources/9999999/dataExtract/post-expected.json +37 -0
  150. package/test/resources/9999999/dataExtract/template-expected.json +35 -0
  151. package/test/resources/9999999/dataFolder/retrieve-ContentType=automations-response.xml +48 -0
  152. package/test/resources/9999999/dataFolder/retrieve-ContentType=contextual_suppression_listORContentType=publicationORContentType=suppression_listORContentType=mysubsORContentType=list-response.xml +136 -0
  153. package/test/resources/9999999/dataFolder/retrieve-ContentType=queryactivity-response.xml +48 -0
  154. package/test/resources/9999999/dataFolder/retrieve-ContentType=ssjsactivity-response.xml +48 -0
  155. package/test/resources/9999999/dataFolder/retrieve-ContentType=triggered_send_journeybuilderORContentType=triggered_sendORContentType=hidden-response.xml +276 -0
  156. package/test/resources/9999999/dataFolder/retrieve-response.xml +45 -0
  157. package/test/resources/9999999/email/retrieve-response.xml +203 -0
  158. package/test/resources/9999999/emailSendDefinition/retrieve-IsPlatformObject=falseANDDescriptionnotEqualsSFSendDefinition-response.xml +85 -0
  159. package/test/resources/9999999/fileTransfer/build-expected.json +15 -0
  160. package/test/resources/9999999/fileTransfer/get-expected.json +17 -0
  161. package/test/resources/9999999/fileTransfer/patch-expected.json +17 -0
  162. package/test/resources/9999999/fileTransfer/post-expected.json +17 -0
  163. package/test/resources/9999999/fileTransfer/template-expected.json +15 -0
  164. package/test/resources/9999999/hub/v1/contacts/schema/attributeGroups/get-response.json +585 -0
  165. package/test/resources/9999999/hub/v1/contacts/schema/setDefinitions/get-response.json +19807 -0
  166. package/test/resources/9999999/importFile/build-expected.json +27 -0
  167. package/test/resources/9999999/importFile/get-expected.json +29 -0
  168. package/test/resources/9999999/importFile/patch-expected.json +29 -0
  169. package/test/resources/9999999/importFile/post-expected.json +29 -0
  170. package/test/resources/9999999/importFile/template-expected.json +27 -0
  171. package/test/resources/9999999/legacy/v1/beta/automations/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/get-response.json +21 -0
  172. package/test/resources/9999999/legacy/v1/beta/automations/notifications/RkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow/post-response.json +0 -0
  173. package/test/resources/9999999/legacy/v1/beta/bulk/automations/automation/definition/get-response.json +30 -0
  174. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation-response.xml +30 -0
  175. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixKey_pause-response.xml +32 -0
  176. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixKey_schedule-response.xml +32 -0
  177. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixedKey_paused-response.xml +32 -0
  178. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_fixedKey_scheduled-response.xml +32 -0
  179. package/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_pause-response.xml +30 -0
  180. package/test/resources/9999999/program/retrieve-CustomerKey=testNew_automation-response.xml +30 -0
  181. package/test/resources/9999999/program/retrieve-Name=testExisting_automation-response.xml +31 -0
  182. package/test/resources/9999999/program/retrieve-response.xml +50 -0
  183. package/test/resources/9999999/query/build-expected.json +2 -2
  184. package/test/resources/9999999/query/get-expected.json +2 -2
  185. package/test/resources/9999999/query/get2-expected.json +2 -2
  186. package/test/resources/9999999/query/patch-expected.json +2 -2
  187. package/test/resources/9999999/query/patch_fixKeys-expected.json +11 -0
  188. package/test/resources/9999999/query/patch_fixKeys-expected.sql +6 -0
  189. package/test/resources/9999999/query/post-expected.json +2 -2
  190. package/test/resources/9999999/query/template-expected.json +2 -2
  191. package/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixKeysANDStatus=Active-response.xml +30 -0
  192. package/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixedKeysANDStatus=Active-response.xml +30 -0
  193. package/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testNew_queryANDStatus=Active-response.xml +30 -0
  194. package/test/resources/9999999/script/build-expected.json +6 -0
  195. package/test/resources/9999999/script/build-expected.ssjs +1 -0
  196. package/test/resources/9999999/script/get-expected.json +8 -0
  197. package/test/resources/9999999/script/get-expected.ssjs +1 -0
  198. package/test/resources/9999999/script/get_noScriptTag-expected.html +1 -0
  199. package/test/resources/9999999/script/get_noScriptTag-expected.json +8 -0
  200. package/test/resources/9999999/script/patch-expected.json +8 -0
  201. package/test/resources/9999999/script/patch-expected.ssjs +1 -0
  202. package/test/resources/9999999/script/post-expected.json +8 -0
  203. package/test/resources/9999999/script/post-expected.ssjs +1 -0
  204. package/test/resources/9999999/script/template-expected.json +6 -0
  205. package/test/resources/9999999/script/template-expected.ssjs +1 -0
  206. package/test/resources/9999999/triggeredSend/build-expected.json +29 -0
  207. package/test/resources/9999999/triggeredSend/get-expected.json +29 -0
  208. package/test/resources/9999999/triggeredSend/patch-expected.json +29 -0
  209. package/test/resources/9999999/triggeredSend/post-expected.json +29 -0
  210. package/test/resources/9999999/triggeredSend/template-expected.json +29 -0
  211. package/test/resources/9999999/triggeredSendDefinition/create-response.xml +75 -0
  212. package/test/resources/9999999/triggeredSendDefinition/delete-response.xml +36 -0
  213. package/test/resources/9999999/triggeredSendDefinition/{retrieve-response.xml → retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml} +4 -4
  214. package/test/resources/9999999/triggeredSendDefinition/update-response.xml +74 -0
  215. package/test/type.attributeGroup.test.js +55 -0
  216. package/test/type.attributeSet.test.js +55 -0
  217. package/test/type.automation.test.js +886 -0
  218. package/test/type.dataExtension.test.js +3 -1
  219. package/test/type.dataExtract.test.js +187 -0
  220. package/test/type.fileTransfer.test.js +185 -0
  221. package/test/type.importFile.test.js +186 -0
  222. package/test/type.mobileKeyword.test.js +0 -1
  223. package/test/type.query.test.js +497 -33
  224. package/test/type.script.test.js +367 -0
  225. package/test/type.triggeredSend.test.js +152 -0
  226. package/test/type.user.test.js +37 -11
  227. package/test/utils.js +10 -6
  228. package/.coverage-comment-template.md +0 -20
  229. package/lib/metadataTypes/SetDefinition.js +0 -37
  230. /package/test/mockRoot/deploy/testInstance/testBU/query/{testExistingQuery.query-meta.sql → testExisting_query.query-meta.sql} +0 -0
  231. /package/test/mockRoot/deploy/testInstance/testBU/query/{testNewQuery.query-meta.sql → testNew_query.query-meta.sql} +0 -0
  232. /package/test/resources/1111111/accountUser/{retrieve-response.xml → retrieve-ActiveFlag=trueANDCustomerKey=testExisting_userANDEmaillike@-response.xml} +0 -0
  233. /package/test/resources/1111111/accountUserAccount/{retrieve-response.xml → retrieve-AccountUser.AccountUserIDIN700301950,700301951,7471228-response.xml} +0 -0
  234. /package/test/resources/1111111/businessUnit/{retrieve-response.xml → retrieve-ID=1111111-response.xml} +0 -0
  235. /package/test/resources/1111111/list/{retrieve-response.xml → retrieve-CustomerKey=All SubscribersORListName=All Subscribers-response.xml} +0 -0
  236. /package/test/resources/1111111/role/{retrieve-response.xml → retrieve-IsPrivate=false-response.xml} +0 -0
  237. /package/test/resources/9999999/queryDefinition/{retrieve-response.xml → retrieve-CustomerKey=testExisting_queryANDStatus=Active-response.xml} +0 -0
@@ -11,6 +11,7 @@ module.exports = {
11
11
  lastmodNameField: 'modifiedBy',
12
12
  nameField: 'name',
13
13
  restPagination: true,
14
+ maxKeyLength: 36, // confirmed max length
14
15
  type: 'dataExtract',
15
16
  typeDescription: 'Creates zipped files in your FTP directory or convert XML into CSV.',
16
17
  typeRetrieveByDefault: true,
@@ -14,6 +14,7 @@ module.exports = {
14
14
  lastmodDateField: 'ModifiedDate',
15
15
  lastmodNameField: null,
16
16
  restPagination: null,
17
+ maxKeyLength: 36, // confirmed max length
17
18
  type: 'emailSend',
18
19
  soapType: 'emailSendDefinition',
19
20
  typeDescription: 'Mainly used in Automations as "Send Email Activity".',
@@ -11,6 +11,7 @@ module.exports = {
11
11
  lastmodDateField: 'modifiedDate',
12
12
  lastmodNameField: 'modifiedBy',
13
13
  restPagination: true,
14
+ maxKeyLength: 200, // confirmed max length
14
15
  type: 'event',
15
16
  typeDescription: 'Used in Journeys (Interactions) to define Entry Events.',
16
17
  typeRetrieveByDefault: true,
@@ -11,6 +11,7 @@ module.exports = {
11
11
  lastmodDateField: 'modifiedDate',
12
12
  lastmodNameField: null,
13
13
  restPagination: true,
14
+ maxKeyLength: 36, // confirmed max length
14
15
  type: 'filter',
15
16
  typeDescription:
16
17
  'BETA: Part of how filtered Data Extensions are created. Depends on type "FilterDefinitions".',
@@ -22,6 +22,7 @@ module.exports = {
22
22
  DataExtension: 255,
23
23
  Email: 0,
24
24
  },
25
+ maxKeyLength: 36, // confirmed max length
25
26
  type: 'importFile',
26
27
  typeDescription: 'Reads files in FTP directory for further processing.',
27
28
  typeRetrieveByDefault: true,
@@ -221,11 +222,41 @@ module.exports = {
221
222
  retrieving: true,
222
223
  template: true,
223
224
  },
224
- c__dataAction: { skipValidation: true },
225
- r__dataExtension_CustomerKey: { skipValidation: true },
226
- c__destinationType: { skipValidation: true },
227
- r__list_PathName: { skipValidation: true },
228
- r__fileLocation_name: { skipValidation: true },
229
- c__subscriberImportType: { skipValidation: true },
225
+ c__dataAction: {
226
+ isCreateable: false,
227
+ isUpdateable: false,
228
+ retrieving: true,
229
+ template: true,
230
+ },
231
+ r__dataExtension_CustomerKey: {
232
+ isCreateable: false,
233
+ isUpdateable: false,
234
+ retrieving: true,
235
+ template: true,
236
+ },
237
+ c__destinationType: {
238
+ isCreateable: false,
239
+ isUpdateable: false,
240
+ retrieving: true,
241
+ template: true,
242
+ },
243
+ r__list_PathName: {
244
+ isCreateable: false,
245
+ isUpdateable: false,
246
+ retrieving: true,
247
+ template: true,
248
+ },
249
+ r__fileLocation_name: {
250
+ isCreateable: false,
251
+ isUpdateable: false,
252
+ retrieving: true,
253
+ template: true,
254
+ },
255
+ c__subscriberImportType: {
256
+ isCreateable: false,
257
+ isUpdateable: false,
258
+ retrieving: true,
259
+ template: true,
260
+ },
230
261
  },
231
262
  };
@@ -12,6 +12,7 @@ module.exports = {
12
12
  lastmodNameField: null,
13
13
  restPagination: true,
14
14
  restPageSize: 50,
15
+ maxKeyLength: 50, // assumed max length
15
16
  type: 'mobileKeyword',
16
17
  typeDescription: 'Used for managing subscriptions for Mobile numbers in Mobile Connect',
17
18
  typeRetrieveByDefault: true,
@@ -21,6 +21,7 @@ module.exports = {
21
21
  Overwrite: 0,
22
22
  Update: 1,
23
23
  },
24
+ maxKeyLength: 36, // confirmed max length
24
25
  type: 'query',
25
26
  typeDescription: 'Select & transform data using SQL.',
26
27
  typeRetrieveByDefault: true,
@@ -23,6 +23,7 @@ module.exports = {
23
23
  createdNameField: null,
24
24
  lastmodDateField: 'ModifiedDate',
25
25
  lastmodNameField: null,
26
+ maxKeyLength: 36, // confirmed max length
26
27
  type: 'role',
27
28
  typeDescription:
28
29
  'User Roles define groups that are used to grant users access to SFMC systems.',
@@ -21,6 +21,7 @@ module.exports = {
21
21
  lastmodDateField: 'ModifiedDate',
22
22
  lastmodNameField: null,
23
23
  restPagination: null,
24
+ maxKeyLength: 36, // confirmed max length
24
25
  type: 'triggeredSend',
25
26
  soapType: 'triggeredSendDefinition',
26
27
  typeDescription: 'DEPRECATED: Sends emails via API or DataExtension Event.',
@@ -534,6 +535,7 @@ module.exports = {
534
535
  r__folder_Path: { skipValidation: true },
535
536
  r__assetMessage_Name_readOnly: { skipValidation: true },
536
537
  r__assetMessage_Key: { skipValidation: true },
538
+ r__email_Name: { skipValidation: true },
537
539
  r__list_PathName: { skipValidation: true },
538
540
  },
539
541
  };
@@ -12,6 +12,7 @@ module.exports = {
12
12
  createdNameField: null,
13
13
  lastmodDateField: 'ModifiedDate',
14
14
  lastmodNameField: 'Client.ModifiedBy',
15
+ maxKeyLength: 50, // confirmed max length
15
16
  type: 'user',
16
17
  soapType: 'AccountUser',
17
18
  typeDescription: 'Marketing Cloud users',
package/lib/util/cache.js CHANGED
@@ -72,10 +72,15 @@ module.exports = {
72
72
  * @returns {void}
73
73
  */
74
74
  mergeMetadata: (type, metadataMap, overrideMID) => {
75
- dataStore[overrideMID || currentMID][type] = Object.assign(
76
- metadataMap,
77
- dataStore[currentMID][type]
78
- );
75
+ // ensure cache exists for type
76
+ dataStore[currentMID][type] ||= {};
77
+ // if overrideMID is provided, create a copy of current MID cache
78
+ if (overrideMID) {
79
+ // ! needs to be verified if this is actually needed. When discovering an issue with this method actually overriting metadataMap, this copy-logic was present and i did not want to break things
80
+ dataStore[overrideMID][type] = Object.assign({}, dataStore[currentMID][type]);
81
+ }
82
+ // merge metadataMap into existing cache
83
+ Object.assign(dataStore[overrideMID || currentMID][type] || {}, metadataMap);
79
84
  },
80
85
  /**
81
86
  * standardized method for getting data from cache.
package/lib/util/cli.js CHANGED
@@ -53,6 +53,46 @@ const Cli = {
53
53
  return null;
54
54
  }
55
55
  },
56
+
57
+ /**
58
+ *
59
+ * @param {TYPE.SupportedMetadataTypes} type limit execution to given metadata type
60
+ * @param {TYPE.SupportedMetadataTypes[]} dependentTypes types that depent on type
61
+ * @returns {Promise.<boolean>} true if user wants to continue with retrieve
62
+ */
63
+ async postFixKeysReretrieve(type, dependentTypes) {
64
+ if (Util.isTrue(Util.skipInteraction?.fixKeysReretrieve)) {
65
+ return true;
66
+ } else if (Util.isFalse(Util.skipInteraction?.fixKeysReretrieve)) {
67
+ return false;
68
+ } else {
69
+ const now = await inquirer.prompt([
70
+ {
71
+ type: 'confirm',
72
+ name: 'fixKeysReretrieve',
73
+ message: `Do you want to re-retrieve dependent types (${dependentTypes.join(
74
+ ', '
75
+ )}) now?`,
76
+ default: true,
77
+ },
78
+ ]);
79
+ if (Util.OPTIONS._multiBuExecution) {
80
+ const remember = await inquirer.prompt([
81
+ {
82
+ type: 'confirm',
83
+ name: 'rememberFixKeysReretrieve',
84
+ message: `Remember answer for other BUs?`,
85
+ default: true,
86
+ },
87
+ ]);
88
+ if (remember.rememberFixKeysReretrieve) {
89
+ Util.skipInteraction ||= {};
90
+ Util.skipInteraction.fixKeysReretrieve = now.fixKeysReretrieve;
91
+ }
92
+ }
93
+ return now.fixKeysReretrieve;
94
+ }
95
+ },
56
96
  /**
57
97
  * helper that logs to cli which credentials are already existing in our config file
58
98
  *
@@ -293,17 +293,19 @@ const DevOps = {
293
293
  }
294
294
 
295
295
  /** @type {TYPE.DeltaPkgItem[]} */
296
- const copied = delta.map((file) =>
297
- File.copyFile(
298
- file.file,
299
- path
300
- .normalize(file.file)
301
- .replace(
302
- path.normalize(properties.directories.retrieve),
303
- path.normalize(properties.directories.deploy)
304
- )
305
- )
306
- );
296
+ const copied = delta
297
+ .filter((file) => !file.file.endsWith('.md')) // filter documentation files
298
+ .map((file) =>
299
+ File.copyFile(
300
+ file.file,
301
+ path
302
+ .normalize(file.file)
303
+ .replace(
304
+ path.normalize(properties.directories.retrieve),
305
+ path.normalize(properties.directories.deploy)
306
+ )
307
+ )
308
+ );
307
309
  const results = await Promise.all(copied);
308
310
  const failed = results.filter((result) => result.status === 'failed');
309
311
  const skipped = results.filter((result) => result.status === 'skipped');
package/lib/util/file.js CHANGED
@@ -381,7 +381,7 @@ const File = {
381
381
  * @param {string | string[]} directory directory where the file is stored
382
382
  * @param {string} filename name of the file without '.json' ending
383
383
  * @param {string} filetype filetype suffix
384
- * @param {string} [encoding='utf8'] read file with encoding (defaults to utf-8)
384
+ * @param {string} [encoding] read file with encoding (defaults to utf-8)
385
385
  * @returns {Promise.<string> | void} file contents; void on error
386
386
  */
387
387
  readFilteredFilename: function (directory, filename, filetype, encoding) {
@@ -514,7 +514,7 @@ const File = {
514
514
  /**
515
515
  * Initalises Prettier formatting lib async.
516
516
  *
517
- * @param {string} [filetype='html'] filetype ie. JSON or SSJS
517
+ * @param {string} [filetype] filetype ie. JSON or SSJS
518
518
  * @returns {Promise.<boolean>} success of config load
519
519
  */
520
520
  async initPrettier(filetype = 'html') {
package/lib/util/init.js CHANGED
@@ -8,6 +8,8 @@ const InitNpm = require('./init.npm');
8
8
  const InitConfig = require('./init.config');
9
9
  const inquirer = require('inquirer');
10
10
  const Util = require('./util');
11
+ const fs = require('node:fs');
12
+ const path = require('node:path');
11
13
 
12
14
  /**
13
15
  * CLI helper class
@@ -22,6 +24,10 @@ const Init = {
22
24
  * @returns {Promise.<void>} -
23
25
  */
24
26
  async initProject(properties, credentialName) {
27
+ if (!(await Init._checkPathForCloud())) {
28
+ return;
29
+ }
30
+
25
31
  const skipInteraction = Util.skipInteraction;
26
32
  if (!properties) {
27
33
  // try to get cached properties because we return null in case of a crucial error
@@ -192,6 +198,10 @@ const Init = {
192
198
  * @returns {Promise.<void>} -
193
199
  */
194
200
  async joinProject() {
201
+ if (!(await Init._checkPathForCloud())) {
202
+ return;
203
+ }
204
+
195
205
  const responses = await inquirer.prompt([
196
206
  {
197
207
  type: 'confirm',
@@ -217,6 +227,9 @@ const Init = {
217
227
  ]);
218
228
  const repoName = gitRepoQs.gitRepoUrl.split('/').pop().replace('.git', '');
219
229
  // clone repo into current folder
230
+ Util.logger.info(
231
+ 'Cloning initiated. You might be asked for your Git credentials in a pop-up window in a few seconds.'
232
+ );
220
233
  Util.execSync(
221
234
  'git',
222
235
  [
@@ -227,6 +240,16 @@ const Init = {
227
240
  gitRepoQs.gitRepoUrl,
228
241
  ].filter(Boolean)
229
242
  );
243
+
244
+ if (!fs.existsSync(repoName)) {
245
+ Util.logger.error(
246
+ 'Could not clone repository. Please check your Git-Repository URL as well as your credentials and try again.'
247
+ );
248
+ Util.logger.info(
249
+ 'Check if you need an "API-Token" instead of your normal user password to authenticate'
250
+ );
251
+ return;
252
+ }
230
253
  // make sure we switch to the new subfolder or else the rest will fail
231
254
  process.chdir(repoName);
232
255
 
@@ -357,6 +380,10 @@ const Init = {
357
380
  * @returns {Promise.<boolean>} success flag
358
381
  */
359
382
  async upgradeProject(properties, initial, repoName) {
383
+ if (!(await Init._checkPathForCloud())) {
384
+ return;
385
+ }
386
+
360
387
  let status;
361
388
  const versionBeforeUpgrade = properties?.version || '0.0.0';
362
389
  if (!initial) {
@@ -390,9 +417,66 @@ const Init = {
390
417
 
391
418
  return true;
392
419
  },
420
+ /**
421
+ * check if git repo is being saved on a cloud service and warn the user
422
+ *
423
+ * @private
424
+ * @returns {void} throws errors if problems were found
425
+ */
426
+ async _checkPathForCloud() {
427
+ const absolutePath = path.resolve('');
428
+ // popular cloud services and their respective default name for the absolute path
429
+ // * CloudDocs is the default folder name for iCloud
430
+ const cloudServices = ['Dropbox', 'OneDrive', 'Google Drive', 'iCloud', 'CloudDocs'];
431
+ let cloudServiceFound = false;
432
+ for (const variable in cloudServices) {
433
+ if (absolutePath.includes(cloudServices[variable])) {
434
+ Util.logger.warn(
435
+ `It seems your project folder will be synchronized via '${
436
+ cloudServices[variable] === 'CloudDocs' ? 'iCloud' : cloudServices[variable]
437
+ }'. This can reduce the overall performance of your computer due to conflicts with Git.`
438
+ );
439
+ Util.logger.warn(
440
+ `We strongly recommend moving your project folder outside of the '${
441
+ cloudServices[variable] === 'CloudDocs' ? 'iCloud' : cloudServices[variable]
442
+ }' folder.`
443
+ );
444
+ cloudServiceFound = true;
445
+ }
446
+ }
447
+ if (!cloudServiceFound && absolutePath.includes(process.env.USERPROFILE)) {
448
+ // warn user to not place project folder into user profile folder
449
+ Util.logger.warn(
450
+ `It seems your project folder is located in your user profile's default folder which is often synchronized to webservices like ${cloudServices.join(
451
+ ', '
452
+ )}. This can reduce the overall performance of your computer due to conflicts between with Git.`
453
+ );
454
+ Util.logger.warn(
455
+ `We strongly recommend moving your project folder outside of this folder.`
456
+ );
457
+ cloudServiceFound = true;
458
+ }
459
+ if (cloudServiceFound) {
460
+ const responses = await inquirer.prompt([
461
+ {
462
+ type: 'confirm',
463
+ name: 'ignoreCloudWarning',
464
+ message: 'Do you want to continue anyways?',
465
+ default: false,
466
+ },
467
+ ]);
468
+ if (!responses.ignoreCloudWarning) {
469
+ Util.logger.error('Exiting due to cloud service warning');
470
+ return false;
471
+ }
472
+ }
473
+ return true;
474
+ },
475
+
393
476
  /**
394
477
  * finds credentials that are set up in config but not in auth file
395
478
  *
479
+ * @private
396
480
  * @param {TYPE.Mcdevrc} properties javascript object in .mcdevrc.json
397
481
  * @returns {string[]} list of credential names
398
482
  */