Skip to content

Commit 56a0e9a

Browse files
Merge pull request #500 from Accenture/develop
4.1.4
2 parents 1829c9a + ead9d88 commit 56a0e9a

27 files changed

+224
-128
lines changed

.github/ISSUE_TEMPLATE/bug.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ body:
3939
label: Version
4040
description: What version of our software are you running? (mcdev --version)
4141
options:
42+
- 4.1.4
4243
- 4.1.3
4344
- 4.1.2
4445
- 4.1.1

.github/workflows/code-analysis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ jobs:
3434

3535
steps:
3636
- name: Checkout repository
37-
uses: actions/checkout@v2
37+
uses: actions/checkout@v3
3838

39-
- uses: actions/setup-node@v2
39+
- uses: actions/setup-node@v3
4040
with:
4141
node-version: 16
4242
registry-url: https://registry.npmjs.org/

.github/workflows/npm-publish.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ jobs:
1111
build:
1212
runs-on: ubuntu-latest
1313
steps:
14-
- uses: actions/checkout@v2
15-
- uses: actions/setup-node@v1
14+
- uses: actions/checkout@v3
15+
- uses: actions/setup-node@v3
1616
with:
1717
node-version: 16
1818
- run: npm ci
@@ -22,8 +22,8 @@ jobs:
2222
needs: build
2323
runs-on: ubuntu-latest
2424
steps:
25-
- uses: actions/checkout@v2
26-
- uses: actions/setup-node@v1
25+
- uses: actions/checkout@v3
26+
- uses: actions/setup-node@v3
2727
with:
2828
node-version: 16
2929
registry-url: https://registry.npmjs.org/

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ If you experience issues installing Accenture SFMC DevTools, please check out th
123123
1. Install Accenture SFMC DevTools by running `npm install -g mcdev` (prefix with `sudo` on MacOS)
124124
- If you get an error, please see the below troubleshooting section.
125125

126-
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.3`).
126+
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.4`).
127127

128128
> **_Side note for proud nerds_:**
129129
>
@@ -277,10 +277,10 @@ _Note: Regardless of which tag or branch you install_
277277
**Install specific version (using a version tag on npm):**
278278

279279
```bash
280-
npm install -g mcdev@4.1.3
280+
npm install -g mcdev@4.1.4
281281
```
282282

