mcdev 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +1 -1
- package/.github/ISSUE_TEMPLATE/bug.yml +72 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/ISSUE_TEMPLATE/task.md +10 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +11 -0
- package/.github/workflows/npm-publish.yml +33 -0
- package/.issuetracker +11 -3
- package/.vscode/extensions.json +1 -2
- package/.vscode/settings.json +19 -4
- package/CHANGELOG.md +98 -0
- package/README.md +247 -142
- package/boilerplate/config.json +3 -2
- package/docs/dist/considerations.md +66 -0
- package/docs/dist/documentation.md +5794 -0
- package/lib/Deployer.js +4 -1
- package/lib/MetadataTypeDefinitions.js +1 -0
- package/lib/MetadataTypeInfo.js +1 -0
- package/lib/Retriever.js +32 -17
- package/lib/cli.js +295 -0
- package/lib/index.js +774 -1019
- package/lib/metadataTypes/AccountUser.js +389 -0
- package/lib/metadataTypes/Asset.js +140 -116
- package/lib/metadataTypes/Automation.js +119 -54
- package/lib/metadataTypes/DataExtension.js +172 -131
- package/lib/metadataTypes/DataExtensionField.js +134 -4
- package/lib/metadataTypes/Folder.js +66 -69
- package/lib/metadataTypes/ImportFile.js +4 -6
- package/lib/metadataTypes/MetadataType.js +168 -80
- package/lib/metadataTypes/Query.js +54 -25
- package/lib/metadataTypes/Role.js +13 -8
- package/lib/metadataTypes/Script.js +43 -24
- package/lib/metadataTypes/definitions/AccountUser.definition.js +227 -0
- package/lib/metadataTypes/definitions/Asset.definition.js +1 -0
- package/lib/metadataTypes/definitions/Campaign.definition.js +1 -1
- package/lib/metadataTypes/definitions/DataExtension.definition.js +1 -1
- package/lib/metadataTypes/definitions/DataExtensionField.definition.js +1 -1
- package/lib/metadataTypes/definitions/Folder.definition.js +1 -1
- package/lib/metadataTypes/definitions/ImportFile.definition.js +2 -1
- package/lib/metadataTypes/definitions/Script.definition.js +5 -5
- package/lib/retrieveChangelog.js +96 -0
- package/lib/util/cli.js +4 -6
- package/lib/util/init.config.js +3 -0
- package/lib/util/init.git.js +2 -1
- package/lib/util/util.js +35 -18
- package/package.json +20 -24
- package/test/util/file.js +51 -0
- package/img/README.md/troubleshoot-nodejs-postinstall.jpg +0 -0
- package/postinstall.js +0 -41
- package/test/deployer.js +0 -16
- package/test/util.js +0 -26
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* sample file on how to retrieve a simple changelog to use in GUIs or automated processing of any kind
|
|
6
|
+
* @example
|
|
7
|
+
[{
|
|
8
|
+
name: 'deName',
|
|
9
|
+
key: 'deKey',
|
|
10
|
+
t: 'dataExtension',
|
|
11
|
+
cd: '2020-05-06T00:16:00.737',
|
|
12
|
+
cb: 'name of creator',
|
|
13
|
+
ld: '2020-05-06T00:16:00.737',
|
|
14
|
+
lb: 'name of lastmodified'
|
|
15
|
+
}]
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const mcdev = require('./index');
|
|
19
|
+
const Definition = require('./MetadataTypeDefinitions');
|
|
20
|
+
const MetadataType = require('./MetadataTypeInfo');
|
|
21
|
+
|
|
22
|
+
// disable cli logs
|
|
23
|
+
// mcdev._setLoggingLevel({ silent: true });
|
|
24
|
+
|
|
25
|
+
const customDefinition = {
|
|
26
|
+
automation: {
|
|
27
|
+
keyField: 'CustomerKey',
|
|
28
|
+
nameField: 'Name',
|
|
29
|
+
createdDateField: 'CreatedDate',
|
|
30
|
+
createdNameField: 'CreatedBy',
|
|
31
|
+
lastmodDateField: 'LastSaveDate',
|
|
32
|
+
lastmodNameField: 'LastSavedBy',
|
|
33
|
+
},
|
|
34
|
+
dataExtension: {
|
|
35
|
+
keyField: 'CustomerKey',
|
|
36
|
+
nameField: 'Name',
|
|
37
|
+
createdDateField: 'CreatedDate',
|
|
38
|
+
createdNameField: null,
|
|
39
|
+
lastmodDateField: 'ModifiedDate',
|
|
40
|
+
lastmodNameField: null,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
(async function () {
|
|
44
|
+
// get userid>name mapping
|
|
45
|
+
const userList = (await mcdev.retrieve('ACN-Learning/_ParentBU_', 'accountUser', true))
|
|
46
|
+
.accountUser;
|
|
47
|
+
// reduce userList to simple id-name map
|
|
48
|
+
Object.keys(userList).forEach((key) => {
|
|
49
|
+
userList[userList[key].ID] = userList[key].Name;
|
|
50
|
+
delete userList[key];
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// get changed metadata
|
|
54
|
+
const changelogList = await mcdev.retrieve('ACN-Learning/MCDEV_Training_Source', null, true);
|
|
55
|
+
const allMetadata = [];
|
|
56
|
+
Object.keys(changelogList).map((type) => {
|
|
57
|
+
if (changelogList[type]) {
|
|
58
|
+
const def = customDefinition[type] || Definition[type];
|
|
59
|
+
allMetadata.push(
|
|
60
|
+
...Object.keys(changelogList[type]).map((key) => {
|
|
61
|
+
const item = changelogList[type][key];
|
|
62
|
+
if (
|
|
63
|
+
MetadataType[type].isFiltered(item, true) ||
|
|
64
|
+
MetadataType[type].isFiltered(item, false)
|
|
65
|
+
) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const listEntry = {
|
|
70
|
+
name: item[def.nameField],
|
|
71
|
+
key: item[def.keyField],
|
|
72
|
+
t: type,
|
|
73
|
+
cd: item[def.createdDateField],
|
|
74
|
+
cb: getUserName(userList, item, def.createdNameField),
|
|
75
|
+
ld: item[def.lastmodDateField],
|
|
76
|
+
lb: getUserName(userList, item, def.lastmodNameField),
|
|
77
|
+
};
|
|
78
|
+
return listEntry;
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
const finalResult = allMetadata.filter((item) => undefined !== item);
|
|
84
|
+
console.log('finalResult', finalResult);
|
|
85
|
+
})();
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
*
|
|
89
|
+
* @param {object<string,string>} userList user-id > user-name map
|
|
90
|
+
* @param {object<string,string>} item single metadata item
|
|
91
|
+
* @param {string} fieldname name of field containing the info
|
|
92
|
+
* @returns {string} username or user id or 'n/a'
|
|
93
|
+
*/
|
|
94
|
+
function getUserName(userList, item, fieldname) {
|
|
95
|
+
return userList[item[fieldname]] || item[fieldname] || 'n/a';
|
|
96
|
+
}
|
package/lib/util/cli.js
CHANGED
|
@@ -427,9 +427,8 @@ const Cli = {
|
|
|
427
427
|
subtype,
|
|
428
428
|
type: MetadataDefinitions[el].type + '-' + subtype,
|
|
429
429
|
mainType: MetadataDefinitions[el].type,
|
|
430
|
-
typeRetrieveByDefault:
|
|
431
|
-
el
|
|
432
|
-
].typeRetrieveByDefault.includes(subtype),
|
|
430
|
+
typeRetrieveByDefault:
|
|
431
|
+
MetadataDefinitions[el].typeRetrieveByDefault.includes(subtype),
|
|
433
432
|
});
|
|
434
433
|
}
|
|
435
434
|
}
|
|
@@ -560,9 +559,8 @@ const Cli = {
|
|
|
560
559
|
let lastCountdown = MetadataDefinitions[el].subTypes.length;
|
|
561
560
|
for (const subtype of MetadataDefinitions[el].subTypes) {
|
|
562
561
|
lastCountdown--;
|
|
563
|
-
const subTypeRetrieveByDefault =
|
|
564
|
-
el
|
|
565
|
-
].typeRetrieveByDefault.includes(subtype);
|
|
562
|
+
const subTypeRetrieveByDefault =
|
|
563
|
+
MetadataDefinitions[el].typeRetrieveByDefault.includes(subtype);
|
|
566
564
|
const definition =
|
|
567
565
|
' ' + MetadataDefinitions[el].extendedSubTypes[subtype].join(', ');
|
|
568
566
|
typeChoices.push({
|
package/lib/util/init.config.js
CHANGED
|
@@ -90,6 +90,9 @@ const Init = {
|
|
|
90
90
|
break;
|
|
91
91
|
case 'version':
|
|
92
92
|
// do nothing other than ensure we re-save the config (with the new version)
|
|
93
|
+
delete properties.catalystFullVersion;
|
|
94
|
+
delete properties.catalystVersion;
|
|
95
|
+
|
|
93
96
|
upgradeMsgs.push(`- ✔️ version updated`);
|
|
94
97
|
break;
|
|
95
98
|
default:
|
package/lib/util/init.git.js
CHANGED
|
@@ -229,7 +229,8 @@ const Init = {
|
|
|
229
229
|
// eslint-disable-next-line require-jsdoc
|
|
230
230
|
validate: function (value) {
|
|
231
231
|
value = value.trim();
|
|
232
|
-
const regex =
|
|
232
|
+
const regex =
|
|
233
|
+
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
|
233
234
|
if (!value || !regex.test(String(value).toLowerCase())) {
|
|
234
235
|
return 'Please enter valid email';
|
|
235
236
|
}
|
package/lib/util/util.js
CHANGED
|
@@ -110,6 +110,23 @@ const Util = {
|
|
|
110
110
|
'workflows_read',
|
|
111
111
|
'workflows_write',
|
|
112
112
|
],
|
|
113
|
+
/**
|
|
114
|
+
* SFMC accepts multiple true values for Boolean attributes for which we are checking here
|
|
115
|
+
* @param {*} attrValue value
|
|
116
|
+
* @returns {boolean} attribute value == true ? true : false
|
|
117
|
+
*/
|
|
118
|
+
isTrue(attrValue) {
|
|
119
|
+
return ['true', 'TRUE', 'True', '1', 1, 'Y'].includes(attrValue);
|
|
120
|
+
},
|
|
121
|
+
/**
|
|
122
|
+
* SFMC accepts multiple false values for Boolean attributes for which we are checking here
|
|
123
|
+
* @param {*} attrValue value
|
|
124
|
+
* @returns {boolean} attribute value == false ? true : false
|
|
125
|
+
*/
|
|
126
|
+
isFalse(attrValue) {
|
|
127
|
+
return ['false', 'FALSE', 'False', '0', 0, 'N'].includes(attrValue);
|
|
128
|
+
},
|
|
129
|
+
|
|
113
130
|
/**
|
|
114
131
|
* defines how the properties.json should look like
|
|
115
132
|
* used for creating a template and for checking if variables are set
|
|
@@ -180,9 +197,10 @@ const Util = {
|
|
|
180
197
|
}
|
|
181
198
|
|
|
182
199
|
// check if user is running older mcdev version than whats saved to the config
|
|
183
|
-
if (semver.gt(properties.version, packageJsonMcdev.version)) {
|
|
200
|
+
if (properties.version && semver.gt(properties.version, packageJsonMcdev.version)) {
|
|
201
|
+
// dont run this for Catalyst to MC DevTools migration
|
|
184
202
|
Util.logger.error(
|
|
185
|
-
`Your
|
|
203
|
+
`Your Accenture SFMC DevTools version ${packageJsonMcdev.version} is lower than your project's config version ${properties.version}`
|
|
186
204
|
);
|
|
187
205
|
const questions = [
|
|
188
206
|
{
|
|
@@ -329,7 +347,7 @@ const Util = {
|
|
|
329
347
|
}
|
|
330
348
|
}
|
|
331
349
|
// check if project config version is outdated compared to user's mcdev version
|
|
332
|
-
if (semver.gt(packageJsonMcdev.version, properties.version)) {
|
|
350
|
+
if (!properties.version || semver.gt(packageJsonMcdev.version, properties.version)) {
|
|
333
351
|
errorMsgs.push(
|
|
334
352
|
`Your project's config version ${properties.version} is lower than your Accenture SFMC DevTools version ${packageJsonMcdev.version}`
|
|
335
353
|
);
|
|
@@ -580,7 +598,7 @@ const Util = {
|
|
|
580
598
|
}
|
|
581
599
|
}
|
|
582
600
|
throw new Error(
|
|
583
|
-
`Missing one or more dependent metadata. ${metadataType} with ${searchField}='${searchValue}' was not found
|
|
601
|
+
`Missing one or more dependent metadata. ${metadataType} with ${searchField}='${searchValue}' was not found on your BU`
|
|
584
602
|
);
|
|
585
603
|
},
|
|
586
604
|
/**
|
|
@@ -626,7 +644,7 @@ const Util = {
|
|
|
626
644
|
}
|
|
627
645
|
}
|
|
628
646
|
throw new Error(
|
|
629
|
-
`Missing one or more dependent metadata. list with ListName='${listName}' and r__folder_Path='${folderPath}' was not found
|
|
647
|
+
`Missing one or more dependent metadata. list with ListName='${listName}' and r__folder_Path='${folderPath}' was not found on your BU`
|
|
630
648
|
);
|
|
631
649
|
},
|
|
632
650
|
|
|
@@ -662,7 +680,7 @@ const Util = {
|
|
|
662
680
|
}
|
|
663
681
|
}
|
|
664
682
|
throw new Error(
|
|
665
|
-
`Missing one or more dependent metadata. list with ${searchField}='${searchValue}' was not found
|
|
683
|
+
`Missing one or more dependent metadata. list with ${searchField}='${searchValue}' was not found on your BU`
|
|
666
684
|
);
|
|
667
685
|
},
|
|
668
686
|
/**
|
|
@@ -675,7 +693,7 @@ const Util = {
|
|
|
675
693
|
*/
|
|
676
694
|
async retryOnError(errorMsg, callback, silentError, retries) {
|
|
677
695
|
if ('undefined' === typeof retries || retries === null) {
|
|
678
|
-
retries =
|
|
696
|
+
retries = 3;
|
|
679
697
|
}
|
|
680
698
|
try {
|
|
681
699
|
await callback();
|
|
@@ -686,34 +704,33 @@ const Util = {
|
|
|
686
704
|
['ETIMEDOUT', 'EHOSTUNREACH', 'ENOTFOUND', 'ECONNRESET'].includes(ex.code)
|
|
687
705
|
) {
|
|
688
706
|
retries--;
|
|
707
|
+
Util.logger.debug(ex.stack);
|
|
708
|
+
const msg = `Connection problem. ${errorMsg} (${retries + 1} tries left)`;
|
|
689
709
|
if (silentError) {
|
|
690
|
-
Util.logger.debug(
|
|
691
|
-
`Connection error. ${errorMsg} - Retries left: ${retries + 1}`
|
|
692
|
-
);
|
|
710
|
+
Util.logger.debug(msg);
|
|
693
711
|
} else {
|
|
694
|
-
Util.logger.
|
|
712
|
+
Util.logger.warn(msg);
|
|
695
713
|
}
|
|
696
|
-
|
|
697
|
-
await this.retryOnError(errorMsg, callback, retries);
|
|
714
|
+
await this.retryOnError(errorMsg, callback, silentError, retries);
|
|
698
715
|
} else if (
|
|
699
716
|
ex.code &&
|
|
700
717
|
['ETIMEDOUT', 'EHOSTUNREACH', 'ENOTFOUND', 'ECONNRESET'].includes(ex.code)
|
|
701
718
|
) {
|
|
719
|
+
Util.logger.debug(ex.stack);
|
|
702
720
|
Util.logger.error(
|
|
703
|
-
`Failed due to a Connection Error (${ex.code}) - Please check your network connection and try again`
|
|
721
|
+
`"${errorMsg}" Failed due to a Connection Error (${ex.code}) - Please check your network connection and try again`
|
|
704
722
|
);
|
|
705
|
-
Util.logger.debug(ex.stack);
|
|
706
723
|
if (Util.logger.level === 'debug') {
|
|
707
724
|
console.log(ex.stack);
|
|
708
725
|
}
|
|
709
|
-
throw
|
|
726
|
+
throw ex;
|
|
710
727
|
} else {
|
|
711
|
-
Util.logger.error(ex.message);
|
|
712
728
|
Util.logger.debug(ex.stack);
|
|
713
729
|
if (Util.logger.level === 'debug') {
|
|
714
730
|
console.log(ex.stack);
|
|
715
731
|
}
|
|
716
|
-
|
|
732
|
+
Util.logger.error(ex.message);
|
|
733
|
+
throw ex;
|
|
717
734
|
}
|
|
718
735
|
}
|
|
719
736
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcdev",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Accenture Salesforce Marketing Cloud DevTools",
|
|
5
5
|
"author": "joern.berkefeld, douglas.midgley, robert.zimmermann, maciej.barnas",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/Accenture/sfmc-devtools.git"
|
|
10
10
|
},
|
|
11
|
-
"homepage": "https://github.com/Accenture/sfmc-devtools",
|
|
11
|
+
"homepage": "https://github.com/Accenture/sfmc-devtools#readme",
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/Accenture/sfmc-devtools/issues",
|
|
14
14
|
"email": "joern.berkefeld@accenture.com"
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"main": "./lib/index.js",
|
|
21
21
|
"bin": {
|
|
22
|
-
"mcdev": "./lib/
|
|
22
|
+
"mcdev": "./lib/cli.js"
|
|
23
23
|
},
|
|
24
24
|
"engines": {
|
|
25
25
|
"node": ">=14.16"
|
|
@@ -27,45 +27,44 @@
|
|
|
27
27
|
"scripts": {
|
|
28
28
|
"start": "node lib/index.js",
|
|
29
29
|
"mcdev": "node lib/index.js",
|
|
30
|
-
"postinstall": "node postinstall.js",
|
|
31
30
|
"build": "run-s lint docs",
|
|
32
31
|
"debug": "node --nolazy --inspect-brk=9229 lib/index.js",
|
|
33
32
|
"docs": "jsdoc2md --files lib/**/*.js > docs/dist/documentation.md",
|
|
34
33
|
"lint": "eslint --fix lib/**/*.js && eslint --fix test/**/*.js && prettier --write lib/**/*.js",
|
|
35
|
-
"test": "mocha",
|
|
34
|
+
"test": "mocha --recursive",
|
|
36
35
|
"upgrade": "npm-check --update",
|
|
37
36
|
"prepare": "husky install"
|
|
38
37
|
},
|
|
39
38
|
"dependencies": {
|
|
40
39
|
"bluebird": "3.7.2",
|
|
41
|
-
"cli-progress": "3.9.
|
|
40
|
+
"cli-progress": "3.9.1",
|
|
42
41
|
"command-exists": "1.2.9",
|
|
43
42
|
"console.table": "0.10.0",
|
|
44
|
-
"fs-extra": "
|
|
45
|
-
"inquirer": "8.
|
|
43
|
+
"fs-extra": "10.0.0",
|
|
44
|
+
"inquirer": "8.2.0",
|
|
46
45
|
"json-to-table": "4.2.1",
|
|
47
|
-
"mustache": "4.
|
|
48
|
-
"prettier": "2.
|
|
49
|
-
"semver": "
|
|
46
|
+
"mustache": "4.2.0",
|
|
47
|
+
"prettier": "2.5.1",
|
|
48
|
+
"semver": "7.3.5",
|
|
50
49
|
"sfmc-fuelsdk-node": "2.4.0",
|
|
51
|
-
"simple-git": "2.
|
|
50
|
+
"simple-git": "2.48.0",
|
|
52
51
|
"sql-formatter-plus": "1.3.6",
|
|
53
52
|
"toposort": "2.0.2",
|
|
54
53
|
"update-notifier-git": "5.0.3",
|
|
55
54
|
"winston": "3.3.3",
|
|
56
|
-
"yargs": "
|
|
55
|
+
"yargs": "17.3.0"
|
|
57
56
|
},
|
|
58
57
|
"devDependencies": {
|
|
59
58
|
"chai": "4.3.4",
|
|
60
|
-
"eslint": "
|
|
61
|
-
"eslint-config-prettier": "8.
|
|
59
|
+
"eslint": "8.4.1",
|
|
60
|
+
"eslint-config-prettier": "8.3.0",
|
|
62
61
|
"eslint-config-ssjs": "1.1.11",
|
|
63
|
-
"eslint-plugin-mocha": "
|
|
64
|
-
"eslint-plugin-prettier": "
|
|
65
|
-
"husky": "
|
|
66
|
-
"jsdoc-to-markdown": "7.
|
|
67
|
-
"lint-staged": "
|
|
68
|
-
"mocha": "
|
|
62
|
+
"eslint-plugin-mocha": "10.0.1",
|
|
63
|
+
"eslint-plugin-prettier": "4.0.0",
|
|
64
|
+
"husky": "7.0.4",
|
|
65
|
+
"jsdoc-to-markdown": "7.1.0",
|
|
66
|
+
"lint-staged": "12.1.2",
|
|
67
|
+
"mocha": "9.1.3",
|
|
69
68
|
"npm-check": "5.9.2",
|
|
70
69
|
"npm-run-all": "4.1.5"
|
|
71
70
|
},
|
|
@@ -73,9 +72,6 @@
|
|
|
73
72
|
"*.{js,jsx,ts,tsx}": [
|
|
74
73
|
"eslint --fix",
|
|
75
74
|
"prettier --write"
|
|
76
|
-
],
|
|
77
|
-
"*.{md}": [
|
|
78
|
-
"prettier --write"
|
|
79
75
|
]
|
|
80
76
|
}
|
|
81
77
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const assert = require('chai').assert;
|
|
2
|
+
const File = require('../../lib/util/file');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const dataDir = 'test_tmp/file/';
|
|
7
|
+
|
|
8
|
+
describe('File', () => {
|
|
9
|
+
after(() => {
|
|
10
|
+
fs.removeSync(dataDir);
|
|
11
|
+
});
|
|
12
|
+
describe('#writeJSONToFile()', () => {
|
|
13
|
+
it('should create json file and directory', async () => {
|
|
14
|
+
assert.strictEqual(fs.existsSync(dataDir + 'test1.json'), false);
|
|
15
|
+
const jsonContent = {
|
|
16
|
+
string: 'abc',
|
|
17
|
+
boolean: true,
|
|
18
|
+
number: 5,
|
|
19
|
+
array: ['asd', 4, 'asdf'],
|
|
20
|
+
obj: {
|
|
21
|
+
name: 'object',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
await File.writeJSONToFile(dataDir, 'test1', jsonContent);
|
|
25
|
+
assert.deepEqual(fs.readJSONSync(dataDir + 'test1.json'), jsonContent);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
describe('#copyFile()', () => {
|
|
29
|
+
it('should copy file from one path to another', async () => {
|
|
30
|
+
const source = path.join(dataDir, 'sourceFile.txt');
|
|
31
|
+
const target = path.join(dataDir, 'targetFile.txt');
|
|
32
|
+
fs.writeFileSync(source, 'filecontent');
|
|
33
|
+
assert.strictEqual(fs.existsSync(source), true);
|
|
34
|
+
await File.copyFile(source, target);
|
|
35
|
+
assert.strictEqual(fs.existsSync(target), true);
|
|
36
|
+
assert.deepEqual(fs.readFileSync(source), fs.readFileSync(target));
|
|
37
|
+
});
|
|
38
|
+
it("should skip copy if source file doesn't exist", async () => {
|
|
39
|
+
const source = path.join(dataDir, 'doesnt_exist_source.txt');
|
|
40
|
+
const target = path.join(dataDir, 'doesnt_exist_target.txt');
|
|
41
|
+
assert.strictEqual(fs.existsSync(source), false);
|
|
42
|
+
const result = await File.copyFile(source, target);
|
|
43
|
+
assert.strictEqual(fs.existsSync(target), false);
|
|
44
|
+
assert.deepEqual(result, {
|
|
45
|
+
status: 'skipped',
|
|
46
|
+
statusMessage: 'deleted from repository',
|
|
47
|
+
file: source,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
Binary file
|
package/postinstall.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
const greenOnBlack = '\x1b[32m\x1b[40m';
|
|
4
|
-
const highlight = '\x1b[7m';
|
|
5
|
-
const reset = '\x1b[0m';
|
|
6
|
-
console.log(greenOnBlack); // green on black
|
|
7
|
-
console.log('Congratulations: You installed Accenture Salesforce Marketing Cloud DevTools!');
|
|
8
|
-
console.log(
|
|
9
|
-
`If you have existing Accenture SFMC DevTools projects please run ${highlight}mcdev upgrade${reset}${greenOnBlack} in each of your project directories.`
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
console.log(reset); // reset cli colors
|
|
13
|
-
|
|
14
|
-
/*
|
|
15
|
-
Color reference
|
|
16
|
-
Reset = "\x1b[0m"
|
|
17
|
-
Bright = "\x1b[1m"
|
|
18
|
-
Dim = "\x1b[2m"
|
|
19
|
-
Underscore = "\x1b[4m"
|
|
20
|
-
Blink = "\x1b[5m"
|
|
21
|
-
Reverse = "\x1b[7m"
|
|
22
|
-
Hidden = "\x1b[8m"
|
|
23
|
-
|
|
24
|
-
FgBlack = "\x1b[30m"
|
|
25
|
-
FgRed = "\x1b[31m"
|
|
26
|
-
FgGreen = "\x1b[32m"
|
|
27
|
-
FgYellow = "\x1b[33m"
|
|
28
|
-
FgBlue = "\x1b[34m"
|
|
29
|
-
FgMagenta = "\x1b[35m"
|
|
30
|
-
FgCyan = "\x1b[36m"
|
|
31
|
-
FgWhite = "\x1b[37m"
|
|
32
|
-
|
|
33
|
-
BgBlack = "\x1b[40m"
|
|
34
|
-
BgRed = "\x1b[41m"
|
|
35
|
-
BgGreen = "\x1b[42m"
|
|
36
|
-
BgYellow = "\x1b[43m"
|
|
37
|
-
BgBlue = "\x1b[44m"
|
|
38
|
-
BgMagenta = "\x1b[45m"
|
|
39
|
-
BgCyan = "\x1b[46m"
|
|
40
|
-
BgWhite = "\x1b[47m"
|
|
41
|
-
*/
|
package/test/deployer.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const assert = require('chai').assert;
|
|
2
|
-
const Deployer = require('../lib/Deployer');
|
|
3
|
-
const testDataDir = 'test/data/deployer/';
|
|
4
|
-
|
|
5
|
-
describe('Deployer', () => {
|
|
6
|
-
describe('#readBUMetadata', () => {
|
|
7
|
-
it('should read metadata from local filesystem', async () => {
|
|
8
|
-
const metadata = Deployer.readBUMetadata(testDataDir);
|
|
9
|
-
// Check that metadata was successfully read
|
|
10
|
-
assert.exists(metadata.dataExtension);
|
|
11
|
-
assert.exists(metadata.dataExtension.Test);
|
|
12
|
-
assert.exists(metadata.dataExtension.Test.columns.idField);
|
|
13
|
-
assert.exists(metadata.folder);
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
});
|
package/test/util.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
const assert = require('chai').assert;
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const Util = require('../lib/util');
|
|
4
|
-
const dataDir = 'test_tmp/util/';
|
|
5
|
-
|
|
6
|
-
describe('Util', () => {
|
|
7
|
-
after(() => {
|
|
8
|
-
fs.removeSync(dataDir);
|
|
9
|
-
});
|
|
10
|
-
describe('#writeJSONToFile', () => {
|
|
11
|
-
it('should create json file and directory', async () => {
|
|
12
|
-
assert.strictEqual(fs.existsSync(dataDir + 'test1.json'), false);
|
|
13
|
-
const jsonContent = {
|
|
14
|
-
string: 'abc',
|
|
15
|
-
boolean: true,
|
|
16
|
-
number: 5,
|
|
17
|
-
array: ['asd', 4, 'asdf'],
|
|
18
|
-
obj: {
|
|
19
|
-
name: 'object',
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
await Util.writeJSONToFile(dataDir, 'test1', jsonContent);
|
|
23
|
-
assert.deepEqual(fs.readJSONSync(dataDir + 'test1.json'), jsonContent);
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
});
|