mcdev 5.0.1 → 5.0.2

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 (67) hide show
  1. package/.eslintrc.json +1 -0
  2. package/.github/ISSUE_TEMPLATE/bug.yml +1 -0
  3. package/.husky/commit-msg +1 -1
  4. package/.husky/post-checkout +34 -3
  5. package/.husky/post-merge +21 -0
  6. package/.husky/pre-commit +1 -0
  7. package/docs/dist/documentation.md +60 -15
  8. package/lib/Deployer.js +0 -1
  9. package/lib/cli.js +8 -8
  10. package/lib/index.js +2 -1
  11. package/lib/metadataTypes/Asset.js +4 -2
  12. package/lib/metadataTypes/Automation.js +39 -28
  13. package/lib/metadataTypes/DataExtension.js +1 -3
  14. package/lib/metadataTypes/DataExtensionField.js +5 -5
  15. package/lib/metadataTypes/Journey.js +11 -10
  16. package/lib/metadataTypes/MetadataType.js +34 -7
  17. package/lib/metadataTypes/MobileKeyword.js +165 -20
  18. package/lib/metadataTypes/MobileMessage.js +20 -28
  19. package/lib/metadataTypes/Role.js +2 -3
  20. package/lib/metadataTypes/TransactionalSMS.js +5 -5
  21. package/lib/metadataTypes/User.js +3 -17
  22. package/lib/metadataTypes/definitions/MobileKeyword.definition.js +19 -7
  23. package/lib/metadataTypes/definitions/MobileMessage.definition.js +50 -8
  24. package/lib/metadataTypes/definitions/User.definition.js +1 -0
  25. package/lib/util/auth.js +4 -1
  26. package/lib/util/cli.js +1 -1
  27. package/lib/util/file.js +5 -3
  28. package/lib/util/util.js +1 -0
  29. package/package.json +9 -9
  30. package/test/mockRoot/.mcdevrc.json +3 -1
  31. package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/{testNew_keyword.mobileKeyword-meta.json → 4912312345678.TESTNEW_KEYWORD.mobileKeyword-meta.json} +1 -4
  32. package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/{testNew_keyword_blocked.mobileKeyword-meta.json → 4912312345678.TESTNEW_KEYWORD_BLOCKED.mobileKeyword-meta.json} +1 -4
  33. package/test/mockRoot/deploy/testInstance/testBU/transactionalSMS/testExisting_tsms.transactionalSMS-meta.json +1 -1
  34. package/test/mockRoot/deploy/testInstance/testBU/transactionalSMS/testNew_tsms.transactionalSMS-meta.json +1 -1
  35. package/test/resources/1111111/user/retrieve-expected.md +19 -0
  36. package/test/resources/9999999/dataExtension/retrieve-expected.md +18 -0
  37. package/test/resources/9999999/journey/build-expected.json +1 -1
  38. package/test/resources/9999999/journey/get-expected.json +1 -1
  39. package/test/resources/9999999/journey/put-expected.json +1 -1
  40. package/test/resources/9999999/journey/template-expected.json +1 -1
  41. package/test/resources/9999999/legacy/v1/beta/mobile/keyword/NXV4ZFMwTEFwRVczd3RaLUF5X3p5dzo4Njow/get-response.json +1 -1
  42. package/test/resources/9999999/legacy/v1/beta/mobile/keyword/get-response.json +1 -1
  43. package/test/resources/9999999/legacy/v1/beta/mobile/message/NTIzOjc4OjA/get-response.json +1 -1
  44. package/test/resources/9999999/legacy/v1/beta/mobile/message/get-response.json +1 -1
  45. package/test/resources/9999999/messaging/v1/sms/definitions/post-response.json +1 -1
  46. package/test/resources/9999999/messaging/v1/sms/definitions/testExisting_tsms/get-response.json +1 -1
  47. package/test/resources/9999999/messaging/v1/sms/definitions/testExisting_tsms/patch-response.json +1 -1
  48. package/test/resources/9999999/mobileKeyword/build-expected.json +1 -4
  49. package/test/resources/9999999/mobileKeyword/get-expected.json +1 -4
  50. package/test/resources/9999999/mobileKeyword/post-create-expected.json +1 -4
  51. package/test/resources/9999999/mobileKeyword/template-expected.json +1 -4
  52. package/test/resources/9999999/query/build-expected.sql +1 -1
  53. package/test/resources/9999999/query/get-expected.sql +1 -1
  54. package/test/resources/9999999/query/patch-expected.sql +1 -1
  55. package/test/resources/9999999/query/post-expected.sql +1 -1
  56. package/test/resources/9999999/query/template-expected.sql +1 -1
  57. package/test/resources/9999999/transactionalSMS/build-expected.json +1 -1
  58. package/test/resources/9999999/transactionalSMS/get-expected.json +1 -1
  59. package/test/resources/9999999/transactionalSMS/patch-expected.json +1 -1
  60. package/test/resources/9999999/transactionalSMS/post-expected.json +1 -1
  61. package/test/resources/9999999/transactionalSMS/template-expected.json +1 -1
  62. package/test/type.dataExtension.test.js +13 -1
  63. package/test/type.mobileKeyword.test.js +57 -19
  64. package/test/type.user.test.js +30 -1
  65. package/test/utils.js +10 -0
  66. /package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/{testNew_keyword.mobileKeyword-meta.amp → 4912312345678.TESTNEW_KEYWORD.mobileKeyword-meta.amp} +0 -0
  67. /package/test/mockRoot/deploy/testInstance/testBU/mobileKeyword/{testNew_keyword_blocked.mobileKeyword-meta.amp → 4912312345678.TESTNEW_KEYWORD_BLOCKED.mobileKeyword-meta.amp} +0 -0