283-
**Warning**: When you used the above method to install Accenture SFMC DevTools for a specific version or tag, trying to [update Accenture SFMC DevTools](#updating-mcdev) might not download the most recently published official version but instead stay on the version or branch you previously selected (in the above examples: develop, 4.1.3)!
283+
**Warning**: When you used the above method to install Accenture SFMC DevTools for a specific version or tag, trying to [update Accenture SFMC DevTools](#updating-mcdev) might not download the most recently published official version but instead stay on the version or branch you previously selected (in the above examples: develop, 4.1.4)!
284284

285285
> **Note**: The version is currently _not_ updated on the developer branch until a new release is published. Hence, you will not see a change if you run `mcdev --version`.
286286
@@ -1493,7 +1493,7 @@ Assuming you cloned Accenture SFMC DevTools into `C:\repos\sfmc-devtools\` (or `
14931493
14941494
This should tell npm to create a symlink to your cloned local directoty, allowing you to see updates you make in your mcdev repo instantly.
14951495
1496-
To test your new **global** developer setup, run `mcdev --version` in CLI which should return the current version (e.g. `4.1.3`). Then, go into your mcdev repo and update the version with the suffix `-dev`, e.g. to `4.1.3-dev` and then run `mcdev --version` again to verify that your change propagates instantly.
1496+
To test your new **global** developer setup, run `mcdev --version` in CLI which should return the current version (e.g. `4.1.4`). Then, go into your mcdev repo and update the version with the suffix `-dev`, e.g. to `4.1.4-dev` and then run `mcdev --version` again to verify that your change propagates instantly.
14971497
14981498
> **Not recommended:** Alternatively, you can install it locally only by opening a terminal in your project directory and executing `npm install --save-dev "C:\repos\sfmc-devtools"`
14991499
> To run the local version you need to prepend "npx" before your commands, e.g. `npx mcdev --version`
@@ -1531,7 +1531,7 @@ The following explains how you _could_ install it locally for certain edge cases
15311531
4. Afterwards, install Accenture SFMC DevTools by running `npm install --save-dev mcdev`
15321532
- If you get an error, please see the below troubleshooting section.
15331533
1534-
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.3`).
1534+
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.4`).
15351535
15361536
### 9.3. NPM Scripts
15371537

docs/dist/documentation.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,7 @@ FileTransfer MetadataType
836836
* [.buildDefinitionForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#Asset.buildDefinitionForNested) ⇒ <code>Promise.&lt;void&gt;</code>
837837
* [.buildTemplateForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#Asset.buildTemplateForNested) ⇒ <code>Promise.&lt;void&gt;</code>
838838
* [._buildForNested(templateDir, targetDir, metadata, templateVariables, templateName, mode)](#Asset._buildForNested) ⇒ <code>Promise.&lt;void&gt;</code>
839+
* [.setFolderPath(metadata)](#Asset.setFolderPath)
839840
* [.parseMetadata(metadata)](#Asset.parseMetadata) ⇒ <code>TYPE.CodeExtractItem</code>
840841
* [._mergeCode(metadata, deployDir, subType, [templateName], [fileListOnly])](#Asset._mergeCode) ⇒ <code>Promise.&lt;Array.&lt;TYPE.CodeExtract&gt;&gt;</code>
841842
* [._mergeCode_slots(prefix, metadataSlots, readDirArr, subtypeExtension, subDirArr, fileList, customerKey, [templateName], [fileListOnly])](#Asset._mergeCode_slots) ⇒ <code>Promise.&lt;void&gt;</code>
@@ -1072,6 +1073,17 @@ handles extracted code if any are found for complex types
10721073
| templateName | <code>string</code> | name of the template to be built |
10731074
| mode | <code>&#x27;definition&#x27;</code> \| <code>&#x27;template&#x27;</code> | defines what we use this helper for |
10741075

1076+
<a name="Asset.setFolderPath"></a>
1077+
1078+
### Asset.setFolderPath(metadata)
1079+
generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve
1080+
1081+
**Kind**: static method of [<code>Asset</code>](#Asset)
1082+
1083+
| Param | Type | Description |
1084+
| --- | --- | --- |
1085+
| metadata | <code>TYPE.MetadataTypeItem</code> | a single script activity definition |
1086+
10751087
<a name="Asset.parseMetadata"></a>
10761088

10771089
### Asset.parseMetadata(metadata) ⇒ <code>TYPE.CodeExtractItem</code>
@@ -1254,6 +1266,7 @@ Automation MetadataType
12541266
* [.preDeployTasks(metadata)](#Automation.preDeployTasks) ⇒ <code>Promise.&lt;TYPE.AutomationItem&gt;</code>
12551267
* [.validateDeployMetadata(metadata)](#Automation.validateDeployMetadata) ⇒ <code>boolean</code>
12561268
* [.postDeployTasks(metadata, originalMetadata)](#Automation.postDeployTasks) ⇒ <code>Promise.&lt;void&gt;</code>
1269+
* [.setFolderPath(metadata)](#Automation.setFolderPath)
12571270
* [.parseMetadata(metadata)](#Automation.parseMetadata) ⇒ <code>TYPE.AutomationItem</code>
12581271
* [._buildSchedule(scheduleObject)](#Automation._buildSchedule) ⇒ <code>TYPE.AutomationScheduleSoap</code>
12591272
* [._calcTime(offsetServer, dateInput, [offsetInput])](#Automation._calcTime) ⇒ <code>string</code>
@@ -1393,6 +1406,17 @@ Gets executed after deployment of metadata type
13931406
| metadata | <code>TYPE.AutomationMap</code> | metadata mapped by their keyField |
13941407
| originalMetadata | <code>TYPE.AutomationMap</code> | metadata to be updated (contains additioanl fields) |
13951408

1409+
<a name="Automation.setFolderPath"></a>
1410+
1411+
### Automation.setFolderPath(metadata)
1412+
generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve
1413+
1414+
**Kind**: static method of [<code>Automation</code>](#Automation)
1415+
1416+
| Param | Type | Description |
1417+
| --- | --- | --- |
1418+
| metadata | <code>TYPE.MetadataTypeItem</code> | a single script activity definition |
1419+
13961420
<a name="Automation.parseMetadata"></a>
13971421

13981422
### Automation.parseMetadata(metadata) ⇒ <code>TYPE.AutomationItem</code>
@@ -1511,6 +1535,7 @@ ContentArea MetadataType
15111535
* [ContentArea](#ContentArea)[<code>MetadataType</code>](#MetadataType)
15121536
* [.retrieve(retrieveDir, [_], [__], [___], [key])](#ContentArea.retrieve) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMapObj&gt;</code>
15131537
* [.postRetrieveTasks(metadata)](#ContentArea.postRetrieveTasks) ⇒ <code>TYPE.MetadataTypeItem</code>
1538+
* [.setFolderPath(metadata)](#ContentArea.setFolderPath)
15141539
* [.parseMetadata(metadata)](#ContentArea.parseMetadata) ⇒ <code>TYPE.MetadataTypeItem</code>
15151540

15161541
<a name="ContentArea.retrieve"></a>
@@ -1541,6 +1566,17 @@ manages post retrieve steps
15411566
| --- | --- | --- |
15421567
| metadata | <code>TYPE.MetadataTypeItem</code> | a single item |
15431568

1569+
<a name="ContentArea.setFolderPath"></a>
1570+
1571+
### ContentArea.setFolderPath(metadata)
1572+
generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve
1573+
1574+
**Kind**: static method of [<code>ContentArea</code>](#ContentArea)
1575+
1576+
| Param | Type | Description |
1577+
| --- | --- | --- |
1578+
| metadata | <code>TYPE.MetadataTypeItem</code> | a single script activity definition |
1579+
15441580
<a name="ContentArea.parseMetadata"></a>
15451581

15461582
### ContentArea.parseMetadata(metadata) ⇒ <code>TYPE.MetadataTypeItem</code>
@@ -1576,6 +1612,7 @@ DataExtension MetadataType
15761612
* [.postDeleteTasks(buObject, customerKey)](#DataExtension.postDeleteTasks) ⇒ <code>void</code>
15771613
* [.retrieveForCache(buObject)](#DataExtension.retrieveForCache) ⇒ <code>Promise.&lt;{metadata: TYPE.DataExtensionMap, type: string}&gt;</code>
15781614
* [.retrieveAsTemplate(templateDir, name, templateVariables)](#DataExtension.retrieveAsTemplate) ⇒ <code>Promise.&lt;{metadata: TYPE.DataExtensionMap, type: string}&gt;</code>
1615+
* [.setFolderPath(metadata)](#DataExtension.setFolderPath)
15791616
* [.getFilesToCommit(keyArr)](#DataExtension.getFilesToCommit) ⇒ <code>Array.&lt;string&gt;</code>
15801617

15811618
<a name="DataExtension.upsert"></a>
@@ -1758,6 +1795,18 @@ Retrieves dataExtension metadata in template format.
17581795
| name | <code>string</code> | name of the metadata item |
17591796
| templateVariables | <code>TYPE.TemplateMap</code> | variables to be replaced in the metadata |
17601797

1798+
<a name="DataExtension.setFolderPath"></a>
1799+
1800+
### DataExtension.setFolderPath(metadata)
1801+
dataExtension logic that retrieves the folder path from cache and updates the given metadata with it after retrieve
1802+
it also sets the content type which is basically the subtype
1803+
1804+
**Kind**: static method of [<code>DataExtension</code>](#DataExtension)
1805+
1806+
| Param | Type | Description |
1807+
| --- | --- | --- |
1808+
| metadata | <code>TYPE.MetadataTypeItem</code> | a single script activity definition |
1809+
17611810
<a name="DataExtension.getFilesToCommit"></a>
17621811

17631812
### DataExtension.getFilesToCommit(keyArr) ⇒ <code>Array.&lt;string&gt;</code>
@@ -2946,6 +2995,7 @@ Provides default functionality that can be overwritten by child metadata type cl
29462995
* [.deploy(metadata, deployDir, retrieveDir, buObject)](#MetadataType.deploy) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMap&gt;</code>
29472996
* [.postDeployTasks(metadata, originalMetadata)](#MetadataType.postDeployTasks) ⇒ <code>void</code>
29482997
* [.postRetrieveTasks(metadata, targetDir, [isTemplating])](#MetadataType.postRetrieveTasks) ⇒ <code>TYPE.MetadataTypeItem</code>
2998+
* [.setFolderPath(metadata)](#MetadataType.setFolderPath)
29492999
* [.retrieve(retrieveDir, [additionalFields], buObject, [subType], [key])](#MetadataType.retrieve) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMapObj&gt;</code>
29503000
* [.retrieveChangelog([buObject], [additionalFields], [subType])](#MetadataType.retrieveChangelog) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMapObj&gt;</code>
29513001
* [.retrieveForCache(buObject, [subType])](#MetadataType.retrieveForCache) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMapObj&gt;</code>
@@ -3069,6 +3119,17 @@ Gets executed after retreive of metadata type
30693119
| targetDir | <code>string</code> | folder where retrieves should be saved |
30703120
| [isTemplating] | <code>boolean</code> | signals that we are retrieving templates |
30713121

3122+
<a name="MetadataType.setFolderPath"></a>
3123+
3124+
### MetadataType.setFolderPath(metadata)
3125+
generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve
3126+
3127+
**Kind**: static method of [<code>MetadataType</code>](#MetadataType)
3128+
3129+
| Param | Type | Description |
3130+
| --- | --- | --- |
3131+
| metadata | <code>TYPE.MetadataTypeItem</code> | a single script activity definition |
3132+
30723133
<a name="MetadataType.retrieve"></a>
30733134

30743135
### MetadataType.retrieve(retrieveDir, [additionalFields], buObject, [subType], [key]) ⇒ <code>Promise.&lt;TYPE.MetadataTypeMapObj&gt;</code>

lib/Retriever.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ class Retriever {
7474
try {
7575
let result;
7676
if (!metadataTypes.includes(type) && !metadataTypes.includes(metadataType)) {
77-
if (changelogOnly) {
78-
// no extra caching needed for list view
77+
if (changelogOnly && type !== 'folder') {
78+
// no extra caching needed for list view except for folders
7979
continue;
8080
}
8181
Util.logger.info(`Caching dependent Metadata: ${metadataType}`);
@@ -115,6 +115,12 @@ class Retriever {
115115
)
116116
)
117117
));
118+
if (changelogOnly) {
119+
// add folder to changelog
120+
for (const key of Object.keys(result.metadata)) {
121+
MetadataTypeInfo[type].setFolderPath(result.metadata[key]);
122+
}
123+
}
118124
}
119125
if (result) {
120126
if (Array.isArray(result)) {

lib/metadataTypes/Asset.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -755,15 +755,12 @@ class Asset extends MetadataType {
755755
}
756756
}
757757
}
758-
759758
/**
760-
* parses retrieved Metadata before saving
759+
* generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve
761760
*
762-
* @param {TYPE.AssetItem} metadata a single asset definition
763-
* @returns {TYPE.CodeExtractItem} parsed metadata definition
761+
* @param {TYPE.MetadataTypeItem} metadata a single script activity definition
764762
*/
765-
static parseMetadata(metadata) {
766-
// folder
763+
static setFolderPath(metadata) {
767764
try {
768765
metadata.r__folder_Path = cache.searchForField(
769766
'folder',
@@ -773,12 +770,23 @@ class Asset extends MetadataType {
773770
);
774771
delete metadata.category;
775772
} catch (ex) {
776-
// ! if we don't catch this error here we end up saving the actual asset but not its corresponding JSON
777-
Util.logger.debug(ex.message);
778773
Util.logger.warn(
779-
` - Could not find folder with ID ${metadata.category.id} for '${metadata.name}' (${metadata.customerKey})`
774+
` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${
775+
metadata[this.definition.keyField]
776+
}): Could not find folder (${ex.message})`
780777
);
781778
}
779+
}
780+
781+
/**
782+
* parses retrieved Metadata before saving
783+
*
784+
* @param {TYPE.AssetItem} metadata a single asset definition
785+
* @returns {TYPE.CodeExtractItem} parsed metadata definition
786+
*/
787+
static parseMetadata(metadata) {
788+
// folder
789+
this.setFolderPath(metadata);
782790
// extract HTML for selected subtypes and convert payload for easier processing in MetadataType.saveResults()
783791
metadata = this._extractCode(metadata);
784792
return metadata;

lib/metadataTypes/Automation.js

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class Automation extends MetadataType {
7373
'ProgramID',
7474
'Name',
7575
'CustomerKey',
76+
'CategoryID',
7677
'LastSaveDate',
7778
'LastSavedBy',
7879
'CreatedBy',
@@ -457,23 +458,23 @@ class Automation extends MetadataType {
457458
}
458459
}
459460
}
460-
461461
/**
462-
* parses retrieved Metadata before saving
462+
* generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve
463463
*
464-
* @param {TYPE.AutomationItem} metadata a single automation definition
465-
* @returns {TYPE.AutomationItem} parsed item
464+
* @param {TYPE.MetadataTypeItem} metadata a single script activity definition
466465
*/
467-
static parseMetadata(metadata) {
468-
// automations are often skipped due to lack of support.
466+
static setFolderPath(metadata) {
467+
const folderIdField = metadata[this.definition.folderIdField]
468+
? this.definition.folderIdField
469+
: 'CategoryID';
469470
try {
470471
metadata.r__folder_Path = cache.searchForField(
471472
'folder',
472-
metadata.categoryId,
473+
metadata[folderIdField],
473474
'ID',
474475
'Path'
475476
);
476-
delete metadata.categoryId;
477+
delete metadata[folderIdField];
477478
if (metadata.r__folder_Path !== 'my automations') {
478479
Util.logger.verbose(
479480
`- automation '${
@@ -484,13 +485,23 @@ class Automation extends MetadataType {
484485
);
485486
}
486487
} catch (ex) {
487-
// * don't exit on missing folder for automation
488488
Util.logger.warn(
489-
` - ${this.definition.typeName} '${metadata[this.definition.nameField]}': ${
490-
ex.message
491-
}`
489+
` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${
490+
metadata[this.definition.keyField]
491+
}): Could not find folder (${ex.message})`
492492
);
493493
}
494+
}
495+
496+
/**
497+
* parses retrieved Metadata before saving
498+
*
499+
* @param {TYPE.AutomationItem} metadata a single automation definition
500+
* @returns {TYPE.AutomationItem} parsed item
501+
*/
502+
static parseMetadata(metadata) {
503+
this.setFolderPath(metadata);
504+
// automations are often skipped due to lack of support.
494505
try {
495506
if (metadata.type === 'scheduled' && metadata.schedule?.startDate) {
496507
// Starting Source == 'Schedule'

lib/metadataTypes/ContentArea.js

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,27 +49,40 @@ class ContentArea extends MetadataType {
4949
return this.parseMetadata(metadata);
5050
}
5151
/**
52-
* parses retrieved Metadata before saving
52+
* generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve
5353
*
54-
* @param {TYPE.MetadataTypeItem} metadata a single item
55-
* @returns {TYPE.MetadataTypeItem} parsed item
54+
* @param {TYPE.MetadataTypeItem} metadata a single script activity definition
5655
*/
57-
static parseMetadata(metadata) {
58-
// folder
56+
static setFolderPath(metadata) {
5957
try {
6058
metadata.r__folder_Path = cache.searchForField(
6159
'folder',
62-
metadata.CategoryID,
60+
metadata[this.definition.folderIdField],
6361
'ID',
6462
'Path'
6563
);
64+
delete metadata[this.definition.folderIdField];
6665
} catch (ex) {
67-
Util.logger.debug(`Classic Content Area '${metadata.CustomerKey}': ${ex.message}`);
66+
Util.logger.debug(
67+
` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${
68+
metadata[this.definition.keyField]
69+
}): Could not find folder (${ex.message})`
70+
);
6871
// classic content blocks that reside in the main folder are
6972
// saved with CategoryID=0, instead of to the actual ID of
7073
// their parent root folder.
7174
metadata.r__folder_Path = 'my contents';
7275
}
76+
}
77+
/**
78+
* parses retrieved Metadata before saving
79+
*
80+
* @param {TYPE.MetadataTypeItem} metadata a single item
81+
* @returns {TYPE.MetadataTypeItem} parsed item
82+
*/
83+
static parseMetadata(metadata) {
84+
// folder
85+
this.setFolderPath(metadata);
7386

7487
// extract code
7588
const codeArr = [

0 commit comments

Comments
 (0)