mcdev 4.2.1 → 4.3.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.
Files changed (98) hide show
  1. package/.github/ISSUE_TEMPLATE/bug.yml +3 -0
  2. package/.github/PULL_REQUEST_TEMPLATE.md +1 -2
  3. package/.github/pr-labeler.yml +3 -0
  4. package/.github/workflows/close_issues_on_merge.yml +18 -0
  5. package/.github/workflows/pr-labeler.yml +19 -0
  6. package/LICENSE +1 -1
  7. package/README.md +1 -1
  8. package/docs/dist/documentation.md +702 -284
  9. package/lib/Deployer.js +21 -15
  10. package/lib/Retriever.js +41 -34
  11. package/lib/cli.js +36 -6
  12. package/lib/index.js +56 -10
  13. package/lib/metadataTypes/AccountUser.js +17 -23
  14. package/lib/metadataTypes/Asset.js +36 -48
  15. package/lib/metadataTypes/AttributeGroup.js +1 -2
  16. package/lib/metadataTypes/Automation.js +75 -37
  17. package/lib/metadataTypes/Campaign.js +4 -3
  18. package/lib/metadataTypes/ContentArea.js +2 -3
  19. package/lib/metadataTypes/DataExtension.js +56 -47
  20. package/lib/metadataTypes/DataExtensionField.js +9 -12
  21. package/lib/metadataTypes/DataExtensionTemplate.js +2 -3
  22. package/lib/metadataTypes/DataExtract.js +1 -2
  23. package/lib/metadataTypes/DataExtractType.js +1 -2
  24. package/lib/metadataTypes/Discovery.js +3 -4
  25. package/lib/metadataTypes/Email.js +20 -6
  26. package/lib/metadataTypes/EmailSendDefinition.js +40 -39
  27. package/lib/metadataTypes/EventDefinition.js +29 -2
  28. package/lib/metadataTypes/FileTransfer.js +1 -2
  29. package/lib/metadataTypes/Filter.js +1 -2
  30. package/lib/metadataTypes/Folder.js +12 -14
  31. package/lib/metadataTypes/FtpLocation.js +1 -2
  32. package/lib/metadataTypes/ImportFile.js +1 -2
  33. package/lib/metadataTypes/Interaction.js +743 -12
  34. package/lib/metadataTypes/List.js +36 -33
  35. package/lib/metadataTypes/MetadataType.js +170 -124
  36. package/lib/metadataTypes/MobileCode.js +1 -2
  37. package/lib/metadataTypes/MobileKeyword.js +1 -2
  38. package/lib/metadataTypes/Query.js +15 -6
  39. package/lib/metadataTypes/Role.js +10 -11
  40. package/lib/metadataTypes/Script.js +2 -5
  41. package/lib/metadataTypes/SetDefinition.js +1 -2
  42. package/lib/metadataTypes/TransactionalMessage.js +25 -32
  43. package/lib/metadataTypes/TransactionalSMS.js +3 -4
  44. package/lib/metadataTypes/TriggeredSendDefinition.js +232 -56
  45. package/lib/metadataTypes/definitions/Asset.definition.js +1 -1
  46. package/lib/metadataTypes/definitions/Automation.definition.js +1 -1
  47. package/lib/metadataTypes/definitions/DataExtension.definition.js +10 -1
  48. package/lib/metadataTypes/definitions/Email.definition.js +1 -1
  49. package/lib/metadataTypes/definitions/EmailSendDefinition.definition.js +1 -1
  50. package/lib/metadataTypes/definitions/EventDefinition.definition.js +40 -1
  51. package/lib/metadataTypes/definitions/Folder.definition.js +31 -0
  52. package/lib/metadataTypes/definitions/ImportFile.definition.js +1 -1
  53. package/lib/metadataTypes/definitions/Interaction.definition.js +47 -26
  54. package/lib/metadataTypes/definitions/List.definition.js +1 -1
  55. package/lib/metadataTypes/definitions/Query.definition.js +1 -1
  56. package/lib/metadataTypes/definitions/Script.definition.js +1 -1
  57. package/lib/metadataTypes/definitions/TransactionalEmail.definition.js +4 -3
  58. package/lib/metadataTypes/definitions/TransactionalPush.definition.js +4 -3
  59. package/lib/metadataTypes/definitions/TransactionalSMS.definition.js +4 -3
  60. package/lib/metadataTypes/definitions/TriggeredSendDefinition.definition.js +10 -2
  61. package/lib/util/auth.js +15 -2
  62. package/lib/util/cli.js +4 -1
  63. package/lib/util/file.js +7 -3
  64. package/lib/util/init.js +62 -0
  65. package/lib/util/util.js +173 -11
  66. package/package.json +23 -9
  67. package/test/dataExtension.test.js +10 -10
  68. package/test/interaction.test.js +123 -0
  69. package/test/mockRoot/.mcdevrc.json +1 -1
  70. package/test/mockRoot/deploy/testInstance/testBU/interaction/testExisting_interaction.interaction-meta.json +266 -0
  71. package/test/mockRoot/deploy/testInstance/testBU/interaction/testNew_interaction.interaction-meta.json +266 -0
  72. package/test/mockRoot/deploy/testInstance/testBU/transactionalEmail/testExisting_temail.transactionalEmail-meta.json +0 -3
  73. package/test/query.test.js +8 -8
  74. package/test/resourceFactory.js +30 -14
  75. package/test/resources/1111111/dataExtension/retrieve-response.xml +26 -0
  76. package/test/resources/9999999/data/v1/customobjectdata/key/childBU_dataextension_test/rowset/get-response.json +13 -0
  77. package/test/resources/9999999/dataFolder/retrieve-response.xml +22 -0
  78. package/test/resources/9999999/eventDefinition/get-expected.json +34 -0
  79. package/test/resources/9999999/interaction/build-expected.json +260 -0
  80. package/test/resources/9999999/interaction/get-expected.json +264 -0
  81. package/test/resources/9999999/interaction/post-expected.json +264 -0
  82. package/test/resources/9999999/interaction/put-expected.json +264 -0
  83. package/test/resources/9999999/interaction/template-expected.json +260 -0
  84. package/test/resources/9999999/interaction/v1/EventDefinitions/get-response.json +43 -0
  85. package/test/resources/9999999/interaction/v1/interactions/get-response.json +222 -3
  86. package/test/resources/9999999/interaction/v1/interactions/key_0b76dccf-594c-b6dc-1acf-10c4493dcb84/get-response.json +219 -0
  87. package/test/resources/9999999/interaction/v1/interactions/key_testExisting_interaction/get-response.json +280 -0
  88. package/test/resources/9999999/interaction/v1/interactions/post-response.json +280 -0
  89. package/test/resources/9999999/interaction/v1/interactions/put-response.json +280 -0
  90. package/test/resources/9999999/messaging/v1/email/definitions/post-response.json +1 -1
  91. package/test/resources/9999999/query/post-expected.sql +1 -1
  92. package/test/resources/9999999/transactionalEmail/post-expected.json +1 -1
  93. package/test/resources/9999999/triggeredSendDefinition/retrieve-response.xml +68 -0
  94. package/test/transactionalEmail.test.js +7 -7
  95. package/test/transactionalPush.test.js +7 -7
  96. package/test/transactionalSMS.test.js +7 -7
  97. package/test/utils.js +50 -0
  98. package/types/mcdev.d.js +1 -0