package/.eslintrc.json CHANGED
@@ -84,6 +84,7 @@
84
84
  }
85
85
  }
86
86
  ],
87
+ "jsdoc/tag-lines": ["warn", "any", { "startLines": 1 }],
87
88
  "spaced-comment": ["warn", "always", { "block": { "exceptions": ["*"], "balanced": true } }]
88
89
  },
89
90
  "overrides": [
@@ -39,6 +39,7 @@ body:
39
39
  label: Version
40
40
  description: What version of our software are you running? (mcdev --version)
41
41
  options:
42
+ - 5.0.2
42
43
  - 5.0.1
43
44
  - 5.0.0
44
45
  - 4.3.4
package/.husky/commit-msg CHANGED
@@ -2,7 +2,7 @@
2
2
  . "$(dirname "$0")/_/husky.sh"
3
3
  INPUT_FILE=$1
4
4
  START_LINE=`head -n1 $INPUT_FILE`
5
- PATTERN="^(#[[:digit:]]|Merge)"
5
+ PATTERN="^(#[[:digit:]]|Merge|Revert)"
6
6
 
7
7
  if ! [[ "$START_LINE" =~ $PATTERN ]] ; then
8
8
  echo "Bad commit message, see example: \"#431 commit message\", you provided: \"$START_LINE\""
@@ -1,5 +1,36 @@
1
1
  #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ # ### git commit message template ###
2
5
  git config commit.template .git/templatemessage
3
- TICKETID=`git rev-parse --abbrev-ref HEAD | LC_ALL=en_US.utf8 grep -oP '((feature|bug|bugfix|fix|hotfix|task|chore)\/)\K\d{1,7}'`
4
- echo "[POST_CHECKOUT] Setting template commit to $TICKETID"
5
- echo "#$TICKETID: " > ".git/templatemessage"
6
+ TICKETID=`git rev-parse --abbrev-ref HEAD | LC_ALL=en_US.utf8 grep -oP '^((feature|bug|bugfix|fix|hotfix|task|chore)\/)?\K\d{1,7}' || true`
7
+ if [ -z "$TICKETID" ]
8
+ then
9
+ TICKETID="0"
10
+ fi
11
+ TEMPLATE="#$TICKETID: "
12
+ echo "[POST_CHECKOUT] Setting template commit to '$TEMPLATE'"
13
+ echo $TEMPLATE > ".git/templatemessage"
14
+
15
+
16
+ # ### run npm install ###
17
+ echo "[POST-CHECKOUT] 📦 Checking for changes to dependencies"
18
+ # define how to split strings into array elements
19
+ IFS=$'\n'
20
+ # $1 is the new HEAD pointer
21
+ NEWHEAD=$1
22
+ # $2 is the previous HEAD pointer
23
+ OLDHEAD=$2
24
+ # extract all paths to package-lock.json files
25
+ PACKAGE_LOCK_REGEX="(^package-lock\.json)"
26
+ PACKAGES=$(git diff --name-only $NEWHEAD $OLDHEAD | grep -E $PACKAGE_LOCK_REGEX || true)
27
+
28
+ if [[ ${PACKAGES[@]} ]]; then
29
+ for package in $PACKAGES; do
30
+ echo "📦 $package was changed."
31
+ done
32
+ echo "📦 Running npm install to update your dependencies..."
33
+ npm install
34
+ else
35
+ echo "📦 All packages up-to-date. No need to run npm install."
36
+ fi
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ # ### run npm install ###
3
+ . "$(dirname "$0")/_/husky.sh"
4
+
5
+
6
+ echo "[POST-MERGE] 📦 Checking for changes to dependencies"
7
+
8
+ IFS=$'\n'
9
+ # extract all paths to package-lock.json files
10
+ PACKAGE_LOCK_REGEX="(^package-lock\.json)"
11
+ PACKAGES=$(git diff --name-only HEAD^1 HEAD | grep -E $PACKAGE_LOCK_REGEX || true)
12
+
13
+ if [[ ${PACKAGES[@]} ]]; then
14
+ for package in $PACKAGES; do
15
+ echo "📦 $package was changed."
16
+ done
17
+ echo "📦 Running npm install to update your dependencies..."
18
+ npm install
19
+ else
20
+ echo "📦 All packages up-to-date. No need to run npm install."
21
+ fi
package/.husky/pre-commit CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/bin/sh
2
2
  . "$(dirname "$0")/_/husky.sh"
3
+
3
4
  npm run docs
4
5
  git update-index --add docs/dist/documentation.md
5
6
  npx --no lint-staged
@@ -1212,7 +1212,7 @@ Automation MetadataType
1212
1212
  * [.update(metadata, metadataBefore)](#Automation.update) ⇒ <code>Promise</code>
1213
1213
  * [.preDeployTasks(metadata)](#Automation.preDeployTasks) ⇒ <code>Promise.&lt;TYPE.AutomationItem&gt;</code>
1214
1214
  * [.validateDeployMetadata(metadata)](#Automation.validateDeployMetadata) ⇒ <code>boolean</code>
1215
- * [.postDeployTasks(metadata, originalMetadata)](#Automation.postDeployTasks) ⇒ <code>Promise.&lt;void&gt;</code>
1215
+ * [.postDeployTasks(metadataMap, originalMetadataMap)](#Automation.postDeployTasks) ⇒ <code>Promise.&lt;void&gt;</code>
1216
1216
  * [.setFolderPath(metadata)](#Automation.setFolderPath)
1217
1217
  * [.setFolderId(metadata)](#Automation.setFolderId)
1218
1218
  * [.parseMetadata(metadata)](#Automation.parseMetadata) ⇒ <code>TYPE.AutomationItem</code> \| <code>void</code>
@@ -1345,7 +1345,7 @@ Whitelisted Activites are deployed but require configuration
1345
1345
 
1346
1346
  <a name="Automation.postDeployTasks"></a>
1347
1347
 
1348
- ### Automation.postDeployTasks(metadata, originalMetadata) ⇒ <code>Promise.&lt;void&gt;</code>
1348
+ ### Automation.postDeployTasks(metadataMap, originalMetadataMap) ⇒ <code>Promise.&lt;void&gt;</code>
1349
1349
  Gets executed after deployment of metadata type
1350
1350
 
1351
1351
  **Kind**: static method of [<code>Automation</code>](#Automation)
@@ -1353,8 +1353,8 @@ Gets executed after deployment of metadata type
1353
1353
 
1354
1354
  | Param | Type | Description |
1355
1355
  | --- | --- | --- |
1356
- | metadata | <code>TYPE.AutomationMap</code> | metadata mapped by their keyField |
1357
- | originalMetadata | <code>TYPE.AutomationMap</code> | metadata to be updated (contains additioanl fields) |
1356
+ | metadataMap | <code>TYPE.AutomationMap</code> | metadata mapped by their keyField |
1357
+ | originalMetadataMap | <code>TYPE.AutomationMap</code> | metadata to be updated (contains additioanl fields) |
1358
1358
 
1359
1359
  <a name="Automation.setFolderPath"></a>
1360
1360
 
@@ -3167,6 +3167,7 @@ Provides default functionality that can be overwritten by child metadata type cl
3167
3167
  * [.getSOAPErrorMsg(ex)](#MetadataType.getSOAPErrorMsg) ⇒ <code>string</code>
3168
3168
  * [.retrieveSOAP(retrieveDir, [requestParams], [singleRetrieve], [additionalFields])](#MetadataType.retrieveSOAP) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMapObj&gt;</code>
3169
3169
  * [.retrieveREST(retrieveDir, uri, [templateVariables], [singleRetrieve])](#MetadataType.retrieveREST) ⇒ <code>Promise.&lt;{metadata: (TYPE.MetadataTypeMap\|TYPE.MetadataTypeItem), type: string}&gt;</code>
3170
+ * [.runDocumentOnRetrieve([singleRetrieve], metadataMap)](#MetadataType.runDocumentOnRetrieve) ⇒ <code>Promise.&lt;void&gt;</code>
3170
3171
  * [.parseResponseBody(body, [singleRetrieve])](#MetadataType.parseResponseBody) ⇒ <code>TYPE.MetadataTypeMap</code>
3171
3172
  * [.deleteFieldByDefinition(metadataEntry, fieldPath, definitionProperty, origin)](#MetadataType.deleteFieldByDefinition) ⇒ <code>void</code>
3172
3173
  * [.removeNotCreateableFields(metadataEntry)](#MetadataType.removeNotCreateableFields) ⇒ <code>void</code>
@@ -3632,6 +3633,19 @@ Retrieves Metadata for Rest Types
3632
3633
  | [templateVariables] | <code>TYPE.TemplateMap</code> | variables to be replaced in the metadata |
3633
3634
  | [singleRetrieve] | <code>string</code> \| <code>number</code> | key of single item to filter by |
3634
3635
 
3636
+ <a name="MetadataType.runDocumentOnRetrieve"></a>
3637
+
3638
+ ### MetadataType.runDocumentOnRetrieve([singleRetrieve], metadataMap) ⇒ <code>Promise.&lt;void&gt;</code>
3639
+ helper for [retrieveREST](retrieveREST) and [retrieveSOAP](retrieveSOAP)
3640
+
3641
+ **Kind**: static method of [<code>MetadataType</code>](#MetadataType)
3642
+ **Returns**: <code>Promise.&lt;void&gt;</code> - -
3643
+
3644
+ | Param | Type | Description |
3645
+ | --- | --- | --- |
3646
+ | [singleRetrieve] | <code>string</code> \| <code>number</code> | key of single item to filter by |
3647
+ | metadataMap | <code>TYPE.MetadataTypeMap</code> | saved metadata |
3648
+
3635
3649
  <a name="MetadataType.parseResponseBody"></a>
3636
3650
 
3637
3651
  ### MetadataType.parseResponseBody(body, [singleRetrieve]) ⇒ <code>TYPE.MetadataTypeMap</code>
@@ -4006,11 +4020,13 @@ MobileKeyword MetadataType
4006
4020
 
4007
4021
  * [MobileKeyword](#MobileKeyword) ⇐ [<code>MetadataType</code>](#MetadataType)
4008
4022
  * [.retrieve(retrieveDir, [_], [__], [key])](#MobileKeyword.retrieve) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMapObj&gt;</code> \| <code>void</code>
4023
+ * [.parseResponseBody(body, [singleRetrieve])](#MobileKeyword.parseResponseBody) ⇒ <code>TYPE.MetadataTypeMap</code>
4024
+ * [.createOrUpdate(metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate)](#MobileKeyword.createOrUpdate) ⇒ <code>&#x27;create&#x27;</code> \| <code>&#x27;update&#x27;</code> \| <code>&#x27;skip&#x27;</code>
4009
4025
  * [.retrieveForCache(_, __, [key])](#MobileKeyword.retrieveForCache) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMapObj&gt;</code>
4010
- * [.retrieveAsTemplate(templateDir, name, templateVariables)](#MobileKeyword.retrieveAsTemplate) ⇒ <code>Promise.&lt;TYPE.MetadataTypeItemObj&gt;</code>
4011
- * [.create(MobileKeyword)](#MobileKeyword.create) ⇒ <code>Promise</code>
4026
+ * [.retrieveAsTemplate(templateDir, key, templateVariables)](#MobileKeyword.retrieveAsTemplate) ⇒ <code>Promise.&lt;TYPE.MetadataTypeItemObj&gt;</code>
4027
+ * [.create(metadata)](#MobileKeyword.create) ⇒ <code>Promise</code>
4012
4028
  * [.update(metadata)](#MobileKeyword.update) ⇒ <code>Promise</code>
4013
- * [.postRetrieveTasks(metadata)](#MobileKeyword.postRetrieveTasks) ⇒ <code>TYPE.CodeExtractItem</code> \| <code>TYPE.MetadataTypeItem</code>
4029
+ * [.postRetrieveTasks(metadata)](#MobileKeyword.postRetrieveTasks) ⇒ <code>TYPE.CodeExtractItem</code> \| <code>TYPE.MetadataTypeItem</code> \| <code>void</code>
4014
4030
  * [.prepExtractedCode(metadataScript)](#MobileKeyword.prepExtractedCode) ⇒ <code>Object</code>
4015
4031
  * [.buildDefinitionForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#MobileKeyword.buildDefinitionForNested) ⇒ <code>Promise.&lt;Array.&lt;Array.&lt;string&gt;&gt;&gt;</code>
4016
4032
  * [.buildTemplateForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#MobileKeyword.buildTemplateForNested) ⇒ <code>Promise.&lt;Array.&lt;Array.&lt;string&gt;&gt;&gt;</code>
@@ -4039,6 +4055,35 @@ Endpoint /legacy/v1/beta/mobile/keyword/ return all Mobile Keywords with all det
4039
4055
  | [__] | <code>void</code> | unused parameter |
4040
4056
  | [key] | <code>string</code> | customer key of single item to retrieve |
4041
4057
 
4058
+ <a name="MobileKeyword.parseResponseBody"></a>
4059
+
4060
+ ### MobileKeyword.parseResponseBody(body, [singleRetrieve]) ⇒ <code>TYPE.MetadataTypeMap</code>
4061
+ Builds map of metadata entries mapped to their keyfields
4062
+
4063
+ **Kind**: static method of [<code>MobileKeyword</code>](#MobileKeyword)
4064
+ **Returns**: <code>TYPE.MetadataTypeMap</code> - keyField => metadata map
4065
+
4066
+ | Param | Type | Description |
4067
+ | --- | --- | --- |
4068
+ | body | <code>object</code> | json of response body |
4069
+ | [singleRetrieve] | <code>string</code> \| <code>number</code> | key of single item to filter by |
4070
+
4071
+ <a name="MobileKeyword.createOrUpdate"></a>
4072
+
4073
+ ### MobileKeyword.createOrUpdate(metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate) ⇒ <code>&#x27;create&#x27;</code> \| <code>&#x27;update&#x27;</code> \| <code>&#x27;skip&#x27;</code>
4074
+ helper for [upsert](#MetadataType.upsert)
4075
+
4076
+ **Kind**: static method of [<code>MobileKeyword</code>](#MobileKeyword)
4077
+ **Returns**: <code>&#x27;create&#x27;</code> \| <code>&#x27;update&#x27;</code> \| <code>&#x27;skip&#x27;</code> - action to take
4078
+
4079
+ | Param | Type | Description |
4080
+ | --- | --- | --- |
4081
+ | metadataMap | <code>TYPE.MetadataTypeMap</code> | list of metadata |
4082
+ | metadataKey | <code>string</code> | key of item we are looking at |
4083
+ | hasError | <code>boolean</code> | error flag from previous code |
4084
+ | metadataToUpdate | <code>Array.&lt;TYPE.MetadataTypeItemDiff&gt;</code> | list of items to update |
4085
+ | metadataToCreate | <code>Array.&lt;TYPE.MetadataTypeItem&gt;</code> | list of items to create |
4086
+
4042
4087
  <a name="MobileKeyword.retrieveForCache"></a>
4043
4088
 
4044
4089
  ### MobileKeyword.retrieveForCache(_, __, [key]) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMapObj&gt;</code>
@@ -4055,8 +4100,8 @@ Retrieves event definition metadata for caching
4055
4100
 
4056
4101
  <a name="MobileKeyword.retrieveAsTemplate"></a>
4057
4102
 
4058
- ### MobileKeyword.retrieveAsTemplate(templateDir, name, templateVariables) ⇒ <code>Promise.&lt;TYPE.MetadataTypeItemObj&gt;</code>
4059
- Retrieve a specific keyword
4103
+ ### MobileKeyword.retrieveAsTemplate(templateDir, key, templateVariables) ⇒ <code>Promise.&lt;TYPE.MetadataTypeItemObj&gt;</code>
4104
+ retrieve an item and create a template from it
4060
4105
 
4061
4106
  **Kind**: static method of [<code>MobileKeyword</code>](#MobileKeyword)
4062
4107
  **Returns**: <code>Promise.&lt;TYPE.MetadataTypeItemObj&gt;</code> - Promise of metadata
@@ -4064,20 +4109,20 @@ Retrieve a specific keyword
4064
4109
  | Param | Type | Description |
4065
4110
  | --- | --- | --- |
4066
4111
  | templateDir | <code>string</code> | Directory where retrieved metadata directory will be saved |
4067
- | name | <code>string</code> | name of the metadata file |
4112
+ | key | <code>string</code> | name of the metadata file |
4068
4113
  | templateVariables | <code>TYPE.TemplateMap</code> | variables to be replaced in the metadata |
4069
4114
 
4070
4115
  <a name="MobileKeyword.create"></a>
4071
4116
 
4072
- ### MobileKeyword.create(MobileKeyword) ⇒ <code>Promise</code>
4073
- Creates a single Event Definition
4117
+ ### MobileKeyword.create(metadata) ⇒ <code>Promise</code>
4118
+ Creates a single item
4074
4119
 
4075
4120
  **Kind**: static method of [<code>MobileKeyword</code>](#MobileKeyword)
4076
4121
  **Returns**: <code>Promise</code> - Promise
4077
4122
 
4078
4123
  | Param | Type | Description |
4079
4124
  | --- | --- | --- |
4080
- | MobileKeyword | <code>TYPE.MetadataTypeItem</code> | a single Event Definition |
4125
+ | metadata | <code>TYPE.MetadataTypeItem</code> | a single item |
4081
4126
 
4082
4127
  <a name="MobileKeyword.update"></a>
4083
4128
 
@@ -4093,11 +4138,11 @@ Updates a single item
4093
4138
 
4094
4139
  <a name="MobileKeyword.postRetrieveTasks"></a>
4095
4140
 
4096
- ### MobileKeyword.postRetrieveTasks(metadata) ⇒ <code>TYPE.CodeExtractItem</code> \| <code>TYPE.MetadataTypeItem</code>
4141
+ ### MobileKeyword.postRetrieveTasks(metadata) ⇒ <code>TYPE.CodeExtractItem</code> \| <code>TYPE.MetadataTypeItem</code> \| <code>void</code>
4097
4142
  manages post retrieve steps
4098
4143
 
4099
4144
  **Kind**: static method of [<code>MobileKeyword</code>](#MobileKeyword)
4100
- **Returns**: <code>TYPE.CodeExtractItem</code> \| <code>TYPE.MetadataTypeItem</code> - Array with one metadata object and one ssjs string
4145
+ **Returns**: <code>TYPE.CodeExtractItem</code> \| <code>TYPE.MetadataTypeItem</code> \| <code>void</code> - Array with one metadata object and one ssjs string; or single metadata object; nothing if filtered
4101
4146
 
4102
4147
  | Param | Type | Description |
4103
4148
  | --- | --- | --- |
package/lib/Deployer.js CHANGED
@@ -18,7 +18,6 @@ class Deployer {
18
18
  /**
19
19
  * Creates a Deployer, uses v2 auth if v2AuthOptions are passed.
20
20
  *
21
- *
22
21
  * @param {TYPE.Mcdevrc} properties General configuration to be used in retrieve
23
22
  * @param {TYPE.BuObject} buObject properties for auth
24
23
  */
package/lib/cli.js CHANGED
@@ -240,7 +240,7 @@ yargs
240
240
  },
241
241
  })
242
242
  .command({
243
- command: 'buildDefinition <BU> <TYPE> <NAME> <MARKET>',
243
+ command: 'buildDefinition <BU> <TYPE> <FILENAME> <MARKET>',
244
244
  aliases: ['bd'],
245
245
  desc: 'builds metadata definition based on template',
246
246
  builder: (yargs) => {
@@ -253,9 +253,9 @@ yargs
253
253
  type: 'string',
254
254
  describe: 'metadata type',
255
255
  })
256
- .positional('NAME', {
256
+ .positional('FILENAME', {
257
257
  type: 'string',
258
- describe: 'name of the metadata component',
258
+ describe: 'File name of the metadata template without the extension',
259
259
  })
260
260
  .positional('MARKET', {
261
261
  type: 'string',
@@ -264,11 +264,11 @@ yargs
264
264
  },
265
265
  handler: (argv) => {
266
266
  Mcdev.setOptions(argv);
267
- Mcdev.buildDefinition(argv.BU, argv.TYPE, argv.NAME, argv.MARKET);
267
+ Mcdev.buildDefinition(argv.BU, argv.TYPE, argv.FILENAME, argv.MARKET);
268
268
  },
269
269
  })
270
270
  .command({
271
- command: 'buildDefinitionBulk <LISTNAME> <TYPE> <NAME>',
271
+ command: 'buildDefinitionBulk <LISTNAME> <TYPE> <FILENAME>',
272
272
  aliases: ['bdb'],
273
273
  desc: 'builds metadata definition based on template en bulk',
274
274
  builder: (yargs) => {
@@ -281,14 +281,14 @@ yargs
281
281
  type: 'string',
282
282
  describe: 'metadata type',
283
283
  })
284
- .positional('NAME', {
284
+ .positional('FILENAME', {
285
285
  type: 'string',
286
- describe: 'name of the metadata component',
286
+ describe: 'File name of the metadata template without the extension',
287
287
  });
288
288
  },
289
289
  handler: (argv) => {
290
290
  Mcdev.setOptions(argv);
291
- Mcdev.buildDefinitionBulk(argv.LISTNAME, argv.TYPE, argv.NAME);
291
+ Mcdev.buildDefinitionBulk(argv.LISTNAME, argv.TYPE, argv.FILENAME);
292
292
  },
293
293
  })
294
294
  .command({
package/lib/index.js CHANGED
@@ -256,11 +256,12 @@ class Mcdev {
256
256
  cred = buObject.credential;
257
257
  bu = buObject.businessUnit;
258
258
  // clean up old folders after types were renamed
259
- // TODO: Remove this with version 5.0.0
259
+ // TODO: Remove renamedTypes-logic 6 months after version 5 release
260
260
  const renamedTypes = {
261
261
  emailSend: 'emailSendDefinition',
262
262
  event: 'eventDefinition',
263
263
  fileLocation: 'ftpLocation',
264
+ journey: 'interaction',
264
265
  triggeredSend: 'triggeredSendDefinition',
265
266
  user: 'accountUser',
266
267
  };
@@ -26,7 +26,9 @@ class Asset extends MetadataType {
26
26
  static async retrieve(retrieveDir, _, subTypeArr, key) {
27
27
  const items = [];
28
28
  subTypeArr ||= this._getSubTypes();
29
- await File.initPrettier();
29
+ if (retrieveDir) {
30
+ await File.initPrettier();
31
+ }
30
32
  // loop through subtypes and return results of each subType for caching (saving is handled per subtype)
31
33
  for (const subType of subTypeArr) {
32
34
  // each subtype contains multiple different specific types (images contains jpg and png for example)
@@ -235,7 +237,7 @@ class Asset extends MetadataType {
235
237
  rightOperand: {
236
238
  property: 'id',
237
239
  simpleOperator: 'greaterThan',
238
- value: items[items.length - 1].id,
240
+ value: items.at(-1).id,
239
241
  },
240
242
  };
241
243
  lastPage = 0;
@@ -70,18 +70,18 @@ class Automation extends MetadataType {
70
70
  })
71
71
  )
72
72
  : [];
73
- const parsed = this.parseResponseBody({ items: details });
73
+ let metadataMap = this.parseResponseBody({ items: details });
74
+ // * retrieveDir can be empty when we use it in the context of postDeployTasks
75
+ if (retrieveDir) {
76
+ metadataMap = await this.saveResults(metadataMap, retrieveDir, null, null);
77
+ Util.logger.info(
78
+ `Downloaded: ${this.definition.type} (${Object.keys(metadataMap).length})` +
79
+ Util.getKeysString(key)
80
+ );
74
81
 
75
- // * retrieveDir is mandatory in this method as it is not used for caching (there is a seperate method for that)
76
- const savedMetadata = await this.saveResults(parsed, retrieveDir, null, null);
77
- Util.logger.info(
78
- `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` +
79
- Util.getKeysString(key)
80
- );
81
- if (this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type)) {
82
- await this.document(savedMetadata);
82
+ await this.runDocumentOnRetrieve(key, metadataMap);
83
83
  }
84
- return { metadata: savedMetadata, type: this.definition.type };
84
+ return { metadata: metadataMap, type: this.definition.type };
85
85
  }
86
86
  /**
87
87
  * Retrieves Metadata of Automation
@@ -397,23 +397,23 @@ class Automation extends MetadataType {
397
397
  /**
398
398
  * Gets executed after deployment of metadata type
399
399
  *
400
- * @param {TYPE.AutomationMap} metadata metadata mapped by their keyField
401
- * @param {TYPE.AutomationMap} originalMetadata metadata to be updated (contains additioanl fields)
400
+ * @param {TYPE.AutomationMap} metadataMap metadata mapped by their keyField
401
+ * @param {TYPE.AutomationMap} originalMetadataMap metadata to be updated (contains additioanl fields)
402
402
  * @returns {Promise.<void>} -
403
403
  */
404
- static async postDeployTasks(metadata, originalMetadata) {
405
- for (const key in metadata) {
404
+ static async postDeployTasks(metadataMap, originalMetadataMap) {
405
+ for (const key in metadataMap) {
406
406
  // need to put schedule on here if status is scheduled
407
407
 
408
- if (originalMetadata[key]?.type === 'scheduled') {
408
+ if (originalMetadataMap[key]?.type === 'scheduled') {
409
409
  // Starting Source == 'Schedule': Try starting the automation
410
- if (originalMetadata[key].status === 'Scheduled') {
410
+ if (originalMetadataMap[key].status === 'Scheduled') {
411
411
  let schedule = null;
412
412
  try {
413
- schedule = this._buildSchedule(originalMetadata[key].schedule);
413
+ schedule = this._buildSchedule(originalMetadataMap[key].schedule);
414
414
  } catch (ex) {
415
415
  Util.logger.error(
416
- `- Could not create schedule for automation ${originalMetadata[key].name} to start it: ${ex.message}`
416
+ `- Could not create schedule for automation ${originalMetadataMap[key].name} to start it: ${ex.message}`
417
417
  );
418
418
  }
419
419
  if (schedule !== null) {
@@ -431,7 +431,7 @@ class Automation extends MetadataType {
431
431
  schedule,
432
432
  {
433
433
  Interaction: {
434
- ObjectID: metadata[key].id,
434
+ ObjectID: metadataMap[key].id,
435
435
  },
436
436
  },
437
437
  'start',
@@ -445,31 +445,42 @@ class Automation extends MetadataType {
445
445
  (schedule_interval > 1 ? 's' : ''));
446
446
  Util.logger.warn(
447
447
  ` - scheduled automation '${
448
- originalMetadata[key].name
448
+ originalMetadataMap[key].name
449
449
  }' deployed Active: runs every ${intervalString} starting ${
450
450
  schedule_StartDateTime.split('T').join(' ').split('.')[0]
451
451
  } ${schedule_timezoneString}`
452
452
  );
453
453
  } catch (ex) {
454
454
  Util.logger.error(
455
- `- Could not start scheduled automation '${originalMetadata[key].name}': ${ex.message}`
455
+ `- Could not start scheduled automation '${originalMetadataMap[key].name}': ${ex.message}`
456
456
  );
457
457
  }
458
458
  }
459
459
  } else {
460
460
  Util.logger.warn(
461
- ` - scheduled automation '${originalMetadata[key].name}' deployed Paused`
461
+ ` - scheduled automation '${originalMetadataMap[key].name}' deployed Paused`
462
462
  );
463
463
  }
464
464
  }
465
- if (metadata[key].startSource) {
466
- metadata[key].schedule = metadata[key].startSource.schedule;
465
+ if (metadataMap[key].startSource) {
466
+ metadataMap[key].schedule = metadataMap[key].startSource.schedule;
467
467
 
468
- delete metadata[key].startSource;
468
+ delete metadataMap[key].startSource;
469
469
  }
470
- if (metadata[key].schedule) {
471
- metadata[key].schedule.typeId = metadata[key].schedule.scheduleTypeId;
472
- delete metadata[key].schedule.scheduleTypeId;
470
+ if (metadataMap[key].schedule) {
471
+ metadataMap[key].schedule.typeId = metadataMap[key].schedule.scheduleTypeId;
472
+ delete metadataMap[key].schedule.scheduleTypeId;
473
+ }
474
+
475
+ // re-retrieve deployed items because the API does not return any info for them except the new id (api key)
476
+ try {
477
+ const { metadata } = await this.retrieve(null, null, null, key);
478
+ metadataMap[key] = Object.values(metadata)[0];
479
+ // postRetrieveTasks will be run automatically on this via super.saveResult
480
+ } catch (ex) {
481
+ throw new Error(
482
+ `Could not get details for new ${this.definition.type} ${key} from server (${ex.message})`
483
+ );
473
484
  }
474
485
  }
475
486
  }
@@ -464,9 +464,7 @@ class DataExtension extends MetadataType {
464
464
  `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` +
465
465
  Util.getKeysString(key)
466
466
  );
467
- if (this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type)) {
468
- await this.document(savedMetadata);
469
- }
467
+ await this.runDocumentOnRetrieve(key, savedMetadata);
470
468
  }
471
469
  return { metadata: metadata, type: 'dataExtension' };
472
470
  }
@@ -170,11 +170,11 @@ class DataExtensionField extends MetadataType {
170
170
 
171
171
  // enable renaming
172
172
  if (item.Name_new) {
173
+ Util.logger.info(
174
+ ` - Found Name_new='${item.Name_new}' for field ${deKey}.${item.Name} - trying to rename.`
175
+ );
173
176
  item.Name = item.Name_new;
174
177
  delete item.Name_new;
175
- Util.logger.warn(
176
- ` - Found 'Name_new' value '${item.Name_new}' for ${deKey}.${item.Name} - trying to rename.`
177
- );
178
178
  }
179
179
 
180
180
  // check if any changes were found
@@ -210,8 +210,8 @@ class DataExtensionField extends MetadataType {
210
210
  }
211
211
  }
212
212
  if (item.Name_new) {
213
- Util.logger.warn(
214
- ` - Found 'Name_new' value '${item.Name_new}' for ${deKey}.${item.Name} but could not find a corresponding DE field on the server - adding new field instead of updating.`
213
+ Util.logger.info(
214
+ ` - Found Name_new='${item.Name_new}' for field ${deKey}.${item.Name} but could not find a corresponding DE field on the server - adding new field instead of updating.`
215
215
  );
216
216
  delete item.Name_new;
217
217
  }
@@ -542,12 +542,13 @@ class Journey extends MetadataType {
542
542
  try {
543
543
  // mobileKeyword
544
544
  if (activity.configurationArguments?.keywordId) {
545
- activity.configurationArguments.c__mobileKeyword = cache.searchForField(
546
- 'mobileKeyword',
547
- activity.configurationArguments.keywordId,
548
- 'id',
549
- 'keyword'
550
- );
545
+ activity.configurationArguments.r__mobileKeyword_codeKeyword =
546
+ cache.searchForField(
547
+ 'mobileKeyword',
548
+ activity.configurationArguments.keywordId,
549
+ 'id',
550
+ 'c__codeKeyword'
551
+ );
551
552
  delete activity.configurationArguments.keywordId;
552
553
  }
553
554
  } catch (ex) {
@@ -833,14 +834,14 @@ class Journey extends MetadataType {
833
834
  delete activity.configurationArguments.c__mobileMessage_id;
834
835
  }
835
836
  // mobileKeyword
836
- if (activity.configurationArguments?.c__mobileKeyword) {
837
+ if (activity.configurationArguments?.r__mobileKeyword_codeKeyword) {
837
838
  activity.configurationArguments.keywordId = cache.searchForField(
838
839
  'mobileKeyword',
839
- activity.c__mobileKeyword,
840
- 'keyword',
840
+ activity.r__mobileKeyword_codeKeyword,
841
+ 'c__codeKeyword',
841
842
  'id'
842
843
  );
843
- delete activity.configurationArguments.c__mobileKeyword;
844
+ delete activity.configurationArguments.r__mobileKeyword_codeKeyword;
844
845
  }
845
846
  if (activity.configurationArguments?.c__next_mobileKeyword) {
846
847
  activity.configurationArguments.nextKeywordId = cache.searchForField(
@@ -1016,12 +1016,7 @@ class MetadataType {
1016
1016
  `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` +
1017
1017
  Util.getKeysString(singleRetrieve)
1018
1018
  );
1019
- if (
1020
- this.buObject &&
1021
- this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type)
1022
- ) {
1023
- await this.document(savedMetadata);
1024
- }
1019
+ await this.runDocumentOnRetrieve(singleRetrieve, savedMetadata);
1025
1020
  }
1026
1021
  return { metadata: metadata, type: this.definition.type };
1027
1022
  }
@@ -1063,6 +1058,7 @@ class MetadataType {
1063
1058
  `Downloaded: ${this.definition.type} (${Object.keys(savedMetadata).length})` +
1064
1059
  Util.getKeysString(singleRetrieve)
1065
1060
  );
1061
+ await this.runDocumentOnRetrieve(singleRetrieve, savedMetadata);
1066
1062
  }
1067
1063
 
1068
1064
  return {
@@ -1071,6 +1067,34 @@ class MetadataType {
1071
1067
  };
1072
1068
  }
1073
1069
 
1070
+ /**
1071
+ * helper for {@link retrieveREST} and {@link retrieveSOAP}
1072
+ *
1073
+ * @param {string|number} [singleRetrieve] key of single item to filter by
1074
+ * @param {TYPE.MetadataTypeMap} metadataMap saved metadata
1075
+ * @returns {Promise.<void>} -
1076
+ */
1077
+ static async runDocumentOnRetrieve(singleRetrieve, metadataMap) {
1078
+ if (
1079
+ this.buObject &&
1080
+ this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type)
1081
+ ) {
1082
+ if (!singleRetrieve || (singleRetrieve && !this.definition.documentInOneFile)) {
1083
+ const count = Object.keys(metadataMap).length;
1084
+ Util.logger.debug(
1085
+ ` - Running document for ${count} record${count === 1 ? '' : 's'}`
1086
+ );
1087
+ await this.document(metadataMap);
1088
+ } else {
1089
+ Util.logger.info(
1090
+ Util.getGrayMsg(
1091
+ ` - Skipped running document because you supplied keys and ${this.definition.type} is documented in a single file for all.`
1092
+ )
1093
+ );
1094
+ }
1095
+ }
1096
+ }
1097
+
1074
1098
  /**
1075
1099
  * Builds map of metadata entries mapped to their keyfields
1076
1100
  *
@@ -1528,7 +1552,10 @@ class MetadataType {
1528
1552
  // so its in retrieve but not in save. Here we put into the clone so that the original
1529
1553
  // object used for caching doesnt have the Id removed.
1530
1554
  const saveClone = JSON.parse(JSON.stringify(results[originalKey]));
1531
- if (!this.definition.keepId) {
1555
+ if (
1556
+ !this.definition.keepId &&
1557
+ this.definition.idField !== this.definition.keyField
1558
+ ) {
1532
1559
  delete saveClone[this.definition.idField];
1533
1560
  }
1534
1561