mcdev 3.1.3 → 4.0.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 +67 -7
- package/.github/ISSUE_TEMPLATE/bug.yml +2 -1
- package/.github/PULL_REQUEST_TEMPLATE.md +5 -3
- package/.github/dependabot.yml +14 -0
- package/.github/workflows/code-analysis.yml +57 -0
- package/.husky/commit-msg +10 -0
- package/.husky/post-checkout +5 -0
- package/.husky/pre-commit +2 -1
- package/.prettierrc +8 -0
- package/.vscode/settings.json +1 -1
- package/LICENSE +2 -2
- package/README.md +134 -45
- package/boilerplate/config.json +5 -11
- package/boilerplate/files/.prettierrc +8 -0
- package/boilerplate/files/.vscode/extensions.json +0 -1
- package/boilerplate/files/.vscode/settings.json +28 -2
- package/boilerplate/files/README.md +2 -2
- package/boilerplate/forcedUpdates.json +10 -0
- package/boilerplate/npm-dependencies.json +5 -5
- package/docs/dist/documentation.md +2795 -1724
- package/jsconfig.json +1 -1
- package/lib/Builder.js +166 -75
- package/lib/Deployer.js +244 -96
- package/lib/MetadataTypeDefinitions.js +2 -0
- package/lib/MetadataTypeInfo.js +2 -0
- package/lib/Retriever.js +61 -84
- package/lib/cli.js +116 -11
- package/lib/index.js +241 -561
- package/lib/metadataTypes/AccountUser.js +101 -95
- package/lib/metadataTypes/Asset.js +677 -248
- package/lib/metadataTypes/AttributeGroup.js +23 -12
- package/lib/metadataTypes/Automation.js +451 -354
- package/lib/metadataTypes/Campaign.js +33 -93
- package/lib/metadataTypes/ContentArea.js +31 -11
- package/lib/metadataTypes/DataExtension.js +387 -372
- package/lib/metadataTypes/DataExtensionField.js +131 -54
- package/lib/metadataTypes/DataExtensionTemplate.js +22 -4
- package/lib/metadataTypes/DataExtract.js +61 -48
- package/lib/metadataTypes/DataExtractType.js +14 -8
- package/lib/metadataTypes/Discovery.js +21 -16
- package/lib/metadataTypes/Email.js +32 -12
- package/lib/metadataTypes/EmailSendDefinition.js +85 -80
- package/lib/metadataTypes/EventDefinition.js +61 -43
- package/lib/metadataTypes/FileTransfer.js +72 -52
- package/lib/metadataTypes/Filter.js +11 -4
- package/lib/metadataTypes/Folder.js +149 -117
- package/lib/metadataTypes/FtpLocation.js +14 -8
- package/lib/metadataTypes/ImportFile.js +61 -64
- package/lib/metadataTypes/Interaction.js +19 -4
- package/lib/metadataTypes/List.js +54 -13
- package/lib/metadataTypes/MetadataType.js +668 -454
- package/lib/metadataTypes/MobileCode.js +46 -0
- package/lib/metadataTypes/MobileKeyword.js +114 -0
- package/lib/metadataTypes/Query.js +204 -103
- package/lib/metadataTypes/Role.js +76 -61
- package/lib/metadataTypes/Script.js +145 -81
- package/lib/metadataTypes/SetDefinition.js +20 -8
- package/lib/metadataTypes/TriggeredSendDefinition.js +78 -58
- package/lib/metadataTypes/definitions/Asset.definition.js +21 -10
- package/lib/metadataTypes/definitions/AttributeGroup.definition.js +12 -0
- package/lib/metadataTypes/definitions/Automation.definition.js +10 -5
- package/lib/metadataTypes/definitions/Campaign.definition.js +44 -1
- package/lib/metadataTypes/definitions/DataExtension.definition.js +4 -0
- package/lib/metadataTypes/definitions/DataExtensionTemplate.definition.js +6 -0
- package/lib/metadataTypes/definitions/DataExtract.definition.js +18 -14
- package/lib/metadataTypes/definitions/Discovery.definition.js +12 -0
- package/lib/metadataTypes/definitions/EmailSendDefinition.definition.js +4 -0
- package/lib/metadataTypes/definitions/EventDefinition.definition.js +22 -0
- package/lib/metadataTypes/definitions/FileTransfer.definition.js +4 -0
- package/lib/metadataTypes/definitions/Filter.definition.js +4 -0
- package/lib/metadataTypes/definitions/Folder.definition.js +6 -0
- package/lib/metadataTypes/definitions/FtpLocation.definition.js +4 -0
- package/lib/metadataTypes/definitions/ImportFile.definition.js +10 -5
- package/lib/metadataTypes/definitions/Interaction.definition.js +4 -0
- package/lib/metadataTypes/definitions/MobileCode.definition.js +163 -0
- package/lib/metadataTypes/definitions/MobileKeyword.definition.js +253 -0
- package/lib/metadataTypes/definitions/Query.definition.js +4 -0
- package/lib/metadataTypes/definitions/Role.definition.js +5 -0
- package/lib/metadataTypes/definitions/Script.definition.js +4 -0
- package/lib/metadataTypes/definitions/SetDefinition.definition.js +28 -0
- package/lib/metadataTypes/definitions/TriggeredSendDefinition.definition.js +4 -0
- package/lib/retrieveChangelog.js +7 -6
- package/lib/util/auth.js +117 -0
- package/lib/util/businessUnit.js +55 -66
- package/lib/util/cache.js +194 -0
- package/lib/util/cli.js +90 -116
- package/lib/util/config.js +302 -0
- package/lib/util/devops.js +240 -50
- package/lib/util/file.js +120 -191
- package/lib/util/init.config.js +195 -69
- package/lib/util/init.git.js +45 -50
- package/lib/util/init.js +72 -59
- package/lib/util/init.npm.js +48 -39
- package/lib/util/util.js +280 -564
- package/package.json +44 -33
- package/test/dataExtension.test.js +152 -0
- package/test/mockRoot/.mcdev-auth.json +8 -0
- package/test/mockRoot/.mcdevrc.json +67 -0
- package/test/mockRoot/deploy/testInstance/testBU/dataExtension/childBU_dataextension_test.dataExtension-meta.json +39 -0
- package/test/mockRoot/deploy/testInstance/testBU/dataExtension/testDataExtension.dataExtension-meta.json +23 -0
- package/test/mockRoot/deploy/testInstance/testBU/query/testExistingQuery.query-meta.json +11 -0
- package/test/mockRoot/deploy/testInstance/testBU/query/testExistingQuery.query-meta.sql +4 -0
- package/test/mockRoot/deploy/testInstance/testBU/query/testQuery.query-meta.json +11 -0
- package/test/mockRoot/deploy/testInstance/testBU/query/testQuery.query-meta.sql +4 -0
- package/test/query.test.js +149 -0
- package/test/resourceFactory.js +142 -0
- package/test/resources/1111111/dataFolder/retrieve-response.xml +43 -0
- package/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json +18 -0
- package/test/resources/9999999/automation/v1/queries/get-response.json +24 -0
- package/test/resources/9999999/automation/v1/queries/post-response.json +18 -0
- package/test/resources/9999999/dataExtension/build-expected.json +51 -0
- package/test/resources/9999999/dataExtension/create-expected.json +23 -0
- package/test/resources/9999999/dataExtension/create-response.xml +54 -0
- package/test/resources/9999999/dataExtension/retrieve-expected.json +51 -0
- package/test/resources/9999999/dataExtension/retrieve-response.xml +47 -0
- package/test/resources/9999999/dataExtension/template-expected.json +51 -0
- package/test/resources/9999999/dataExtension/update-expected.json +55 -0
- package/test/resources/9999999/dataExtension/update-response.xml +52 -0
- package/test/resources/9999999/dataExtensionField/retrieve-response.xml +93 -0
- package/test/resources/9999999/dataExtensionTemplate/retrieve-response.xml +303 -0
- package/test/resources/9999999/dataFolder/retrieve-response.xml +65 -0
- package/test/resources/9999999/query/build-expected.json +8 -0
- package/test/resources/9999999/query/get-expected.json +11 -0
- package/test/resources/9999999/query/patch-expected.json +11 -0
- package/test/resources/9999999/query/post-expected.json +11 -0
- package/test/resources/9999999/query/template-expected.json +8 -0
- package/test/resources/auth.json +32 -0
- package/test/resources/rest404-response.json +5 -0
- package/test/resources/retrieve-response.xml +21 -0
- package/test/utils.js +107 -0
- package/types/mcdev.d.js +301 -0
- package/CHANGELOG.md +0 -126
- package/PULL_REQUEST_TEMPLATE.md +0 -19
- package/test/util/file.js +0 -51
package/test/utils.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
const File = require('../lib/util/file');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const axios = require('axios');
|
|
4
|
+
const MockAdapter = require('axios-mock-adapter');
|
|
5
|
+
const auth = require('../lib/util/auth');
|
|
6
|
+
const Util = require('../lib/util/util');
|
|
7
|
+
|
|
8
|
+
// for some reason doesnt realize below reference
|
|
9
|
+
// eslint-disable-next-line no-unused-vars
|
|
10
|
+
const fsmock = require('mock-fs');
|
|
11
|
+
let apimock;
|
|
12
|
+
const authResources = require('./resources/auth.json');
|
|
13
|
+
const resourceFactory = require('./resourceFactory');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* gets file from Retrieve folder
|
|
17
|
+
*
|
|
18
|
+
* @param {string} customerKey of metadata
|
|
19
|
+
* @param {string} type of metadata
|
|
20
|
+
* @returns {Promise.<string>} file in string form
|
|
21
|
+
*/
|
|
22
|
+
exports.getActualFile = (customerKey, type) =>
|
|
23
|
+
File.readJSON(`./retrieve/testInstance/testBU/${type}/${customerKey}.${type}-meta.json`);
|
|
24
|
+
/**
|
|
25
|
+
* gets file from Deploy folder
|
|
26
|
+
*
|
|
27
|
+
* @param {string} customerKey of metadata
|
|
28
|
+
* @param {string} type of metadata
|
|
29
|
+
* @returns {Promise.<string>} file in string form
|
|
30
|
+
*/
|
|
31
|
+
exports.getActualDeployFile = (customerKey, type) =>
|
|
32
|
+
File.readJSON(`./deploy/testInstance/testBU/${type}/${customerKey}.${type}-meta.json`);
|
|
33
|
+
/**
|
|
34
|
+
* gets file from Template folder
|
|
35
|
+
*
|
|
36
|
+
* @param {string} customerKey of metadata
|
|
37
|
+
* @param {string} type of metadata
|
|
38
|
+
* @returns {Promise.<string>} file in string form
|
|
39
|
+
*/
|
|
40
|
+
exports.getActualTemplate = (customerKey, type) =>
|
|
41
|
+
File.readJSON(`./template/${type}/${customerKey}.${type}-meta.json`);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* gets file from resources folder which should be used for comparison
|
|
45
|
+
*
|
|
46
|
+
* @param {number} mid of Business Unit
|
|
47
|
+
* @param {string} type of metadata
|
|
48
|
+
* @param {string} action of SOAP request
|
|
49
|
+
* @returns {Promise.<string>} file in string form
|
|
50
|
+
*/
|
|
51
|
+
exports.getExpectedFile = (mid, type, action) =>
|
|
52
|
+
File.readJSON(path.join('test', 'resources', mid, type, action + '-expected.json'));
|
|
53
|
+
/**
|
|
54
|
+
* setup mocks for API and FS
|
|
55
|
+
*
|
|
56
|
+
* @returns {void}
|
|
57
|
+
*/
|
|
58
|
+
exports.mockSetup = () => {
|
|
59
|
+
Util.setLoggingLevel({ debug: true });
|
|
60
|
+
apimock = new MockAdapter(axios, { onNoMatch: 'throwException' });
|
|
61
|
+
// set access_token to mid to allow for autorouting of mock to correct resources
|
|
62
|
+
apimock.onPost(authResources.success.url).reply((config) => {
|
|
63
|
+
authResources.success.response.access_token = JSON.parse(config.data).account_id;
|
|
64
|
+
return [authResources.success.status, authResources.success.response];
|
|
65
|
+
});
|
|
66
|
+
apimock
|
|
67
|
+
.onPost(resourceFactory.soapUrl)
|
|
68
|
+
.reply((config) => resourceFactory.handleSOAPRequest(config));
|
|
69
|
+
apimock
|
|
70
|
+
.onAny(new RegExp(`^${escapeRegExp(resourceFactory.restUrl)}`))
|
|
71
|
+
.reply((config) => resourceFactory.handleRESTRequest(config));
|
|
72
|
+
fsmock({
|
|
73
|
+
'.prettierrc': fsmock.load(path.resolve(__dirname, '../boilerplate/files/.prettierrc')),
|
|
74
|
+
'.mcdevrc.json': fsmock.load(path.resolve(__dirname, 'mockRoot/.mcdevrc.json')),
|
|
75
|
+
'.mcdev-auth.json': fsmock.load(path.resolve(__dirname, 'mockRoot/.mcdev-auth.json')),
|
|
76
|
+
'boilerplate/config.json': fsmock.load(
|
|
77
|
+
path.resolve(__dirname, '../boilerplate/config.json')
|
|
78
|
+
),
|
|
79
|
+
deploy: fsmock.load(path.resolve(__dirname, 'mockRoot/deploy')),
|
|
80
|
+
test: fsmock.load(path.resolve(__dirname)),
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* resets mocks for API and FS
|
|
85
|
+
*
|
|
86
|
+
* @returns {void}
|
|
87
|
+
*/
|
|
88
|
+
exports.mockReset = () => {
|
|
89
|
+
auth.clearSessions();
|
|
90
|
+
apimock.restore();
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* helper to return api history
|
|
94
|
+
*
|
|
95
|
+
* @returns {object} of API history
|
|
96
|
+
*/
|
|
97
|
+
exports.getAPIHistory = () => apimock.history;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* escapes string for regex
|
|
101
|
+
*
|
|
102
|
+
* @param {string} str to escape
|
|
103
|
+
* @returns {string} escaped string
|
|
104
|
+
*/
|
|
105
|
+
function escapeRegExp(str) {
|
|
106
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
107
|
+
}
|
package/types/mcdev.d.js
ADDED
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
const SDK = require('sfmc-sdk');
|
|
2
|
+
/**
|
|
3
|
+
* @ignore
|
|
4
|
+
* @typedef {object} BuObject
|
|
5
|
+
* @property {string} clientId installed package client id
|
|
6
|
+
* @property {string} clientSecret installed package client secret
|
|
7
|
+
* @property {string} tenant subdomain part of Authentication Base Uri
|
|
8
|
+
* @property {string} [eid] Enterprise ID = MID of the parent BU
|
|
9
|
+
* @property {string} [mid] MID of the BU to work with
|
|
10
|
+
* @property {string} [businessUnit] name of the BU to interact with
|
|
11
|
+
* @property {string} [credential] name of the credential to interact with
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Object.<string, string>} TemplateMap
|
|
15
|
+
* @typedef {'accountUser'|'asset'|'attributeGroup'|'automation'|'campaign'|'contentArea'|'dataExtension'|'dataExtensionField'|'dataExtensionTemplate'|'dataExtract'|'dataExtractType'|'discovery'|'email'|'emailSendDefinition'|'eventDefinition'|'fileTransfer'|'filter'|'folder'|'ftpLocation'|'importFile'|'interaction'|'list'|'mobileCode'|'mobileKeyword'|'query'|'role'|'script'|'setDefinition'|'triggeredSendDefinition'} SupportedMetadataTypes
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {Object.<string, any>} MetadataTypeItem
|
|
20
|
+
* @typedef {Object.<string, MetadataTypeItem>} MetadataTypeMap key=customer key
|
|
21
|
+
* @typedef {Object.<string, MetadataTypeMap>} MultiMetadataTypeMap key=Supported MetadataType
|
|
22
|
+
* @typedef {Object.<string, MetadataTypeItem[]>} MultiMetadataTypeList key=Supported MetadataType
|
|
23
|
+
* @typedef {{metadata:MetadataTypeMap,type:SupportedMetadataTypes}} MetadataTypeMapObj
|
|
24
|
+
* @typedef {{metadata:MetadataTypeItem,type:SupportedMetadataTypes}} MetadataTypeItemObj
|
|
25
|
+
* @typedef {Object.<number, MultiMetadataTypeMap>} Cache key=MID
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @typedef {object} CodeExtractItem
|
|
30
|
+
* @property {MetadataTypeItem} json metadata of one item w/o code
|
|
31
|
+
* @property {CodeExtract[]} codeArr list of code snippets in this item
|
|
32
|
+
* @property {string[]} subFolder mostly set to null, otherwise list of subfolders
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* @typedef {object} CodeExtract
|
|
36
|
+
* @property {string[]} subFolder mostly set to null, otherwise subfolders path split into elements
|
|
37
|
+
* @property {string} fileName name of file w/o extension
|
|
38
|
+
* @property {string} fileExt file extension
|
|
39
|
+
* @property {string} content file content
|
|
40
|
+
* @property {'base64'} [encoding] optional for binary files
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {object} QueryItem
|
|
44
|
+
* @property {string} name name
|
|
45
|
+
* @property {string} key key
|
|
46
|
+
* @property {string} description -
|
|
47
|
+
* @property {string} targetKey key of target data extension
|
|
48
|
+
* @property {string} createdDate e.g. "2020-09-14T01:42:03.017"
|
|
49
|
+
* @property {string} modifiedDate e.g. "2020-09-14T01:42:03.017"
|
|
50
|
+
* @property {'Overwrite'|'Update'|'Append'} targetUpdateTypeName defines how the query writes into the target data extension
|
|
51
|
+
* @property {0|1|2} [targetUpdateTypeId] mapped to targetUpdateTypeName via this.definition.targetUpdateTypeMapping
|
|
52
|
+
* @property {string} [targetId] Object ID of DE (removed before save)
|
|
53
|
+
* @property {string} [targetDescription] Description DE (removed before save)
|
|
54
|
+
* @property {boolean} isFrozen looks like this is always set to false
|
|
55
|
+
* @property {string} [queryText] contains SQL query with line breaks converted to '\n'. The content is extracted during retrieval and written into a separate *.sql file
|
|
56
|
+
* @property {string} [categoryId] holds folder ID, replaced with r__folder_Path during retrieve
|
|
57
|
+
* @property {string} r__folder_Path folder path in which this DE is saved
|
|
58
|
+
* @typedef {Object.<string, QueryItem>} QueryMap
|
|
59
|
+
* @typedef {object} CodeExtractItem
|
|
60
|
+
* @property {QueryItem} json metadata of one item w/o code
|
|
61
|
+
* @property {CodeExtract[]} codeArr list of code snippets in this item
|
|
62
|
+
* @property {string[]} subFolder mostly set to null, otherwise list of subfolders
|
|
63
|
+
*/
|
|
64
|
+
/**
|
|
65
|
+
* @typedef {object} ScriptItem
|
|
66
|
+
* @property {string} name name
|
|
67
|
+
* @property {string} key key
|
|
68
|
+
* @property {string} description -
|
|
69
|
+
* @property {string} createdDate e.g. "2020-09-14T01:42:03.017"
|
|
70
|
+
* @property {string} modifiedDate e.g. "2020-09-14T01:42:03.017"
|
|
71
|
+
* @property {string} [script] contains script with line breaks converted to '\n'. The content is extracted during retrieval and written into a separate *.ssjs file
|
|
72
|
+
* @property {string} [categoryId] holds folder ID, replaced with r__folder_Path during retrieve
|
|
73
|
+
* @property {string} r__folder_Path folder path in which this DE is saved
|
|
74
|
+
* @typedef {Object.<string, ScriptItem>} ScriptMap
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* @typedef {Object.<string, any>} AssetItem
|
|
78
|
+
* @typedef {Object.<string, AssetItem>} AssetMap
|
|
79
|
+
* @typedef {'archive'|'asset'|'audio'|'block'|'code'|'document'|'image'|'message'|'other'|'rawimage'|'template'|'textfile'|'video'} AssetSubType
|
|
80
|
+
*/
|
|
81
|
+
/**
|
|
82
|
+
* @typedef {object} DataExtensionFieldItem
|
|
83
|
+
* @property {string} [ObjectID] id
|
|
84
|
+
* @property {string} [CustomerKey] key in format [DEkey].[FieldName]
|
|
85
|
+
* @property {object} [DataExtension] -
|
|
86
|
+
* @property {string} DataExtension.CustomerKey key of DE
|
|
87
|
+
* @property {string} Name name of field
|
|
88
|
+
* @property {string} [Name_new] custom attribute that is only used when trying to rename a field from Name to Name_new
|
|
89
|
+
* @property {string} DefaultValue empty string for not set
|
|
90
|
+
* @property {true|false} IsRequired -
|
|
91
|
+
* @property {true|false} IsPrimaryKey -
|
|
92
|
+
* @property {string} Ordinal 1, 2, 3, ...
|
|
93
|
+
* @property {'Text'|'Number'|'Date'|'Boolean'|'Decimal'|'EmailAddress'|'Phone'|'Locale'} FieldType can only be set on create
|
|
94
|
+
* @property {string} Scale the number of places after the decimal that the field can hold; example: "0","1", ...
|
|
95
|
+
* @typedef {Object.<string, DataExtensionFieldItem>} DataExtensionFieldMap
|
|
96
|
+
*/
|
|
97
|
+
/**
|
|
98
|
+
* @typedef {object} DataExtensionItem
|
|
99
|
+
* @property {string} CustomerKey key
|
|
100
|
+
* @property {string} Name name
|
|
101
|
+
* @property {string} Description -
|
|
102
|
+
* @property {string} [CreatedDate] iso format
|
|
103
|
+
* @property {string} [ModifiedDate] iso format
|
|
104
|
+
* @property {true|false} IsSendable -
|
|
105
|
+
* @property {true|false} IsTestable -
|
|
106
|
+
* @property {object} SendableDataExtensionField -
|
|
107
|
+
* @property {string} SendableDataExtensionField.Name -
|
|
108
|
+
* @property {object} SendableSubscriberField -
|
|
109
|
+
* @property {string} SendableSubscriberField.Name -
|
|
110
|
+
* @property {DataExtensionFieldItem[]} Fields list of DE fields
|
|
111
|
+
* @property {'dataextension'|'salesforcedataextension'|'synchronizeddataextension'|'shared_dataextension'|'shared_salesforcedataextension'} r__folder_ContentType retrieved from associated folder
|
|
112
|
+
* @property {string} r__folder_Path folder path in which this DE is saved
|
|
113
|
+
* @property {string} [CategoryID] holds folder ID, replaced with r__folder_Path during retrieve
|
|
114
|
+
* @property {string} [r__dataExtensionTemplate_Name] name of optionally associated DE template
|
|
115
|
+
* @property {object} [Template] -
|
|
116
|
+
* @property {string} [Template.CustomerKey] key of optionally associated DE teplate
|
|
117
|
+
* @typedef {Object.<string, DataExtensionItem>} DataExtensionMap
|
|
118
|
+
*/
|
|
119
|
+
/**
|
|
120
|
+
* @typedef {object} AccountUserDocument
|
|
121
|
+
* @property {string} TYPE user.type__c
|
|
122
|
+
* @property {string} UserID user.UserID
|
|
123
|
+
* @property {string} AccountUserID user.AccountUserID
|
|
124
|
+
* @property {string} CustomerKey user.CustomerKey
|
|
125
|
+
* @property {string} Name user.Name
|
|
126
|
+
* @property {string} Email user.Email
|
|
127
|
+
* @property {string} NotificationEmailAddress user.NotificationEmailAddress
|
|
128
|
+
* @property {string} ActiveFlag user.ActiveFlag === true ? '✓' : '-'
|
|
129
|
+
* @property {string} IsAPIUser user.IsAPIUser === true ? '✓' : '-'
|
|
130
|
+
* @property {string} MustChangePassword user.MustChangePassword === true ? '✓' : '-'
|
|
131
|
+
* @property {string} DefaultBusinessUnit defaultBUName
|
|
132
|
+
* @property {string} AssociatedBusinessUnits__c associatedBus
|
|
133
|
+
* @property {string} Roles roles
|
|
134
|
+
* @property {string} UserPermissions userPermissions
|
|
135
|
+
* @property {string} LastSuccessfulLogin this.timeSinceDate(user.LastSuccessfulLogin)
|
|
136
|
+
* @property {string} CreatedDate user.CreatedDate
|
|
137
|
+
* @property {string} ModifiedDate user.ModifiedDate
|
|
138
|
+
*/
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @typedef {object} AutomationActivity
|
|
142
|
+
* @property {string} name name (not key) of activity
|
|
143
|
+
* @property {string} [objectTypeId] Id of assoicated activity type; see this.definition.activityTypeMapping
|
|
144
|
+
* @property {string} [activityObjectId] Object Id of assoicated metadata item
|
|
145
|
+
* @property {number} [displayOrder] order within step; starts with 1 or higher number
|
|
146
|
+
* @property {string} r__type see this.definition.activityTypeMapping
|
|
147
|
+
*/
|
|
148
|
+
/**
|
|
149
|
+
* @typedef {object} AutomationStep
|
|
150
|
+
* @property {string} name description
|
|
151
|
+
* @property {string} [annotation] equals AutomationStep.name
|
|
152
|
+
* @property {number} [step] step iterator; starts with 1
|
|
153
|
+
* @property {number} [stepNumber] step iterator, automatically set during deployment
|
|
154
|
+
* @property {AutomationActivity[]} activities -
|
|
155
|
+
*/
|
|
156
|
+
/**
|
|
157
|
+
* @typedef {object} AutomationSchedule REST format
|
|
158
|
+
* @property {number} typeId ?
|
|
159
|
+
* @property {string} startDate example: '2021-05-07T09:00:00'
|
|
160
|
+
* @property {string} endDate example: '2021-05-07T09:00:00'
|
|
161
|
+
* @property {string} icalRecur example: 'FREQ=DAILY;UNTIL=20790606T160000;INTERVAL=1'
|
|
162
|
+
* @property {string} timezoneName example: 'W. Europe Standard Time'; see this.definition.timeZoneMapping
|
|
163
|
+
* @property {number} [timezoneId] see this.definition.timeZoneMapping
|
|
164
|
+
*/
|
|
165
|
+
/**
|
|
166
|
+
* @typedef {object} AutomationScheduleSoap SOAP format
|
|
167
|
+
* @property {object} Recurrence -
|
|
168
|
+
* @property {object} Recurrence.$ {'xsi:type': keyStem + 'lyRecurrence'}
|
|
169
|
+
* @property {'ByYear'} [Recurrence.YearlyRecurrencePatternType] * currently not supported by tool *
|
|
170
|
+
* @property {'ByMonth'} [Recurrence.MonthlyRecurrencePatternType] * currently not supported by tool *
|
|
171
|
+
* @property {'ByWeek'} [Recurrence.WeeklyRecurrencePatternType] * currently not supported by tool *
|
|
172
|
+
* @property {'ByDay'} [Recurrence.DailyRecurrencePatternType] -
|
|
173
|
+
* @property {'Interval'} [Recurrence.MinutelyRecurrencePatternType] -
|
|
174
|
+
* @property {'Interval'} [Recurrence.HourlyRecurrencePatternType] -
|
|
175
|
+
* @property {number} [Recurrence.YearInterval] 1..n * currently not supported by tool *
|
|
176
|
+
* @property {number} [Recurrence.MonthInterval] 1..n * currently not supported by tool *
|
|
177
|
+
* @property {number} [Recurrence.WeekInterval] 1..n * currently not supported by tool *
|
|
178
|
+
* @property {number} [Recurrence.DayInterval] 1..n
|
|
179
|
+
* @property {number} [Recurrence.HourInterval] 1..n
|
|
180
|
+
* @property {number} [Recurrence.MinuteInterval] 1..n
|
|
181
|
+
* @property {number} _interval internal variable for CLI output only
|
|
182
|
+
* @property {object} TimeZone -
|
|
183
|
+
* @property {number} TimeZone.ID AutomationSchedule.timezoneId
|
|
184
|
+
* @property {string} _timezoneString internal variable for CLI output only
|
|
185
|
+
* @property {string} StartDateTime AutomationSchedule.startDate
|
|
186
|
+
* @property {string} EndDateTime AutomationSchedule.endDate
|
|
187
|
+
* @property {string} _StartDateTime AutomationSchedule.startDate; internal variable for CLI output only
|
|
188
|
+
* @property {'EndOn'|'EndAfter'} RecurrenceRangeType set to 'EndOn' if AutomationSchedule.icalRecur contains 'UNTIL'; otherwise to 'EndAfter'
|
|
189
|
+
* @property {number} Occurrences only exists if RecurrenceRangeType=='EndAfter'
|
|
190
|
+
*/
|
|
191
|
+
/**
|
|
192
|
+
* @typedef {object} AutomationItem
|
|
193
|
+
* @property {string} [id] Object Id
|
|
194
|
+
* @property {string} key key
|
|
195
|
+
* @property {string} name name
|
|
196
|
+
* @property {string} description -
|
|
197
|
+
* @property {'scheduled'|'triggered'} type Starting Source = Schedule / File Drop
|
|
198
|
+
* @property {'Scheduled'|'Running'|'Ready'|'Building'|'PausedSchedule'|'InactiveTrigger'} status -
|
|
199
|
+
* @property {AutomationSchedule} [schedule] only existing if type=scheduled
|
|
200
|
+
* @property {object} [fileTrigger] only existing if type=triggered
|
|
201
|
+
* @property {string} fileTrigger.fileNamingPattern file name with placeholders
|
|
202
|
+
* @property {number} fileTrigger.fileNamePatternTypeId -
|
|
203
|
+
* @property {string} fileTrigger.folderLocationText where to look for the fileNamingPattern
|
|
204
|
+
* @property {boolean} fileTrigger.isPublished ?
|
|
205
|
+
* @property {boolean} fileTrigger.queueFiles ?
|
|
206
|
+
* @property {boolean} fileTrigger.triggerActive -
|
|
207
|
+
* @property {object} [startSource] -
|
|
208
|
+
* @property {AutomationSchedule} [startSource.schedule] rewritten to AutomationItem.schedule
|
|
209
|
+
* @property {object} [startSource.fileDrop] rewritten to AutomationItem.fileTrigger
|
|
210
|
+
* @property {string} startSource.fileDrop.fileNamingPattern file name with placeholders
|
|
211
|
+
* @property {string} startSource.fileDrop.fileNamePatternTypeId -
|
|
212
|
+
* @property {string} startSource.fileDrop.folderLocation -
|
|
213
|
+
* @property {boolean} startSource.fileDrop.queueFiles -
|
|
214
|
+
* @property {number} startSource.typeId -
|
|
215
|
+
* @property {AutomationStep[]} steps -
|
|
216
|
+
* @property {string} r__folder_Path folder path
|
|
217
|
+
* @property {string} [categoryId] holds folder ID, replaced with r__folder_Path during retrieve
|
|
218
|
+
*/
|
|
219
|
+
/**
|
|
220
|
+
* @typedef {Object.<string, AutomationItem>} AutomationMap
|
|
221
|
+
* @typedef {{metadata:AutomationMap,type:string}} AutomationMapObj
|
|
222
|
+
* @typedef {{metadata:AutomationItem,type:string}} AutomationItemObj
|
|
223
|
+
* @typedef {object} DeltaPkgItem
|
|
224
|
+
* @property {string} file relative path to file
|
|
225
|
+
* @property {number} changes changed lines
|
|
226
|
+
* @property {number} insertions added lines
|
|
227
|
+
* @property {number} deletions deleted lines
|
|
228
|
+
* @property {boolean} binary is a binary file
|
|
229
|
+
* @property {boolean} moved git thinks this file was moved
|
|
230
|
+
* @property {string} [fromPath] git thinks this relative path is where the file was before
|
|
231
|
+
* @property {SupportedMetadataTypes} type metadata type
|
|
232
|
+
* @property {string} externalKey key
|
|
233
|
+
* @property {string} name name
|
|
234
|
+
* @property {'move'|'add/update'|'delete'} gitAction what git recognized as an action
|
|
235
|
+
* @property {string} _credential mcdev credential name
|
|
236
|
+
* @property {string} _businessUnit mcdev business unit name inside of _credential
|
|
237
|
+
* @typedef {SDK} SDK
|
|
238
|
+
*/
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* @typedef {object} skipInteraction signals what to insert automatically for things usually asked via wizard
|
|
242
|
+
* @property {string} client_id client id of installed package
|
|
243
|
+
* @property {string} client_secret client secret of installed package
|
|
244
|
+
* @property {string} auth_url tenant specific auth url of installed package
|
|
245
|
+
* @property {number} account_id MID of the Parent Business Unit
|
|
246
|
+
* @property {string} credentialName how you would like the credential to be named
|
|
247
|
+
* @property {string} gitRemoteUrl URL of Git remote server
|
|
248
|
+
*/
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* @typedef {object} AuthObject
|
|
252
|
+
* @property {string} client_id client_id client_id for sfmc-sdk auth
|
|
253
|
+
* @property {string} client_secret client_secret for sfmc-sdk auth
|
|
254
|
+
* @property {number} account_id mid of business unit to auth against
|
|
255
|
+
* @property {string} auth_url authentication base url
|
|
256
|
+
*/
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* @typedef {object} SoapRequestParams
|
|
260
|
+
* @property {string} [continueRequest] request id
|
|
261
|
+
* @property {object} [options] additional options (CallsInConversation, Client, ConversationID, Priority, RequestType, SaveOptions, ScheduledTime, SendResponseTo, SequenceCode)
|
|
262
|
+
* @property {*} clientIDs ?
|
|
263
|
+
* @property {SoapFilter} [filter] simple or complex
|
|
264
|
+
complex
|
|
265
|
+
* @property {boolean} [QueryAllAccounts] all BUs or just one
|
|
266
|
+
* @typedef {object} SoapFilter
|
|
267
|
+
* @property {string|SoapFilter} leftOperand string for simple or a new filter-object for complex
|
|
268
|
+
* @property {'AND'|'OR'|'equals'|'notEquals'|'isNull'|'isNotNull'|'greaterThan'|'lessThan'|'greaterThanOrEqual'|'lessThanOrEqual'|'between'|'IN'|'like'} operator various options
|
|
269
|
+
* @property {string|number|boolean|Array|SoapFilter} [rightOperand] string for simple or a new filter-object for complex; omit for isNull and isNotNull
|
|
270
|
+
*/
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* @typedef {object} Mcdevrc
|
|
274
|
+
* @property {object} credentials list of credentials
|
|
275
|
+
* @property {object} options configure options for mcdev
|
|
276
|
+
* @property {object} directories configure directories for mcdev to read/write to
|
|
277
|
+
* @property {string} directories.businessUnits "businessUnits/"
|
|
278
|
+
* @property {string} directories.deploy "deploy/"
|
|
279
|
+
* @property {string} directories.docs "docs/"
|
|
280
|
+
* @property {string} directories.retrieve "retrieve/"
|
|
281
|
+
* @property {string} directories.template "template/"
|
|
282
|
+
* @property {string} directories.templateBuilds ["retrieve/", "deploy/"]
|
|
283
|
+
* @property {Object.<string, object>} markets templating variables grouped by markets
|
|
284
|
+
* @property {object} marketList combination of markets and BUs for streamlined deployments
|
|
285
|
+
* @property {object} metaDataTypes templating variables grouped by markets
|
|
286
|
+
* @property {string[]} metaDataTypes.retrieve define what types shall be downloaded by default during retrieve
|
|
287
|
+
* @property {string[]} metaDataTypes.documentOnRetrieve which types should be parsed & documented after retrieve
|
|
288
|
+
* @property {string} version mcdev version that last updated the config file
|
|
289
|
+
*/
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* @typedef {object} Logger
|
|
293
|
+
* @property {Function} info (msg) print info message
|
|
294
|
+
* @property {Function} warn (msg) print warning message
|
|
295
|
+
* @property {Function} verbose (msg) additional messages that are not important
|
|
296
|
+
* @property {Function} debug (msg) print debug message
|
|
297
|
+
* @property {Function} error (msg) print error message
|
|
298
|
+
* @property {Function} errorStack (ex, msg) print error with trace message
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
module.exports = {};
|
package/CHANGELOG.md
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
Accenture SFMC DevTools follows [semantic versioning](https://semver.org/).
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## [3.1.1](https://github.com/Accenture/sfmc-devtools/compare/v3.1.0...v3.1.1) - 2022-01-10
|
|
8
|
-
|
|
9
|
-
**Bugfixes:**
|
|
10
|
-
|
|
11
|
-
- [#160](https://github.com/Accenture/sfmc-devtools/issues/160) mcdev outputs bogus text since dependency colorjs got corrupted ( [background story](https://www.theverge.com/2022/1/9/22874949/developer-corrupts-open-source-libraries-projects-affected))
|
|
12
|
-
|
|
13
|
-
**Chores:**
|
|
14
|
-
|
|
15
|
-
- bumped cli-progress to 3.10.0 (removes colors dependency)
|
|
16
|
-
- bumped winston to 3.3.4 (removes colors dependency)
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## [3.1.0](https://github.com/Accenture/sfmc-devtools/compare/v3.0.3...v3.1.0) - 2021-12-27
|
|
21
|
-
|
|
22
|
-
**Features:**
|
|
23
|
-
|
|
24
|
-
- [#55](https://github.com/Accenture/sfmc-devtools/issues/55) added user / roles documentation
|
|
25
|
-
- [#64](https://github.com/Accenture/sfmc-devtools/issues/64) Added `accountUser` (system users) support (retrieve)
|
|
26
|
-
- [#103](https://github.com/Accenture/sfmc-devtools/issues/103) Add rename `dataExtensionField` option (via Name_new)
|
|
27
|
-
- [#130](https://github.com/Accenture/sfmc-devtools/issues/130) offer `retrieveChangelog` option to other node packages including mcdev (see [retrieveChangelog.js](/lib/retrieveChangelog.js) for a how-to)
|
|
28
|
-
- [#133](https://github.com/Accenture/sfmc-devtools/issues/133) `dataExtensionField` validation during DE update (see [README](README.md#722-addingupdating-fields-on-existing-data-extensions) for details)
|
|
29
|
-
- [#136](https://github.com/Accenture/sfmc-devtools/issues/136) enable including mcdev in other node packages (see [README](README.md#26-using-mcdev-in-other-node-packages) for a how-to)
|
|
30
|
-
- [#144](https://github.com/Accenture/sfmc-devtools/issues/144) added file type .ai to `asset` - thanks to @fbellgr
|
|
31
|
-
|
|
32
|
-
**Bugfixes:**
|
|
33
|
-
|
|
34
|
-
- [#112](https://github.com/Accenture/sfmc-devtools/issues/112) add (unknown) new type 783 to defintion of `importFile`
|
|
35
|
-
- [#117](https://github.com/Accenture/sfmc-devtools/issues/117) `queries` not deployable when target is `shared DE`
|
|
36
|
-
- [#118](https://github.com/Accenture/sfmc-devtools/issues/118) `automation` start not auto-retried during deploy
|
|
37
|
-
- [#119](https://github.com/Accenture/sfmc-devtools/issues/119) fixed `list` dependency for importFile
|
|
38
|
-
- [#122](https://github.com/Accenture/sfmc-devtools/issues/122) ECONNRESET on caching metadata during deploy
|
|
39
|
-
- [#128](https://github.com/Accenture/sfmc-devtools/issues/128) `dataExtension` json not equal for retrieve/deploy
|
|
40
|
-
- [#129](https://github.com/Accenture/sfmc-devtools/issues/129) `script` json not equal for retrieve/deploy
|
|
41
|
-
- [#140](https://github.com/Accenture/sfmc-devtools/issues/140) avoid issues when retrieving `dataExtensions` that do not have a folder ID (edge case) - thanks to @fbellgr
|
|
42
|
-
- [#144](https://github.com/Accenture/sfmc-devtools/issues/144) improved handling high volumes of `asset` - thanks to @fbellgr
|
|
43
|
-
- [#149](https://github.com/Accenture/sfmc-devtools/issues/149) handle errors on upsert of data extensions gracefully
|
|
44
|
-
|
|
45
|
-
**Chores:**
|
|
46
|
-
|
|
47
|
-
- [#5](https://github.com/Accenture/sfmc-devtools/issues/5) removed postinstall msg after npm 7 dropped support for that
|
|
48
|
-
- [#127](https://github.com/Accenture/sfmc-devtools/issues/127) bad message "info: updated automation: undefined"
|
|
49
|
-
- [#132](https://github.com/Accenture/sfmc-devtools/issues/132) `dataExtension.SendableSubscriberField.Name` now has a slightly more readable value
|
|
50
|
-
- [#137](https://github.com/Accenture/sfmc-devtools/issues/137) docs for installing a specific version were incorrect
|
|
51
|
-
- [#138](https://github.com/Accenture/sfmc-devtools/issues/138) make issues and pull requests clickable in gitfork
|
|
52
|
-
- change `mcdev document` to take the cred/BU first and then the type to align it with other commands
|
|
53
|
-
- improved error handling of `document role` command
|
|
54
|
-
- bumped cli-progress to 3.9.1
|
|
55
|
-
- bumped eslint to 8.4.1
|
|
56
|
-
- bumped eslint-plugin-mocha to 10.0.1
|
|
57
|
-
- bumped eslint-plugin-prettier to 4.0.0
|
|
58
|
-
- bumped fs-extra to 10.0.0
|
|
59
|
-
- bumped husky to 7.0.4
|
|
60
|
-
- bumped inquirer to 8.2.0
|
|
61
|
-
- bumped jsdoc-to-markdown to 7.1.0
|
|
62
|
-
- bumped lint-staged to 12.1.2
|
|
63
|
-
- bumped mocha to 9.1.3
|
|
64
|
-
- bumped mustache to 4.2.0
|
|
65
|
-
- bumped prettier to 2.5.1
|
|
66
|
-
- bumped semver to 7.3.5
|
|
67
|
-
- bumped simple-git to 2.48.0
|
|
68
|
-
- bumped yargs to 17.3.0
|
|
69
|
-
- [#146](https://github.com/Accenture/sfmc-devtools/issues/146) remove AccountUser retrieve as a default retrieve option
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## [3.0.3](https://github.com/Accenture/sfmc-devtools/compare/v3.0.2...v3.0.3) - 2021-08-11
|
|
74
|
-
|
|
75
|
-
**Bugfixes:**
|
|
76
|
-
|
|
77
|
-
- [#100](https://github.com/Accenture/sfmc-devtools/issues/100) Handle ECONNRESET errors across various types (incl. Data Extensions)
|
|
78
|
-
- [#102](https://github.com/Accenture/sfmc-devtools/issues/102) block deployment attempt for synchronized Data Extensions with proper error message
|
|
79
|
-
- [#104](https://github.com/Accenture/sfmc-devtools/issues/104) block deployment of shared data extensions on child BUs (existing solution broke somewhere down the line)
|
|
80
|
-
|
|
81
|
-
**Chores:**
|
|
82
|
-
|
|
83
|
-
- [#107](https://github.com/Accenture/sfmc-devtools/issues/107) rewrite folder to use generic update/create to help with ECONNRESET issue
|
|
84
|
-
- [#108](https://github.com/Accenture/sfmc-devtools/issues/108) return full API error messages for create & update via SOAP
|
|
85
|
-
- [#110](https://github.com/Accenture/sfmc-devtools/issues/110) improve error message for missing dependencies
|
|
86
|
-
- bumped jsdoc-to-markdown to 7.0.1
|
|
87
|
-
- bumped eslint-plugin-mocha to 9.0.0
|
|
88
|
-
- bumped eslint-plugin-prettier to 3.4.0
|
|
89
|
-
- bumped eslint-config-prettier to 8.3.0
|
|
90
|
-
- bumped eslint to 7.32.0
|
|
91
|
-
- enhanced Pull Request Template with note on `npm run docs`
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
## [3.0.2](https://github.com/Accenture/sfmc-devtools/compare/v3.0.1...v3.0.2) - 2021-08-03
|
|
96
|
-
|
|
97
|
-
**Bugfixes:**
|
|
98
|
-
|
|
99
|
-
- [#26](https://github.com/Accenture/sfmc-devtools/issues/26) retrieving asset subtypes via r ... asset-xyz actually saves result to disk
|
|
100
|
-
- [#45](https://github.com/Accenture/sfmc-devtools/issues/45) connection errors for automations fixed
|
|
101
|
-
- [#46](https://github.com/Accenture/sfmc-devtools/issues/46) (temp fix) campaigns break entire retrieve - disabled for now
|
|
102
|
-
- [#48](https://github.com/Accenture/sfmc-devtools/issues/48) connection errors for dataExtensions and other types are now handled gracefully
|
|
103
|
-
- [#49](https://github.com/Accenture/sfmc-devtools/issues/49) connection errors for asset subtypes no longer restart downloading all subtypes
|
|
104
|
-
- [#51](https://github.com/Accenture/sfmc-devtools/issues/51) retrieving asset subtypes now always uses the default list of subtypes
|
|
105
|
-
- [#52](https://github.com/Accenture/sfmc-devtools/issues/52) no more endless retries in case of connection errors
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## [3.0.1](https://github.com/Accenture/sfmc-devtools/compare/v3.0.0...v3.0.1) - 2021-04-11
|
|
110
|
-
|
|
111
|
-
**Bugfixes:**
|
|
112
|
-
|
|
113
|
-
- fix [#4](https://github.com/Accenture/sfmc-devtools/issues/4): retrieveAsTemplate led to fatal error if target metadata was not found
|
|
114
|
-
- migration from prior internal version was not handled gracefully before
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## 3.0.0 - 2021-03-26
|
|
119
|
-
|
|
120
|
-
Initial public release.
|
|
121
|
-
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
## 2.0.0 - 2020-02-03
|
|
125
|
-
|
|
126
|
-
Initial Accenture-wide release.
|
package/PULL_REQUEST_TEMPLATE.md
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# PR details
|
|
2
|
-
|
|
3
|
-
## What is the purpose of this pull request? (put an "X" next to an item)
|
|
4
|
-
|
|
5
|
-
- [ ] Documentation update
|
|
6
|
-
- [ ] Bug fix
|
|
7
|
-
- [ ] New metadata support
|
|
8
|
-
- [ ] Enhanced metadata
|
|
9
|
-
- [ ] Add a CLI option
|
|
10
|
-
- [ ] Add something to the core
|
|
11
|
-
- [ ] Other, please explain:
|
|
12
|
-
|
|
13
|
-
## What changes did you make? (Give an overview)
|
|
14
|
-
|
|
15
|
-
...
|
|
16
|
-
|
|
17
|
-
## Is there anything you'd like reviewers to focus on?
|
|
18
|
-
|
|
19
|
-
...
|
package/test/util/file.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
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
|
-
});
|