package/lib/Deployer.js CHANGED
@@ -238,38 +238,44 @@ class Deployer {
238
238
  Object.keys(this.metadata)
239
239
  );
240
240
  }
241
- const foundDeployTypes = Object.keys(this.metadata).map((item) =>
242
- item === 'asset' && Util.includesStartsWith(typeArr, item)
243
- ? typeArr[Util.includesStartsWithIndex(typeArr, item)]
244
- : item
245
- );
241
+ const foundDeployTypes = Object.keys(this.metadata)
242
+ .map((type) =>
243
+ type === 'asset' && Util.includesStartsWith(typeArr, type)
244
+ ? typeArr[Util.includesStartsWithIndex(typeArr, type)]
245
+ : type
246
+ )
247
+ // remove empty types
248
+ .filter((type) => Object.keys(this.metadata[type]).length);
249
+ if (!foundDeployTypes.length) {
250
+ throw new Error('No metadata found for deployment');
251
+ }
246
252
  const deployOrder = Util.getMetadataHierachy(foundDeployTypes);
247
253
  // build cache, including all metadata types which will be deployed (Avoids retrieve later)
248
- for (const metadataType of deployOrder) {
249
- const [type, subType] = metadataType.split('-');
254
+ for (const metadataType in deployOrder) {
255
+ const type = metadataType;
256
+ const subTypeArr = deployOrder[metadataType];
250
257
  // add metadata & client to metadata process class instead of passing cache/mapping every time
251
258
  MetadataTypeInfo[type].client = auth.getSDK(this.buObject);
252
259
  MetadataTypeInfo[type].properties = this.properties;
253
260
  MetadataTypeInfo[type].buObject = this.buObject;
254
- Util.logger.info('Caching dependent Metadata: ' + metadataType);
255
- const result = await MetadataTypeInfo[type].retrieveForCache(this.buObject, subType);
261
+ Util.logger.info(`Caching dependent Metadata: ${metadataType}`);
262
+ Util.logSubtypes(subTypeArr);
263
+ const result = await MetadataTypeInfo[type].retrieveForCache(null, subTypeArr);
256
264
  cache.setMetadata(type, result.metadata);
257
265
  }
258
266
  /** @type {TYPE.MultiMetadataTypeMap} */
259
267
  const multiMetadataTypeMap = {};
260
268
  // deploy metadata files, extending cache once deploys
261
- for (const metadataType of deployOrder) {
262
- // TODO rewrite to allow deploying only a specific sub-type
263
- // const [type, subType] = metadataType.split('-');
264
- const type = metadataType.split('-')[0];
269
+ for (const metadataType in deployOrder) {
270
+ // TODO rewrite to allow deploying only a specific sub-type; currently, subtypes are ignored when executing deploy
271
+ const type = metadataType;
265
272
  if (this.metadata[type]) {
266
273
  Util.logger.info('Deploying: ' + metadataType);
267
274
 
268
275
  const result = await MetadataTypeInfo[type].deploy(
269
276
  this.metadata[type],
270
277
  this.deployDir,
271
- this.retrieveDir,
272
- this.buObject
278
+ this.retrieveDir
273
279
  );
274
280
  multiMetadataTypeMap[type] = result;
275
281
  cache.mergeMetadata(type, result);
package/lib/Retriever.js CHANGED
@@ -59,75 +59,82 @@ class Retriever {
59
59
  // assuming TypeKeyCombo was provided
60
60
  typeKeyMap = namesOrKeys;
61
61
  }
62
- // defined colors for optionally printing the keys we filtered by
63
- const color = {
64
- reset: '\x1B[0m',
65
- dim: '\x1B[2m',
66
- };
67
62
  // ensure we know which real dependencies we have to ensure we cache those completely
68
63
  const dependencies = this._getTypeDependencies(metadataTypes);
69
-
70
- for (const metadataType of Util.getMetadataHierachy(metadataTypes)) {
71
- const [type, subType] = metadataType.split('-');
64
+ const deployOrder = Util.getMetadataHierachy(metadataTypes);
65
+ for (const type in deployOrder) {
66
+ const subTypeArr = deployOrder[type];
72
67
  // if types were added by getMetadataHierachy() for caching, make sure the key-list is set to [null] for them which will retrieve all
73
- typeKeyMap[metadataType] = typeKeyMap[metadataType] || [null];
68
+ typeKeyMap[type] = typeKeyMap[type] || [null];
74
69
  // add client to metadata process class instead of passing every time
75
70
  MetadataTypeInfo[type].client = auth.getSDK(this.buObject);
76
71
  MetadataTypeInfo[type].properties = this.properties;
77
72
  MetadataTypeInfo[type].buObject = this.buObject;
78
73
  try {
79
74
  let result;
80
- if (!metadataTypes.includes(type) && !metadataTypes.includes(metadataType)) {
75
+ if (
76
+ !metadataTypes.includes(type) &&
77
+ (!Array.isArray(subTypeArr) ||
78
+ (Array.isArray(subTypeArr) &&
79
+ !metadataTypes.includes(`${type}-${subTypeArr?.[0]}`)))
80
+ ) {
81
+ // type not in list of types to retrieve, but is a dependency of one of them
81
82
  if (changelogOnly && type !== 'folder') {
82
83
  // no extra caching needed for list view except for folders
83
84
  continue;
84
85
  }
85
- Util.logger.info(`Caching dependent Metadata: ${metadataType}`);
86
- result = await MetadataTypeInfo[type].retrieveForCache(this.buObject, subType);
86
+ Util.logger.info(`Caching dependent Metadata: ${type}`);
87
+ Util.logSubtypes(subTypeArr);
88
+ result = await MetadataTypeInfo[type].retrieveForCache(null, subTypeArr);
87
89
  } else if (templateVariables) {
88
- Util.logger.info(`Retrieving as Template: ${metadataType}`);
89
-
90
+ // type is in list of types to retrieve and we have template variables
91
+ Util.logger.info(`Retrieving as Template: ${type}`);
92
+ if (subTypeArr?.length > 1) {
93
+ Util.logger.warn(
94
+ `retrieveAsTemplate only works with one subtype, ignoring all but first subtype from your list: ${subTypeArr.join(
95
+ ', '
96
+ )}`
97
+ );
98
+ }
90
99
  result = await Promise.all(
91
- typeKeyMap[metadataType].map((name) =>
100
+ typeKeyMap[type].map((name) =>
92
101
  MetadataTypeInfo[type].retrieveAsTemplate(
93
102
  this.templateDir,
94
103
  name,
95
104
  templateVariables,
96
- subType
105
+ subTypeArr?.[0]
97
106
  )
98
107
  )
99
108
  );
100
109
  } else {
110
+ // type is in list of types to retrieve and we don't have template variables
101
111
  let cacheResult = null;
102
112
  if (
103
- (typeKeyMap[metadataType].length > 1 ||
104
- typeKeyMap[metadataType][0] !== null) &&
105
- (dependencies.includes(type) || dependencies.includes(metadataType))
113
+ (typeKeyMap[type].length > 1 || typeKeyMap[type][0] !== null) &&
114
+ (dependencies.includes(type) || dependencies.includes(type))
106
115
  ) {
107
116
  // if we have a key-list and the type is a dependency, we need to cache the whole type
108
- Util.logger.info(`Caching dependent Metadata: ${metadataType}`);
117
+ Util.logger.info(`Caching dependent Metadata: ${type}`);
118
+ Util.logSubtypes(subTypeArr);
109
119
  cacheResult = await MetadataTypeInfo[type].retrieveForCache(
110
- this.buObject,
111
- subType
120
+ null,
121
+ subTypeArr
112
122
  );
113
123
  }
114
124
  Util.logger.info(
115
- `Retrieving: ${metadataType}` +
116
- (typeKeyMap[metadataType][0] === null
125
+ `Retrieving: ${type}` +
126
+ (typeKeyMap[type][0] === null
117
127
  ? ''
118
- : ` ${color.dim}(Keys: ${typeKeyMap[metadataType].join(', ')})${
119
- color.reset
120
- }`)
128
+ : Util.getKeysString(typeKeyMap[type]))
121
129
  );
122
130
  result = await (changelogOnly
123
- ? MetadataTypeInfo[type].retrieveChangelog(this.buObject, null, subType)
131
+ ? MetadataTypeInfo[type].retrieveChangelog(null, subTypeArr)
124
132
  : Promise.all(
125
- typeKeyMap[metadataType].map((key) =>
133
+ typeKeyMap[type].map((key) =>
126
134
  MetadataTypeInfo[type].retrieve(
127
135
  this.savePath,
128
136
  null,
129
- this.buObject,
130
- subType,
137
+ subTypeArr,
131
138
  key
132
139
  )
133
140
  )
@@ -150,14 +157,14 @@ class Retriever {
150
157
  cache.mergeMetadata(type, result_i.metadata);
151
158
  }
152
159
  }
153
- if (metadataTypes.includes(type) || metadataTypes.includes(metadataType)) {
160
+ if (metadataTypes.includes(type) || metadataTypes.includes(type)) {
154
161
  retrieveChangelog[type] = result
155
162
  .filter((el) => !!el)
156
163
  .map((element) => element.metadata);
157
164
  }
158
165
  } else {
159
166
  cache.setMetadata(type, result.metadata);
160
- if (metadataTypes.includes(type) || metadataTypes.includes(metadataType)) {
167
+ if (metadataTypes.includes(type) || metadataTypes.includes(type)) {
161
168
  retrieveChangelog[type] = result.metadata;
162
169
  }
163
170
  }
@@ -171,7 +178,7 @@ class Retriever {
171
178
  Util.logger.error(ex.message);
172
179
  break;
173
180
  } else {
174
- Util.logger.errorStack(ex, ` - Retrieving ${metadataType} failed`);
181
+ Util.logger.errorStack(ex, ` - Retrieving ${type} failed`);
175
182
  }
176
183
  }
177
184
  }
package/lib/cli.js CHANGED
@@ -84,6 +84,15 @@ yargs
84
84
  Mcdev.initProject(argv.credentialsName);
85
85
  },
86
86
  })
87
+ .command({
88
+ command: 'join',
89
+ desc: `clones an existing project from git`,
90
+ handler: (argv) => {
91
+ Mcdev.setSkipInteraction(argv.skipInteraction);
92
+ Mcdev.setLoggingLevel(argv);
93
+ Mcdev.joinProject();
94
+ },
95
+ })
87
96
  .command({
88
97
  command: 'reloadBUs [credentialsName]',
89
98
  aliases: ['rb'],
@@ -221,9 +230,7 @@ yargs
221
230
  handler: (argv) => {
222
231
  Mcdev.setSkipInteraction(argv.skipInteraction);
223
232
  Mcdev.setLoggingLevel(argv);
224
- const keyArr = csvToArray(argv.KEY);
225
-
226
- Mcdev.buildTemplate(argv.BU, argv.TYPE, keyArr, argv.MARKET);
233
+ Mcdev.buildTemplate(argv.BU, argv.TYPE, csvToArray(argv.KEY), argv.MARKET);
227
234
  },
228
235
  })
229
236
  .command({
@@ -345,9 +352,32 @@ yargs
345
352
  handler: (argv) => {
346
353
  Mcdev.setSkipInteraction(argv.skipInteraction);
347
354
  Mcdev.setLoggingLevel(argv);
348
- const keyArr = csvToArray(argv.KEY);
349
-
350
- Mcdev.getFilesToCommit(argv.BU, argv.TYPE, keyArr);
355
+ Mcdev.getFilesToCommit(argv.BU, argv.TYPE, csvToArray(argv.KEY));
356
+ },
357
+ })
358
+ .command({
359
+ command: 'refresh <BU> [TYPE] [KEY]',
360
+ aliases: ['re'],
361
+ desc: 'ensures that updates are properly published',
362
+ builder: (yargs) => {
363
+ yargs
364
+ .positional('BU', {
365
+ type: 'string',
366
+ describe: 'the business unit to execute the refresh on',
367
+ })
368
+ .positional('TYPE', {
369
+ type: 'string',
370
+ describe: 'metadata type',
371
+ })
372
+ .positional('KEY', {
373
+ type: 'string',
374
+ describe: 'key(s) of the metadata component(s)',
375
+ });
376
+ },
377
+ handler: (argv) => {
378
+ Mcdev.setSkipInteraction(argv.skipInteraction);
379
+ Mcdev.setLoggingLevel(argv);
380
+ Mcdev.refresh(argv.BU, argv.TYPE, csvToArray(argv.KEY));
351
381
  },
352
382
  })
353
383
  .command({
package/lib/index.js CHANGED
@@ -147,7 +147,7 @@ class Mcdev {
147
147
  if (
148
148
  properties.credentials &&
149
149
  (!properties.credentials[cred] ||
150
- (bu !== '*' && properties.credentials[cred].businessUnits[bu]))
150
+ (bu !== '*' && !properties.credentials[cred].businessUnits[bu]))
151
151
  ) {
152
152
  const buObject = await Cli.getCredentialObject(
153
153
  properties,
@@ -220,7 +220,7 @@ class Mcdev {
220
220
  for (const selectedType of Array.isArray(selectedTypesArr)
221
221
  ? selectedTypesArr
222
222
  : Object.keys(selectedTypesArr)) {
223
- const [type, subType] = selectedType ? selectedType.split('-') : [];
223
+ const [type, subType] = Util.getTypeAndSubType(selectedType);
224
224
  const removePathArr = [properties.directories.retrieve, cred, bu, type];
225
225
  if (
226
226
  type &&
@@ -293,6 +293,15 @@ class Mcdev {
293
293
  const properties = await config.getProperties(!!credentialsName, true);
294
294
  await Init.initProject(properties, credentialsName);
295
295
  }
296
+ /**
297
+ * Clones an existing project from git repository and installs it
298
+ *
299
+ * @returns {Promise.<void>} -
300
+ */
301
+ static async joinProject() {
302
+ Util.logger.info('mcdev:: Joining an existing project');
303
+ await Init.joinProject();
304
+ }
296
305
 
297
306
  /**
298
307
  * Refreshes BU names and ID's from MC instance
@@ -338,7 +347,8 @@ class Mcdev {
338
347
  );
339
348
  if (buObject !== null) {
340
349
  MetadataTypeInfo[type].properties = properties;
341
- MetadataTypeInfo[type].document(buObject);
350
+ MetadataTypeInfo[type].buObject = buObject;
351
+ MetadataTypeInfo[type].document();
342
352
  }
343
353
  } catch (ex) {
344
354
  Util.logger.error('mcdev.document ' + ex.message);
@@ -350,25 +360,59 @@ class Mcdev {
350
360
  }
351
361
 
352
362
  /**
353
- * Creates docs for supported metadata types in Markdown and/or HTML format
363
+ * deletes metadata from MC instance by key
354
364
  *
355
365
  * @param {string} businessUnit references credentials from properties.json
356
366
  * @param {string} type supported metadata type
357
- * @param {string} customerKey Identifier of data extension
367
+ * @param {string} customerKey Identifier of metadata
358
368
  * @returns {Promise.<void>} -
359
369
  */
360
370
  static async deleteByKey(businessUnit, type, customerKey) {
361
371
  Util.logger.info('mcdev:: delete');
372
+ if (!Util._isValidType(type)) {
373
+ return;
374
+ }
362
375
  const properties = await config.getProperties();
363
376
  if (!(await config.checkProperties(properties))) {
364
377
  return null;
365
378
  }
366
379
  const buObject = await Cli.getCredentialObject(properties, businessUnit);
367
380
  if (buObject !== null) {
368
- if ('string' !== typeof type) {
369
- Util.logger.error('mcdev.delete failed: Bad metadata type passed in');
381
+ try {
382
+ MetadataTypeInfo[type].client = auth.getSDK(buObject);
383
+ } catch (ex) {
384
+ Util.logger.error(ex.message);
370
385
  return;
371
386
  }
387
+ try {
388
+ MetadataTypeInfo[type].properties = properties;
389
+ MetadataTypeInfo[type].buObject = buObject;
390
+ await MetadataTypeInfo[type].deleteByKey(customerKey);
391
+ } catch (ex) {
392
+ Util.logger.errorStack(ex, ` - Deleting ${type} failed`);
393
+ }
394
+ }
395
+ }
396
+ /**
397
+ * ensures triggered sends are restarted to ensure they pick up on changes of the underlying emails
398
+ *
399
+ * @param {string} businessUnit references credentials from properties.json
400
+ * @param {string} type references credentials from properties.json
401
+ * @param {string[]} [keyArr] metadata keys
402
+ * @returns {Promise.<void>} -
403
+ */
404
+ static async refresh(businessUnit, type, keyArr) {
405
+ Util.logger.info('mcdev:: refresh');
406
+ if (!type || !Util._isValidType(type, true)) {
407
+ type = 'triggeredSendDefinition';
408
+ Util.logger.info(' - setting type to ' + type);
409
+ }
410
+ const properties = await config.getProperties();
411
+ if (!(await config.checkProperties(properties))) {
412
+ return null;
413
+ }
414
+ const buObject = await Cli.getCredentialObject(properties, businessUnit);
415
+ if (buObject !== null) {
372
416
  try {
373
417
  MetadataTypeInfo[type].client = auth.getSDK(buObject);
374
418
  } catch (ex) {
@@ -376,10 +420,12 @@ class Mcdev {
376
420
  return;
377
421
  }
378
422
  try {
423
+ cache.initCache(buObject);
379
424
  MetadataTypeInfo[type].properties = properties;
380
- MetadataTypeInfo[type].deleteByKey(buObject, customerKey);
425
+ MetadataTypeInfo[type].buObject = buObject;
426
+ await MetadataTypeInfo[type].refresh(keyArr);
381
427
  } catch (ex) {
382
- Util.logger.error('mcdev.delete ' + ex.message);
428
+ Util.logger.errorStack(ex, 'mcdev.refresh ' + ex.message);
383
429
  }
384
430
  }
385
431
  }
@@ -472,7 +518,7 @@ class Mcdev {
472
518
  if (!Util._isValidType(selectedType)) {
473
519
  return;
474
520
  }
475
- const [type, subType] = selectedType ? selectedType.split('-') : [];
521
+ const [type, subType] = Util.getTypeAndSubType(selectedType);
476
522
 
477
523
  let retrieveTypesArr;
478
524
  if (
@@ -16,37 +16,34 @@ class AccountUser extends MetadataType {
16
16
  *
17
17
  * @param {string} retrieveDir Directory where retrieved metadata directory will be saved
18
18
  * @param {void} _ unused parameter
19
- * @param {TYPE.BuObject} buObject properties for auth
20
- * @param {void} [___] unused parameter
19
+ * @param {void} [__] unused parameter
21
20
  * @param {string} [key] customer key of single item to retrieve
22
21
  * @returns {Promise.<TYPE.MetadataTypeMapObj>} Promise of metadata
23
22
  */
24
- static async retrieve(retrieveDir, _, buObject, ___, key) {
25
- if (buObject.eid !== buObject.mid) {
23
+ static async retrieve(retrieveDir, _, __, key) {
24
+ if (this.buObject.eid !== this.buObject.mid) {
26
25
  Util.logger.info(' - Skipping User retrieval on non-parent BU');
27
26
  return;
28
27
  }
29
- return this._retrieve(retrieveDir, buObject, key);
28
+ return this._retrieve(retrieveDir, key);
30
29
  }
31
30
  /**
32
31
  * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata
33
32
  *
34
- * @param {TYPE.BuObject} buObject properties for auth
35
33
  * @returns {Promise.<TYPE.MetadataTypeMapObj>} Promise of metadata
36
34
  */
37
- static async retrieveChangelog(buObject) {
38
- return this._retrieve(null, buObject, null);
35
+ static async retrieveChangelog() {
36
+ return this._retrieve();
39
37
  }
40
38
  /**
41
39
  * Retrieves SOAP based metadata of metadata type into local filesystem. executes callback with retrieved metadata
42
40
  *
43
41
  * @private
44
42
  * @param {string} retrieveDir Directory where retrieved metadata directory will be saved
45
- * @param {TYPE.BuObject} buObject properties for auth
46
43
  * @param {string} [key] customer key of single item to retrieve
47
44
  * @returns {Promise.<TYPE.MetadataTypeMapObj>} Promise of metadata
48
45
  */
49
- static async _retrieve(retrieveDir, buObject, key) {
46
+ static async _retrieve(retrieveDir, key) {
50
47
  Util.logger.info(' - Caching dependent Metadata: AccountUserAccount');
51
48
 
52
49
  // get BUs that each users have access to
@@ -113,7 +110,7 @@ class AccountUser extends MetadataType {
113
110
  };
114
111
  }
115
112
  Util.logger.info(` - Loading ${this.definition.type}. This might take a while...`);
116
- return super.retrieveSOAP(retrieveDir, buObject, requestParams);
113
+ return super.retrieveSOAP(retrieveDir, requestParams);
117
114
  }
118
115
  /**
119
116
  *
@@ -175,24 +172,21 @@ class AccountUser extends MetadataType {
175
172
  /**
176
173
  * helper to print bu names
177
174
  *
178
- * @param {TYPE.BuObject} buObject needed for eid
179
- * @param {string} buObject.eid needed to check for parent bu
180
175
  * @param {number} id bu id
181
176
  * @returns {string} "bu name (bu id)""
182
177
  */
183
- static getBuName(buObject, id) {
184
- const name = buObject.eid == id ? '_ParentBU_' : this.buIdName[id];
178
+ static getBuName(id) {
179
+ const name = this.buObject.eid == id ? '_ParentBU_' : this.buIdName[id];
185
180
  return `<nobr>${name} (${id})</nobr>`;
186
181
  }
187
182
  /**
188
183
  * Creates markdown documentation of all roles
189
184
  *
190
- * @param {TYPE.BuObject} buObject properties for auth
191
185
  * @param {TYPE.MetadataTypeMap} [metadata] user list
192
186
  * @returns {Promise.<void>} -
193
187
  */
194
- static async document(buObject, metadata) {
195
- if (buObject.eid !== buObject.mid) {
188
+ static async document(metadata) {
189
+ if (this.buObject.eid !== this.buObject.mid) {
196
190
  Util.logger.error(
197
191
  `Users can only be retrieved & documented for the ${Util.parentBuName}`
198
192
  );
@@ -204,7 +198,7 @@ class AccountUser extends MetadataType {
204
198
  metadata = this.readBUMetadataForType(
205
199
  File.normalizePath([
206
200
  this.properties.directories.retrieve,
207
- buObject.credential,
201
+ this.buObject.credential,
208
202
  Util.parentBuName,
209
203
  ]),
210
204
  true
@@ -252,12 +246,12 @@ class AccountUser extends MetadataType {
252
246
  if (user.AssociatedBusinessUnits__c) {
253
247
  associatedBus = user.AssociatedBusinessUnits__c.map((item) => {
254
248
  this.buIdName[item.ID] = item.Name;
255
- return this.getBuName(buObject, item.ID);
249
+ return this.getBuName(item.ID);
256
250
  })
257
251
  .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0))
258
252
  .join(',<br> ');
259
253
  }
260
- const defaultBUName = this.getBuName(buObject, user.DefaultBusinessUnit);
254
+ const defaultBUName = this.getBuName(user.DefaultBusinessUnit);
261
255
  users.push({
262
256
  TYPE: user.type__c,
263
257
  UserID: user.UserID,
@@ -297,7 +291,7 @@ class AccountUser extends MetadataType {
297
291
  ['Modified Date', 'ModifiedDate'],
298
292
  ['Created Date', 'CreatedDate'],
299
293
  ];
300
- let output = `# User Overview - ${buObject.credential}`;
294
+ let output = `# User Overview - ${this.buObject.credential}`;
301
295
  output += this._generateDocMd(
302
296
  users.filter((user) => user.TYPE === 'User' && user.ActiveFlag === '✓'),
303
297
  'User',
@@ -316,7 +310,7 @@ class AccountUser extends MetadataType {
316
310
  const docPath = File.normalizePath([this.properties.directories.docs, 'user']);
317
311
 
318
312
  try {
319
- const filename = buObject.credential;
313
+ const filename = this.buObject.credential;
320
314
  // write to disk
321
315
  await File.writeToFile(docPath, filename + '.accountUsers', 'md', output);
322
316
  Util.logger.info(`Created ${File.normalizePath([docPath, filename])}.accountUsers.md`);