mcdev 4.1.0 → 4.1.1
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/.github/ISSUE_TEMPLATE/bug.yml +2 -0
- package/.github/workflows/npm-publish.yml +24 -24
- package/README.md +5 -5
- package/boilerplate/files/.vscode/settings.json +3 -0
- package/boilerplate/forcedUpdates.json +4 -0
- package/docs/dist/documentation.md +15 -15
- package/lib/Deployer.js +34 -7
- package/lib/index.js +1 -1
- package/lib/metadataTypes/Asset.js +1 -1
- package/lib/metadataTypes/ImportFile.js +28 -14
- package/lib/metadataTypes/MetadataType.js +1 -1
- package/lib/util/devops.js +1 -1
- package/lib/util/util.js +28 -5
- package/package.json +6 -3
- package/test/mockRoot/.mcdevrc.json +1 -1
|
@@ -4,30 +4,30 @@
|
|
|
4
4
|
name: Publish NPM on Release
|
|
5
5
|
|
|
6
6
|
on:
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
release:
|
|
8
|
+
types: [published]
|
|
9
9
|
|
|
10
10
|
jobs:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
build:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v2
|
|
15
|
+
- uses: actions/setup-node@v1
|
|
16
|
+
with:
|
|
17
|
+
node-version: 16
|
|
18
|
+
- run: npm ci
|
|
19
|
+
- run: npm test
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
publish-npm:
|
|
22
|
+
needs: build
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v2
|
|
26
|
+
- uses: actions/setup-node@v1
|
|
27
|
+
with:
|
|
28
|
+
node-version: 16
|
|
29
|
+
registry-url: https://registry.npmjs.org/
|
|
30
|
+
- run: npm ci
|
|
31
|
+
- run: npm publish
|
|
32
|
+
env:
|
|
33
|
+
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
package/README.md
CHANGED
|
@@ -123,7 +123,7 @@ If you experience issues installing Accenture SFMC DevTools, please check out th
|
|
|
123
123
|
1. Install Accenture SFMC DevTools by running `npm install -g mcdev` (prefix with `sudo` on MacOS)
|
|
124
124
|
- If you get an error, please see the below troubleshooting section.
|
|
125
125
|
|
|
126
|
-
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.
|
|
126
|
+
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.1`).
|
|
127
127
|
|
|
128
128
|
> **_Side note for proud nerds_:**
|
|
129
129
|
>
|
|
@@ -277,10 +277,10 @@ _Note: Regardless of which tag or branch you install_
|
|
|
277
277
|
**Install specific version (using a version tag on npm):**
|
|
278
278
|
|
|
279
279
|
```bash
|
|
280
|
-
npm install -g mcdev@4.1.
|
|
280
|
+
npm install -g mcdev@4.1.1
|
|
281
281
|
```
|
|
282
282
|
|
|
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.
|
|
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.1)!
|
|
284
284
|
|
|
285
285
|
> **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`.
|
|
286
286
|
|
|
@@ -1494,7 +1494,7 @@ Assuming you cloned Accenture SFMC DevTools into `C:\repos\sfmc-devtools\` (or `
|
|
|
1494
1494
|
|
|
1495
1495
|
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.
|
|
1496
1496
|
|
|
1497
|
-
To test your new **global** developer setup, run `mcdev --version` in CLI which should return the current version (e.g. `4.1.
|
|
1497
|
+
To test your new **global** developer setup, run `mcdev --version` in CLI which should return the current version (e.g. `4.1.1`). Then, go into your mcdev repo and update the version with the suffix `-dev`, e.g. to `4.1.1-dev` and then run `mcdev --version` again to verify that your change propagates instantly.
|
|
1498
1498
|
|
|
1499
1499
|
> **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"`
|
|
1500
1500
|
> To run the local version you need to prepend "npx" before your commands, e.g. `npx mcdev --version`
|
|
@@ -1532,7 +1532,7 @@ The following explains how you _could_ install it locally for certain edge cases
|
|
|
1532
1532
|
4. Afterwards, install Accenture SFMC DevTools by running `npm install --save-dev mcdev`
|
|
1533
1533
|
- If you get an error, please see the below troubleshooting section.
|
|
1534
1534
|
|
|
1535
|
-
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.
|
|
1535
|
+
When completed run `mcdev --version` and it will show you which version you installed (e.g. `4.1.1`).
|
|
1536
1536
|
|
|
1537
1537
|
### 9.3. NPM Scripts
|
|
1538
1538
|
|
|
@@ -346,10 +346,10 @@ Source and target business units are also compared before the deployment to appl
|
|
|
346
346
|
* [new Deployer(properties, buObject)](#new_Deployer_new)
|
|
347
347
|
* _instance_
|
|
348
348
|
* [.metadata](#Deployer+metadata) : <code>TYPE.MultiMetadataTypeMap</code>
|
|
349
|
-
* [._deploy([typeArr], [keyArr], [fromRetrieve])](#Deployer+_deploy) ⇒ <code>Promise
|
|
349
|
+
* [._deploy([typeArr], [keyArr], [fromRetrieve])](#Deployer+_deploy) ⇒ <code>Promise.<TYPE.MultiMetadataTypeMap></code>
|
|
350
350
|
* _static_
|
|
351
|
-
* [.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve])](#Deployer.deploy) ⇒ <code>Promise.<
|
|
352
|
-
* [._deployBU(cred, bu, properties, [typeArr], [keyArr], [fromRetrieve])](#Deployer._deployBU) ⇒ <code>Promise
|
|
351
|
+
* [.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve])](#Deployer.deploy) ⇒ <code>Promise.<Object.<string, TYPE.MultiMetadataTypeMap>></code>
|
|
352
|
+
* [._deployBU(cred, bu, properties, [typeArr], [keyArr], [fromRetrieve])](#Deployer._deployBU) ⇒ <code>Promise.<TYPE.MultiMetadataTypeMap></code>
|
|
353
353
|
* [.readBUMetadata(deployDir, [typeArr], [listBadKeys])](#Deployer.readBUMetadata) ⇒ <code>TYPE.MultiMetadataTypeMap</code>
|
|
354
354
|
* [.createFolderDefinitions(deployDir, metadata, metadataTypeArr)](#Deployer.createFolderDefinitions) ⇒ <code>void</code>
|
|
355
355
|
|
|
@@ -370,11 +370,11 @@ Creates a Deployer, uses v2 auth if v2AuthOptions are passed.
|
|
|
370
370
|
**Kind**: instance property of [<code>Deployer</code>](#Deployer)
|
|
371
371
|
<a name="Deployer+_deploy"></a>
|
|
372
372
|
|
|
373
|
-
### deployer.\_deploy([typeArr], [keyArr], [fromRetrieve]) ⇒ <code>Promise
|
|
373
|
+
### deployer.\_deploy([typeArr], [keyArr], [fromRetrieve]) ⇒ <code>Promise.<TYPE.MultiMetadataTypeMap></code>
|
|
374
374
|
Deploy all metadata that is located in the deployDir
|
|
375
375
|
|
|
376
376
|
**Kind**: instance method of [<code>Deployer</code>](#Deployer)
|
|
377
|
-
**Returns**: <code>Promise
|
|
377
|
+
**Returns**: <code>Promise.<TYPE.MultiMetadataTypeMap></code> - Promise of all deployed metadata
|
|
378
378
|
|
|
379
379
|
| Param | Type | Description |
|
|
380
380
|
| --- | --- | --- |
|
|
@@ -384,11 +384,11 @@ Deploy all metadata that is located in the deployDir
|
|
|
384
384
|
|
|
385
385
|
<a name="Deployer.deploy"></a>
|
|
386
386
|
|
|
387
|
-
### Deployer.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve]) ⇒ <code>Promise.<
|
|
387
|
+
### Deployer.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve]) ⇒ <code>Promise.<Object.<string, TYPE.MultiMetadataTypeMap>></code>
|
|
388
388
|
Deploys all metadata located in the 'deploy' directory to the specified business unit
|
|
389
389
|
|
|
390
390
|
**Kind**: static method of [<code>Deployer</code>](#Deployer)
|
|
391
|
-
**Returns**: <code>Promise.<
|
|
391
|
+
**Returns**: <code>Promise.<Object.<string, TYPE.MultiMetadataTypeMap>></code> - deployed metadata per BU (first key: bu name, second key: metadata type)
|
|
392
392
|
|
|
393
393
|
| Param | Type | Description |
|
|
394
394
|
| --- | --- | --- |
|
|
@@ -399,11 +399,11 @@ Deploys all metadata located in the 'deploy' directory to the specified business
|
|
|
399
399
|
|
|
400
400
|
<a name="Deployer._deployBU"></a>
|
|
401
401
|
|
|
402
|
-
### Deployer.\_deployBU(cred, bu, properties, [typeArr], [keyArr], [fromRetrieve]) ⇒ <code>Promise
|
|
402
|
+
### Deployer.\_deployBU(cred, bu, properties, [typeArr], [keyArr], [fromRetrieve]) ⇒ <code>Promise.<TYPE.MultiMetadataTypeMap></code>
|
|
403
403
|
helper for deploy()
|
|
404
404
|
|
|
405
405
|
**Kind**: static method of [<code>Deployer</code>](#Deployer)
|
|
406
|
-
**Returns**: <code>Promise
|
|
406
|
+
**Returns**: <code>Promise.<TYPE.MultiMetadataTypeMap></code> - ensure that BUs are worked on sequentially
|
|
407
407
|
|
|
408
408
|
| Param | Type | Description |
|
|
409
409
|
| --- | --- | --- |
|
|
@@ -456,7 +456,7 @@ main class
|
|
|
456
456
|
* [.explainTypes()](#Mcdev.explainTypes) ⇒ <code>void</code>
|
|
457
457
|
* [.upgrade([skipInteraction])](#Mcdev.upgrade) ⇒ <code>Promise.<boolean></code>
|
|
458
458
|
* [.retrieve(businessUnit, [selectedTypesArr], [keys], [changelogOnly])](#Mcdev.retrieve) ⇒ <code>Promise.<object></code>
|
|
459
|
-
* [.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve])](#Mcdev.deploy) ⇒ <code>Promise.<
|
|
459
|
+
* [.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve])](#Mcdev.deploy) ⇒ <code>Promise.<Object.<string, TYPE.MultiMetadataTypeMap>></code>
|
|
460
460
|
* [.initProject([credentialsName], [skipInteraction])](#Mcdev.initProject) ⇒ <code>Promise.<void></code>
|
|
461
461
|
* [.findBUs(credentialsName)](#Mcdev.findBUs) ⇒ <code>Promise.<void></code>
|
|
462
462
|
* [.document(businessUnit, type)](#Mcdev.document) ⇒ <code>Promise.<void></code>
|
|
@@ -545,11 +545,11 @@ Retrieve all metadata from the specified business unit into the local file syste
|
|
|
545
545
|
|
|
546
546
|
<a name="Mcdev.deploy"></a>
|
|
547
547
|
|
|
548
|
-
### Mcdev.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve]) ⇒ <code>Promise.<
|
|
548
|
+
### Mcdev.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve]) ⇒ <code>Promise.<Object.<string, TYPE.MultiMetadataTypeMap>></code>
|
|
549
549
|
Deploys all metadata located in the 'deploy' directory to the specified business unit
|
|
550
550
|
|
|
551
551
|
**Kind**: static method of [<code>Mcdev</code>](#Mcdev)
|
|
552
|
-
**Returns**: <code>Promise.<
|
|
552
|
+
**Returns**: <code>Promise.<Object.<string, TYPE.MultiMetadataTypeMap>></code> - deployed metadata per BU (first key: bu name, second key: metadata type)
|
|
553
553
|
|
|
554
554
|
| Param | Type | Default | Description |
|
|
555
555
|
| --- | --- | --- | --- |
|
|
@@ -2943,7 +2943,7 @@ Provides default functionality that can be overwritten by child metadata type cl
|
|
|
2943
2943
|
* [.buObject](#MetadataType.buObject) : <code>TYPE.BuObject</code>
|
|
2944
2944
|
* [.getJsonFromFS(dir, [listBadKeys])](#MetadataType.getJsonFromFS) ⇒ <code>TYPE.MetadataTypeMap</code>
|
|
2945
2945
|
* [.getFieldNamesToRetrieve([additionalFields])](#MetadataType.getFieldNamesToRetrieve) ⇒ <code>Array.<string></code>
|
|
2946
|
-
* [.deploy(metadata, deployDir, retrieveDir, buObject)](#MetadataType.deploy) ⇒ <code>Promise.<
|
|
2946
|
+
* [.deploy(metadata, deployDir, retrieveDir, buObject)](#MetadataType.deploy) ⇒ <code>Promise.<TYPE.MetadataTypeMap></code>
|
|
2947
2947
|
* [.postDeployTasks(metadata, originalMetadata)](#MetadataType.postDeployTasks) ⇒ <code>void</code>
|
|
2948
2948
|
* [.postRetrieveTasks(metadata, targetDir, [isTemplating])](#MetadataType.postRetrieveTasks) ⇒ <code>TYPE.MetadataTypeItem</code>
|
|
2949
2949
|
* [.retrieve(retrieveDir, [additionalFields], buObject, [subType], [key])](#MetadataType.retrieve) ⇒ <code>Promise.<TYPE.MetadataTypeMapObj></code>
|
|
@@ -3030,11 +3030,11 @@ Returns fieldnames of Metadata Type. 'this.definition.fields' variable only set
|
|
|
3030
3030
|
|
|
3031
3031
|
<a name="MetadataType.deploy"></a>
|
|
3032
3032
|
|
|
3033
|
-
### MetadataType.deploy(metadata, deployDir, retrieveDir, buObject) ⇒ <code>Promise.<
|
|
3033
|
+
### MetadataType.deploy(metadata, deployDir, retrieveDir, buObject) ⇒ <code>Promise.<TYPE.MetadataTypeMap></code>
|
|
3034
3034
|
Deploys metadata
|
|
3035
3035
|
|
|
3036
3036
|
**Kind**: static method of [<code>MetadataType</code>](#MetadataType)
|
|
3037
|
-
**Returns**: <code>Promise.<
|
|
3037
|
+
**Returns**: <code>Promise.<TYPE.MetadataTypeMap></code> - Promise of keyField => metadata map
|
|
3038
3038
|
|
|
3039
3039
|
| Param | Type | Description |
|
|
3040
3040
|
| --- | --- | --- |
|
package/lib/Deployer.js
CHANGED
|
@@ -48,10 +48,11 @@ class Deployer {
|
|
|
48
48
|
* @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit deployment to given metadata type
|
|
49
49
|
* @param {string[]} [keyArr] limit deployment to given metadata keys
|
|
50
50
|
* @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder
|
|
51
|
-
* @returns {Promise.<
|
|
51
|
+
* @returns {Promise.<Object.<string,TYPE.MultiMetadataTypeMap>>} deployed metadata per BU (first key: bu name, second key: metadata type)
|
|
52
52
|
*/
|
|
53
53
|
static async deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve) {
|
|
54
54
|
Util.logger.info('mcdev:: Deploy');
|
|
55
|
+
const buMultiMetadataTypeMap = {};
|
|
55
56
|
const properties = await config.getProperties();
|
|
56
57
|
if (!(await config.checkProperties(properties))) {
|
|
57
58
|
return null;
|
|
@@ -87,9 +88,18 @@ class Deployer {
|
|
|
87
88
|
2,
|
|
88
89
|
false
|
|
89
90
|
);
|
|
91
|
+
|
|
90
92
|
for (const buPath of deployFolders.filter((r) => r.includes(path.sep))) {
|
|
91
93
|
const [cred, bu] = buPath.split(path.sep);
|
|
92
|
-
await this._deployBU(
|
|
94
|
+
const multiMetadataTypeMap = await this._deployBU(
|
|
95
|
+
cred,
|
|
96
|
+
bu,
|
|
97
|
+
properties,
|
|
98
|
+
selectedTypesArr,
|
|
99
|
+
keyArr,
|
|
100
|
+
fromRetrieve
|
|
101
|
+
);
|
|
102
|
+
buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap;
|
|
93
103
|
counter_credBu++;
|
|
94
104
|
Util.logger.info('');
|
|
95
105
|
Util.restartLogger();
|
|
@@ -129,7 +139,7 @@ class Deployer {
|
|
|
129
139
|
false
|
|
130
140
|
);
|
|
131
141
|
for (const buPath of deployFolders) {
|
|
132
|
-
await this._deployBU(
|
|
142
|
+
const multiMetadataTypeMap = await this._deployBU(
|
|
133
143
|
cred,
|
|
134
144
|
buPath,
|
|
135
145
|
properties,
|
|
@@ -137,6 +147,7 @@ class Deployer {
|
|
|
137
147
|
keyArr,
|
|
138
148
|
fromRetrieve
|
|
139
149
|
);
|
|
150
|
+
buMultiMetadataTypeMap[cred + '/' + buPath] = multiMetadataTypeMap;
|
|
140
151
|
counter_credBu++;
|
|
141
152
|
Util.logger.info('');
|
|
142
153
|
Util.restartLogger();
|
|
@@ -144,13 +155,22 @@ class Deployer {
|
|
|
144
155
|
Util.logger.info(`\n :: ${counter_credBu} BUs for ${cred}\n`);
|
|
145
156
|
} else {
|
|
146
157
|
// either bad credential or specific BU or no BU given
|
|
147
|
-
await this._deployBU(
|
|
158
|
+
const multiMetadataTypeMap = await this._deployBU(
|
|
159
|
+
cred,
|
|
160
|
+
bu,
|
|
161
|
+
properties,
|
|
162
|
+
selectedTypesArr,
|
|
163
|
+
keyArr,
|
|
164
|
+
fromRetrieve
|
|
165
|
+
);
|
|
148
166
|
counter_credBu++;
|
|
167
|
+
buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap;
|
|
149
168
|
}
|
|
150
169
|
}
|
|
151
170
|
if (counter_credBu !== 0) {
|
|
152
171
|
Util.logger.info(`\n :: Deployed ${counter_credBu} BUs\n`);
|
|
153
172
|
}
|
|
173
|
+
return buMultiMetadataTypeMap;
|
|
154
174
|
}
|
|
155
175
|
/**
|
|
156
176
|
* helper for deploy()
|
|
@@ -161,22 +181,25 @@ class Deployer {
|
|
|
161
181
|
* @param {TYPE.SupportedMetadataTypes[]} [typeArr] limit deployment to given metadata type
|
|
162
182
|
* @param {string[]} [keyArr] limit deployment to given metadata keys
|
|
163
183
|
* @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder
|
|
164
|
-
* @returns {Promise} ensure that BUs are worked on sequentially
|
|
184
|
+
* @returns {Promise.<TYPE.MultiMetadataTypeMap>} ensure that BUs are worked on sequentially
|
|
165
185
|
*/
|
|
166
186
|
static async _deployBU(cred, bu, properties, typeArr, keyArr, fromRetrieve) {
|
|
167
187
|
const buPath = `${cred}/${bu}`;
|
|
168
188
|
Util.logger.info(`::Deploying ${buPath}`);
|
|
169
189
|
const buObject = await Cli.getCredentialObject(properties, buPath, null, true);
|
|
190
|
+
let multiMetadataTypeMap;
|
|
191
|
+
|
|
170
192
|
if (buObject !== null) {
|
|
171
193
|
cache.initCache(buObject);
|
|
172
194
|
const deployer = new Deployer(properties, buObject);
|
|
173
195
|
try {
|
|
174
196
|
// await is required or the calls end up conflicting
|
|
175
|
-
await deployer._deploy(typeArr, keyArr, fromRetrieve);
|
|
197
|
+
multiMetadataTypeMap = await deployer._deploy(typeArr, keyArr, fromRetrieve);
|
|
176
198
|
} catch (ex) {
|
|
177
199
|
Util.logger.errorStack(ex, 'mcdev.deploy failed');
|
|
178
200
|
}
|
|
179
201
|
}
|
|
202
|
+
return multiMetadataTypeMap;
|
|
180
203
|
}
|
|
181
204
|
|
|
182
205
|
/**
|
|
@@ -185,7 +208,7 @@ class Deployer {
|
|
|
185
208
|
* @param {TYPE.SupportedMetadataTypes[]} [typeArr] limit deployment to given metadata type (can include subtype)
|
|
186
209
|
* @param {string[]} [keyArr] limit deployment to given metadata keys
|
|
187
210
|
* @param {boolean} [fromRetrieve] if true, no folders will be updated/created
|
|
188
|
-
* @returns {Promise} Promise
|
|
211
|
+
* @returns {Promise.<TYPE.MultiMetadataTypeMap>} Promise of all deployed metadata
|
|
189
212
|
*/
|
|
190
213
|
async _deploy(typeArr, keyArr, fromRetrieve) {
|
|
191
214
|
if (await File.pathExists(this.deployDir)) {
|
|
@@ -232,6 +255,8 @@ class Deployer {
|
|
|
232
255
|
const result = await MetadataTypeInfo[type].retrieveForCache(this.buObject, subType);
|
|
233
256
|
cache.setMetadata(type, result.metadata);
|
|
234
257
|
}
|
|
258
|
+
/** @type {TYPE.MultiMetadataTypeMap} */
|
|
259
|
+
const multiMetadataTypeMap = {};
|
|
235
260
|
// deploy metadata files, extending cache once deploys
|
|
236
261
|
for (const metadataType of deployOrder) {
|
|
237
262
|
// TODO rewrite to allow deploying only a specific sub-type
|
|
@@ -246,9 +271,11 @@ class Deployer {
|
|
|
246
271
|
this.retrieveDir,
|
|
247
272
|
this.buObject
|
|
248
273
|
);
|
|
274
|
+
multiMetadataTypeMap[type] = result;
|
|
249
275
|
cache.mergeMetadata(type, result);
|
|
250
276
|
}
|
|
251
277
|
}
|
|
278
|
+
return multiMetadataTypeMap;
|
|
252
279
|
}
|
|
253
280
|
|
|
254
281
|
/**
|
package/lib/index.js
CHANGED
|
@@ -285,7 +285,7 @@ class Mcdev {
|
|
|
285
285
|
* @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit deployment to given metadata type
|
|
286
286
|
* @param {string[]} [keyArr] limit deployment to given metadata keys
|
|
287
287
|
* @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder
|
|
288
|
-
* @returns {Promise.<
|
|
288
|
+
* @returns {Promise.<Object.<string,TYPE.MultiMetadataTypeMap>>} deployed metadata per BU (first key: bu name, second key: metadata type)
|
|
289
289
|
*/
|
|
290
290
|
static async deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve = false) {
|
|
291
291
|
return Deployer.deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve);
|
|
@@ -527,7 +527,7 @@ class Asset extends MetadataType {
|
|
|
527
527
|
if (
|
|
528
528
|
buObject.mid &&
|
|
529
529
|
metadata.memberId !== buObject.mid &&
|
|
530
|
-
!metadata[this.definition.keyField].
|
|
530
|
+
!metadata[this.definition.keyField].endsWith(buObject.mid)
|
|
531
531
|
) {
|
|
532
532
|
// #3 make sure customer key is unique by suffixing it with target MID (unless we are deploying to the same MID)
|
|
533
533
|
// check if this suffixed with the source MID
|
|
@@ -134,23 +134,37 @@ class ImportFile extends MetadataType {
|
|
|
134
134
|
delete metadata.r__ftpLocation_name;
|
|
135
135
|
|
|
136
136
|
if (metadata.c__destinationType === 'DataExtension') {
|
|
137
|
-
metadata.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
137
|
+
if (metadata.r__dataExtension_CustomerKey) {
|
|
138
|
+
metadata.destinationObjectId = cache.searchForField(
|
|
139
|
+
'dataExtension',
|
|
140
|
+
metadata.r__dataExtension_CustomerKey,
|
|
141
|
+
'CustomerKey',
|
|
142
|
+
'ObjectID'
|
|
143
|
+
);
|
|
144
|
+
delete metadata.r__dataExtension_CustomerKey;
|
|
145
|
+
} else {
|
|
146
|
+
throw new Error('Import Destination DataExtension not defined');
|
|
147
|
+
}
|
|
144
148
|
} else if (metadata.c__destinationType === 'List') {
|
|
145
|
-
metadata.
|
|
146
|
-
metadata.
|
|
147
|
-
|
|
149
|
+
if (metadata.r__list_PathName) {
|
|
150
|
+
metadata.destinationObjectId = cache.getListObjectId(
|
|
151
|
+
metadata.r__list_PathName,
|
|
152
|
+
'ObjectID'
|
|
153
|
+
);
|
|
154
|
+
// destinationId is also needed for List types
|
|
155
|
+
metadata.destinationId = cache.getListObjectId(metadata.r__list_PathName, 'ID');
|
|
156
|
+
delete metadata.r__list_PathName;
|
|
157
|
+
} else {
|
|
158
|
+
throw new Error('Import Destination List not defined');
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
Util.logger.debug(
|
|
162
|
+
` - importFile ${metadata[this.definition.keyField]}: Import Destination Type ${
|
|
163
|
+
metadata.c__destinationType
|
|
164
|
+
} not fully supported. Deploy might fail.`
|
|
148
165
|
);
|
|
149
|
-
// destinationId is also needed for List types
|
|
150
|
-
metadata.destinationId = cache.getListObjectId(metadata.r__list_PathName, 'ID');
|
|
151
|
-
delete metadata.r__list_PathName;
|
|
152
166
|
}
|
|
153
|
-
// When the destinationObjectTypeId is 584
|
|
167
|
+
// When the destinationObjectTypeId is 584 it refers to Mobile Connect which is not supported as an Import Type
|
|
154
168
|
metadata.destinationObjectTypeId =
|
|
155
169
|
this.definition.destinationObjectTypeMapping[metadata.c__destinationType];
|
|
156
170
|
metadata.subscriberImportTypeId =
|
|
@@ -104,7 +104,7 @@ class MetadataType {
|
|
|
104
104
|
* @param {string} deployDir directory where deploy metadata are saved
|
|
105
105
|
* @param {string} retrieveDir directory where metadata after deploy should be saved
|
|
106
106
|
* @param {TYPE.BuObject} buObject properties for auth
|
|
107
|
-
* @returns {Promise.<
|
|
107
|
+
* @returns {Promise.<TYPE.MetadataTypeMap>} Promise of keyField => metadata map
|
|
108
108
|
*/
|
|
109
109
|
static async deploy(metadata, deployDir, retrieveDir, buObject) {
|
|
110
110
|
const upsertResults = await this.upsert(metadata, deployDir, buObject);
|
package/lib/util/devops.js
CHANGED
|
@@ -407,7 +407,7 @@ const DevOps = {
|
|
|
407
407
|
);
|
|
408
408
|
}
|
|
409
409
|
await Promise.all(bdPromises);
|
|
410
|
-
Util.logger.info(`- ✔️ Deploy
|
|
410
|
+
Util.logger.info(`- ✔️ Deploy definitions created`);
|
|
411
411
|
if (
|
|
412
412
|
properties.directories.templateBuilds == properties.directories.deploy ||
|
|
413
413
|
(Array.isArray(properties.directories.templateBuilds) &&
|
package/lib/util/util.js
CHANGED
|
@@ -428,10 +428,20 @@ const Util = {
|
|
|
428
428
|
* @returns {object} initiated logger for console and file
|
|
429
429
|
*/
|
|
430
430
|
function createNewLoggerTransport() {
|
|
431
|
+
// {
|
|
432
|
+
// error: 0,
|
|
433
|
+
// warn: 1,
|
|
434
|
+
// info: 2,
|
|
435
|
+
// http: 3,
|
|
436
|
+
// verbose: 4,
|
|
437
|
+
// debug: 5,
|
|
438
|
+
// silly: 6
|
|
439
|
+
// }
|
|
440
|
+
const logFileName = new Date().toISOString().split(':').join('.');
|
|
431
441
|
return {
|
|
432
442
|
console: new winston.transports.Console({
|
|
433
443
|
// Write logs to Console
|
|
434
|
-
level: 'info',
|
|
444
|
+
level: 'info', // log error, warn, info
|
|
435
445
|
format: winston.format.combine(
|
|
436
446
|
winston.format.colorize(),
|
|
437
447
|
winston.format.timestamp({ format: 'HH:mm:ss' }),
|
|
@@ -441,9 +451,18 @@ function createNewLoggerTransport() {
|
|
|
441
451
|
}),
|
|
442
452
|
file: new winston.transports.File({
|
|
443
453
|
// Write logs to logfile
|
|
444
|
-
filename: 'logs/' +
|
|
445
|
-
|
|
446
|
-
|
|
454
|
+
filename: 'logs/' + logFileName + '.log',
|
|
455
|
+
level: 'debug', // log everything
|
|
456
|
+
format: winston.format.combine(
|
|
457
|
+
winston.format.timestamp({ format: 'HH:mm:ss.SSS' }),
|
|
458
|
+
winston.format.simple(),
|
|
459
|
+
winston.format.printf((info) => `${info.timestamp} ${info.level}: ${info.message}`)
|
|
460
|
+
),
|
|
461
|
+
}),
|
|
462
|
+
fileError: new winston.transports.File({
|
|
463
|
+
// Write logs to additional error-logfile for better visibility of errors
|
|
464
|
+
filename: 'logs/' + logFileName + '-errors.log',
|
|
465
|
+
level: 'error', // only log errors
|
|
447
466
|
format: winston.format.combine(
|
|
448
467
|
winston.format.timestamp({ format: 'HH:mm:ss.SSS' }),
|
|
449
468
|
winston.format.simple(),
|
|
@@ -461,7 +480,11 @@ function startLogger() {
|
|
|
461
480
|
Util.loggerTransports = createNewLoggerTransport();
|
|
462
481
|
const myWinston = winston.createLogger({
|
|
463
482
|
levels: winston.config.npm.levels,
|
|
464
|
-
transports: [
|
|
483
|
+
transports: [
|
|
484
|
+
Util.loggerTransports.console,
|
|
485
|
+
Util.loggerTransports.file,
|
|
486
|
+
Util.loggerTransports.fileError,
|
|
487
|
+
],
|
|
465
488
|
});
|
|
466
489
|
const winstonError = myWinston.error;
|
|
467
490
|
const winstonExtension = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcdev",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"description": "Accenture Salesforce Marketing Cloud DevTools",
|
|
5
5
|
"author": "joern.berkefeld, douglas.midgley, robert.zimmermann, maciej.barnas",
|
|
6
6
|
"license": "MIT",
|
|
@@ -64,10 +64,10 @@
|
|
|
64
64
|
"assert": "2.0.0",
|
|
65
65
|
"axios-mock-adapter": "1.21.2",
|
|
66
66
|
"chai": "4.3.6",
|
|
67
|
-
"eslint": "8.
|
|
67
|
+
"eslint": "8.26.0",
|
|
68
68
|
"eslint-config-prettier": "8.5.0",
|
|
69
69
|
"eslint-config-ssjs": "1.1.11",
|
|
70
|
-
"eslint-plugin-jsdoc": "39.3.
|
|
70
|
+
"eslint-plugin-jsdoc": "39.3.25",
|
|
71
71
|
"eslint-plugin-mocha": "10.1.0",
|
|
72
72
|
"eslint-plugin-prettier": "4.2.1",
|
|
73
73
|
"eslint-plugin-unicorn": "44.0.2",
|
|
@@ -80,6 +80,9 @@
|
|
|
80
80
|
"npm-run-all": "4.1.5",
|
|
81
81
|
"prettier-eslint": "15.0.1"
|
|
82
82
|
},
|
|
83
|
+
"optionalDependencies": {
|
|
84
|
+
"fsevents": "*"
|
|
85
|
+
},
|
|
83
86
|
"lint-staged": {
|
|
84
87
|
"*.{js,jsx,ts,tsx}": [
|
|
85
88
|
"eslint --fix"
|