mcdev 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/.eslintrc.json +1 -1
  2. package/.github/ISSUE_TEMPLATE/bug.yml +72 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. package/.github/ISSUE_TEMPLATE/task.md +10 -0
  5. package/.github/PULL_REQUEST_TEMPLATE.md +11 -0
  6. package/.github/workflows/npm-publish.yml +33 -0
  7. package/.issuetracker +11 -3
  8. package/.vscode/extensions.json +1 -2
  9. package/.vscode/settings.json +19 -4
  10. package/CHANGELOG.md +98 -0
  11. package/README.md +247 -142
  12. package/boilerplate/config.json +3 -2
  13. package/docs/dist/considerations.md +66 -0
  14. package/docs/dist/documentation.md +5794 -0
  15. package/lib/Deployer.js +4 -1
  16. package/lib/MetadataTypeDefinitions.js +1 -0
  17. package/lib/MetadataTypeInfo.js +1 -0
  18. package/lib/Retriever.js +32 -17
  19. package/lib/cli.js +295 -0
  20. package/lib/index.js +774 -1019
  21. package/lib/metadataTypes/AccountUser.js +389 -0
  22. package/lib/metadataTypes/Asset.js +140 -116
  23. package/lib/metadataTypes/Automation.js +119 -54
  24. package/lib/metadataTypes/DataExtension.js +172 -131
  25. package/lib/metadataTypes/DataExtensionField.js +134 -4
  26. package/lib/metadataTypes/Folder.js +66 -69
  27. package/lib/metadataTypes/ImportFile.js +4 -6
  28. package/lib/metadataTypes/MetadataType.js +168 -80
  29. package/lib/metadataTypes/Query.js +54 -25
  30. package/lib/metadataTypes/Role.js +13 -8
  31. package/lib/metadataTypes/Script.js +43 -24
  32. package/lib/metadataTypes/definitions/AccountUser.definition.js +227 -0
  33. package/lib/metadataTypes/definitions/Asset.definition.js +1 -0
  34. package/lib/metadataTypes/definitions/Campaign.definition.js +1 -1
  35. package/lib/metadataTypes/definitions/DataExtension.definition.js +1 -1
  36. package/lib/metadataTypes/definitions/DataExtensionField.definition.js +1 -1
  37. package/lib/metadataTypes/definitions/Folder.definition.js +1 -1
  38. package/lib/metadataTypes/definitions/ImportFile.definition.js +2 -1
  39. package/lib/metadataTypes/definitions/Script.definition.js +5 -5
  40. package/lib/retrieveChangelog.js +96 -0
  41. package/lib/util/cli.js +4 -6
  42. package/lib/util/init.config.js +3 -0
  43. package/lib/util/init.git.js +2 -1
  44. package/lib/util/util.js +35 -18
  45. package/package.json +20 -24
  46. package/test/util/file.js +51 -0
  47. package/img/README.md/troubleshoot-nodejs-postinstall.jpg +0 -0
  48. package/postinstall.js +0 -41
  49. package/test/deployer.js +0 -16
  50. package/test/util.js +0 -26
@@ -7,6 +7,19 @@ const bluebird = require('bluebird');
7
7
  const cliProgress = require('cli-progress');
8
8
  const Mustache = require('mustache');
9
9
 
10
+ /**
11
+ * @typedef {Object.<string, any>} AssetItem
12
+ *
13
+ * @typedef {Object.<string, AssetItem>} AssetMap
14
+ *
15
+ * @typedef {'archive'|'asset'|'audio'|'block'|'code'|'document'|'image'|'message'|'other'|'rawimage'|'template'|'textfile'|'video'} AssetSubType
16
+ *
17
+ * @typedef {Object} CodeExtractItem
18
+ * @property {AssetItem} json metadata of one item w/o code
19
+ * @property {MetadataType.CodeExtract[]} codeArr list of code snippets in this item
20
+ * @property {string[]} subFolder mostly set to null, otherwise list of subfolders
21
+ */
22
+
10
23
  /**
11
24
  * FileTransfer MetadataType
12
25
  * @augments MetadataType
@@ -14,11 +27,11 @@ const Mustache = require('mustache');
14
27
  class Asset extends MetadataType {
15
28
  /**
16
29
  * Retrieves Metadata of Asset
17
- * @param {String} retrieveDir Directory where retrieved metadata directory will be saved
30
+ * @param {string} retrieveDir Directory where retrieved metadata directory will be saved
18
31
  * @param {void} _ -
19
32
  * @param {void} __ -
20
- * @param {String} [selectedSubType] optionally limit to a single subtype
21
- * @returns {Promise} Promise
33
+ * @param {AssetSubType} [selectedSubType] optionally limit to a single subtype
34
+ * @returns {Promise<{metadata:AssetMap,type:string}>} Promise
22
35
  */
23
36
  static async retrieve(retrieveDir, _, __, selectedSubType) {
24
37
  const items = [];
@@ -48,8 +61,8 @@ class Asset extends MetadataType {
48
61
  /**
49
62
  * Retrieves asset metadata for caching
50
63
  * @param {void} _ -
51
- * @param {String} [selectedSubType] optionally limit to a single subtype
52
- * @returns {Promise} Promise
64
+ * @param {string} [selectedSubType] optionally limit to a single subtype
65
+ * @returns {Promise<{metadata:AssetMap,type:string}>} Promise
53
66
  */
54
67
  static retrieveForCache(_, selectedSubType) {
55
68
  return this.retrieve(null, null, null, selectedSubType);
@@ -57,13 +70,13 @@ class Asset extends MetadataType {
57
70
 
58
71
  /**
59
72
  * Retrieves asset metadata for caching
60
- * @param {String} templateDir Directory where retrieved metadata directory will be saved
61
- * @param {String} templateName name of the metadata file
62
- * @param {Object} templateVariables variables to be replaced in the metadata
63
- * @param {String} [selectedSubType] optionally limit to a single subtype
64
- * @returns {Promise} Promise
73
+ * @param {string} templateDir Directory where retrieved metadata directory will be saved
74
+ * @param {string} name name of the metadata file
75
+ * @param {Util.TemplateMap} templateVariables variables to be replaced in the metadata
76
+ * @param {AssetSubType} [selectedSubType] optionally limit to a single subtype
77
+ * @returns {Promise<{metadata:AssetMap,type:string}>} Promise
65
78
  */
66
- static async retrieveAsTemplate(templateDir, templateName, templateVariables, selectedSubType) {
79
+ static async retrieveAsTemplate(templateDir, name, templateVariables, selectedSubType) {
67
80
  const items = [];
68
81
  const subTypes = selectedSubType ? [selectedSubType] : this._getSubTypes();
69
82
  await File.initPrettier();
@@ -76,12 +89,15 @@ class Asset extends MetadataType {
76
89
  subType,
77
90
  this.definition.extendedSubTypes[subType],
78
91
  templateDir,
79
- templateName,
92
+ name,
80
93
  templateVariables
81
94
  ))
82
95
  );
83
96
  }
84
97
  const metadata = this.parseResponseBody({ items: items });
98
+ if (!Object.keys(metadata).length) {
99
+ Util.logger.error(`${this.definition.type} '${name}' not found on server.`);
100
+ }
85
101
  Util.logger.info(`Downloaded: ${this.definition.type} (${Object.keys(metadata).length})`);
86
102
 
87
103
  return { metadata: metadata, type: this.definition.type };
@@ -89,22 +105,26 @@ class Asset extends MetadataType {
89
105
  /**
90
106
  * helper for retrieve + retrieveAsTemplate
91
107
  * @private
92
- * @returns {String[]} subtype array
108
+ * @returns {AssetSubType[]} subtype array
93
109
  */
94
110
  static _getSubTypes() {
95
- if (this.properties.metaDataTypes.retrieve.includes('asset')) {
111
+ const selectedSubTypeArr = this.properties.metaDataTypes.retrieve.filter((type) =>
112
+ type.startsWith('asset-')
113
+ );
114
+ if (
115
+ this.properties.metaDataTypes.retrieve.includes('asset') ||
116
+ !selectedSubTypeArr.length
117
+ ) {
96
118
  // if "asset" is found in config assume to download the default subtypes only
97
119
  return this.definition.typeRetrieveByDefault;
98
120
  } else {
99
- return this.properties.metaDataTypes.retrieve
100
- .filter((type) => type.startsWith('asset-'))
101
- .map((type) => type.replace('asset-', ''));
121
+ return selectedSubTypeArr.map((type) => type.replace('asset-', ''));
102
122
  }
103
123
  }
104
124
 
105
125
  /**
106
126
  * Creates a single asset
107
- * @param {Object} metadata a single asset
127
+ * @param {AssetItem} metadata a single asset
108
128
  * @returns {Promise} Promise
109
129
  */
110
130
  static create(metadata) {
@@ -114,7 +134,7 @@ class Asset extends MetadataType {
114
134
 
115
135
  /**
116
136
  * Updates a single asset
117
- * @param {Object} metadata a single asset
137
+ * @param {AssetItem} metadata a single asset
118
138
  * @returns {Promise} Promise
119
139
  */
120
140
  static update(metadata) {
@@ -123,11 +143,11 @@ class Asset extends MetadataType {
123
143
  }
124
144
  /**
125
145
  * Retrieves Metadata of a specific asset type
126
- * @param {String} subType group of similar assets to put in a folder (ie. images)
127
- * @param {Array} subTypeArray list of all asset types within this subtype
128
- * @param {String} [retrieveDir] target directory for saving assets
129
- * @param {String} [templateName] name of the metadata file
130
- * @param {Object} [templateVariables] variables to be replaced in the metadata
146
+ * @param {AssetSubType} subType group of similar assets to put in a folder (ie. images)
147
+ * @param {AssetSubType[]} subTypeArray list of all asset types within this subtype
148
+ * @param {string} [retrieveDir] target directory for saving assets
149
+ * @param {string} [templateName] name of the metadata file
150
+ * @param {Util.TemplateMap} [templateVariables] variables to be replaced in the metadata
131
151
  * @returns {Promise} Promise
132
152
  */
133
153
  static async requestSubType(
@@ -142,6 +162,7 @@ class Asset extends MetadataType {
142
162
  } else {
143
163
  Util.logger.info(`- Caching Subtype: ${subType}`);
144
164
  }
165
+ const subtypeIds = subTypeArray?.map(subTypeItemName => Asset.definition.typeMapping[subTypeItemName]);
145
166
  const uri = 'asset/v1/content/assets/';
146
167
  const options = {
147
168
  uri: uri + 'query',
@@ -158,9 +179,9 @@ class Asset extends MetadataType {
158
179
  if (templateName) {
159
180
  options.json.query = {
160
181
  leftOperand: {
161
- property: 'assetType.name',
182
+ property: 'assetType.id',
162
183
  simpleOperator: 'in',
163
- value: subTypeArray,
184
+ value: subtypeIds,
164
185
  },
165
186
  logicalOperator: 'AND',
166
187
  rightOperand: {
@@ -171,9 +192,9 @@ class Asset extends MetadataType {
171
192
  };
172
193
  } else {
173
194
  options.json.query = {
174
- property: 'assetType.name',
195
+ property: 'assetType.id',
175
196
  simpleOperator: 'in',
176
- value: subTypeArray,
197
+ value: subtypeIds,
177
198
  };
178
199
  options.json.sort = [{ property: 'id', direction: 'ASC' }];
179
200
  }
@@ -197,7 +218,10 @@ class Asset extends MetadataType {
197
218
  let items = [];
198
219
  do {
199
220
  options.json.page.page = lastPage + 1;
200
- const response = await this.client.RestClient.post(options);
221
+ let response;
222
+ await Util.retryOnError(`Retrying Subtype: ${subType}`, async () => {
223
+ response = await this.client.RestClient.post(options);
224
+ });
201
225
  if (response && response.body && response.body.items && response.body.items.length) {
202
226
  // sometimes the api will return a payload without items
203
227
  // --> ensure we only add proper items-arrays here
@@ -209,9 +233,9 @@ class Asset extends MetadataType {
209
233
  // Since we sort by ID, we can get the last ID then run new requests from there
210
234
  options.json.query = {
211
235
  leftOperand: {
212
- property: 'assetType.name',
236
+ property: 'assetType.id',
213
237
  simpleOperator: 'in',
214
- value: subTypeArray,
238
+ value: subtypeIds,
215
239
  },
216
240
  logicalOperator: 'AND',
217
241
  rightOperand: {
@@ -239,9 +263,9 @@ class Asset extends MetadataType {
239
263
  /**
240
264
  * Retrieves extended metadata (files or extended content) of asset
241
265
  * @param {Array} items array of items to retrieve
242
- * @param {String} subType group of similar assets to put in a folder (ie. images)
243
- * @param {String} retrieveDir target directory for saving assets
244
- * @param {Object} [templateVariables] variables to be replaced in the metadata
266
+ * @param {AssetSubType} subType group of similar assets to put in a folder (ie. images)
267
+ * @param {string} retrieveDir target directory for saving assets
268
+ * @param {Util.TemplateMap} [templateVariables] variables to be replaced in the metadata
245
269
  * @returns {Promise} Promise
246
270
  */
247
271
  static async requestAndSaveExtended(items, subType, retrieveDir, templateVariables) {
@@ -274,7 +298,7 @@ class Asset extends MetadataType {
274
298
  ) {
275
299
  metadata[item.customerKey] = item;
276
300
  if (templateVariables) {
277
- // do this here already because otherwise the extended file could be saved with wrong filename
301
+ // do this here already because otherwise the extended file could be saved with wrong fileName
278
302
  const warningMsg =
279
303
  'Ensure that Code that might be loading this via ContentBlockByKey is updated with the new key before deployment.';
280
304
  this.overrideKeyWithName(item, warningMsg);
@@ -320,9 +344,9 @@ class Asset extends MetadataType {
320
344
  /**
321
345
  * Some metadata types store their actual content as a separate file, e.g. images
322
346
  * This method retrieves these and saves them alongside the metadata json
323
- * @param {Object} metadata a single asset
324
- * @param {String} subType group of similar assets to put in a folder (ie. images)
325
- * @param {String} retrieveDir target directory for saving assets
347
+ * @param {AssetItem} metadata a single asset
348
+ * @param {AssetSubType} subType group of similar assets to put in a folder (ie. images)
349
+ * @param {string} retrieveDir target directory for saving assets
326
350
  * @returns {Promise<void>} -
327
351
  */
328
352
  static async _retrieveExtendedFile(metadata, subType, retrieveDir) {
@@ -330,14 +354,14 @@ class Asset extends MetadataType {
330
354
  uri: 'asset/v1/content/assets/' + metadata.id + '/file',
331
355
  });
332
356
 
333
- // to handle uploaded files that bear the same name, SFMC engineers decided to add a number after the filename
357
+ // to handle uploaded files that bear the same name, SFMC engineers decided to add a number after the fileName
334
358
  // however, their solution was not following standards: fileName="header.png (4) " and then extension="png (4) "
335
- const fileext = metadata.fileProperties.extension.split(' ')[0];
359
+ const fileExt = metadata.fileProperties.extension.split(' ')[0];
336
360
 
337
361
  File.writeToFile(
338
362
  [retrieveDir, this.definition.type, subType],
339
363
  metadata.customerKey,
340
- fileext,
364
+ fileExt,
341
365
  file.body,
342
366
  'base64'
343
367
  );
@@ -346,31 +370,31 @@ class Asset extends MetadataType {
346
370
  * helper for this.preDeployTasks()
347
371
  * Some metadata types store their actual content as a separate file, e.g. images
348
372
  * This method reads these from the local FS stores them in the metadata object allowing to deploy it
349
- * @param {Object} metadata a single asset
350
- * @param {String} subType group of similar assets to put in a folder (ie. images)
351
- * @param {String} deployDir directory of deploy files
373
+ * @param {AssetItem} metadata a single asset
374
+ * @param {AssetSubType} subType group of similar assets to put in a folder (ie. images)
375
+ * @param {string} deployDir directory of deploy files
352
376
  * @returns {Promise<void>} -
353
377
  */
354
378
  static async _readExtendedFileFromFS(metadata, subType, deployDir) {
355
379
  if (metadata.fileProperties && metadata.fileProperties.extension) {
356
- // to handle uploaded files that bear the same name, SFMC engineers decided to add a number after the filename
380
+ // to handle uploaded files that bear the same name, SFMC engineers decided to add a number after the fileName
357
381
  // however, their solution was not following standards: fileName="header.png (4) " and then extension="png (4) "
358
- const fileext = metadata.fileProperties.extension.split(' ')[0];
382
+ const fileExt = metadata.fileProperties.extension.split(' ')[0];
359
383
 
360
384
  metadata.file = await File.readFile(
361
385
  [deployDir, this.definition.type, subType],
362
386
  metadata.customerKey,
363
- fileext,
387
+ fileExt,
364
388
  'base64'
365
389
  );
366
390
  }
367
391
  }
368
392
  /**
369
393
  * manages post retrieve steps
370
- * @param {Object} metadata a single asset
371
- * @param {String} [_] unused
394
+ * @param {AssetItem} metadata a single asset
395
+ * @param {string} [_] unused
372
396
  * @param {Boolean} isTemplating signals that we are retrieving templates
373
- * @returns {Object[]} metadata
397
+ * @returns {CodeExtractItem} metadata
374
398
  */
375
399
  static postRetrieveTasks(metadata, _, isTemplating) {
376
400
  // if retrieving template, replace the name with customer key if that wasn't already the case
@@ -384,9 +408,9 @@ class Asset extends MetadataType {
384
408
 
385
409
  /**
386
410
  * prepares an asset definition for deployment
387
- * @param {Object} metadata a single asset
388
- * @param {String} deployDir directory of deploy files
389
- * @returns {Promise} Promise
411
+ * @param {AssetItem} metadata a single asset
412
+ * @param {string} deployDir directory of deploy files
413
+ * @returns {Promise<AssetItem>} Promise
390
414
  */
391
415
  static async preDeployTasks(metadata, deployDir) {
392
416
  // additonalattributes fail where the value is "" so we need to remove them from deploy
@@ -418,14 +442,14 @@ class Asset extends MetadataType {
418
442
  await this._mergeCode(metadata, deployDir, subType);
419
443
 
420
444
  // #2 get file from local disk and insert as base64
421
- await this._readExtendedFileFromFS(metadata, deployDir, subType);
445
+ await this._readExtendedFileFromFS(metadata, subType, deployDir);
422
446
 
423
447
  return metadata;
424
448
  }
425
449
  /**
426
450
  * determines the subtype of the current asset
427
- * @param {Object} metadata a single asset
428
- * @returns {String} subtype
451
+ * @param {AssetItem} metadata a single asset
452
+ * @returns {AssetSubType} subtype
429
453
  */
430
454
  static getSubtype(metadata) {
431
455
  for (const sub in this.definition.extendedSubTypes) {
@@ -438,12 +462,12 @@ class Asset extends MetadataType {
438
462
  /**
439
463
  * helper for buildDefinition
440
464
  * handles extracted code if any are found for complex types
441
- * @param {String} templateDir Directory where metadata templates are stored
442
- * @param {String} targetDir Directory where built definitions will be saved
443
- * @param {Object} metadata main JSON file that was read from file system
444
- * @param {Object} variables variables to be replaced in the metadata
445
- * @param {String} templateName name of the template to be built
446
- * @returns {Promise} Promise
465
+ * @param {string} templateDir Directory where metadata templates are stored
466
+ * @param {string} targetDir Directory where built definitions will be saved
467
+ * @param {AssetItem} metadata main JSON file that was read from file system
468
+ * @param {Util.TemplateMap} variables variables to be replaced in the metadata
469
+ * @param {string} templateName name of the template to be built
470
+ * @returns {Promise<void>} Promise
447
471
  */
448
472
  static async buildDefinitionForExtracts(
449
473
  templateDir,
@@ -468,27 +492,27 @@ class Asset extends MetadataType {
468
492
  throw new Error(
469
493
  `${this.definition.type}:: Error applying template variables on ${
470
494
  metadata[this.definition.keyField]
471
- }: ${extractedFile.filename}.${extractedFile.fileext}.`
495
+ }: ${extractedFile.fileName}.${extractedFile.fileExt}.`
472
496
  );
473
497
  }
474
498
  }
475
499
 
476
500
  // #2 binary extracts
477
501
  if (metadata.fileProperties && metadata.fileProperties.extension) {
478
- // to handle uploaded files that bear the same name, SFMC engineers decided to add a number after the filename
502
+ // to handle uploaded files that bear the same name, SFMC engineers decided to add a number after the fileName
479
503
  // however, their solution was not following standards: fileName="header.png (4) " and then extension="png (4) "
480
- const fileext = metadata.fileProperties.extension.split(' ')[0];
504
+ const fileExt = metadata.fileProperties.extension.split(' ')[0];
481
505
 
482
506
  const filecontent = await File.readFile(
483
507
  [templateDir, this.definition.type, subType],
484
508
  metadata.customerKey,
485
- fileext,
509
+ fileExt,
486
510
  'base64'
487
511
  );
488
512
  fileList.push({
489
- pathArr: [this.definition.type, subType],
490
- filename: metadata.customerKey,
491
- fileext: fileext,
513
+ subFolder: [this.definition.type, subType],
514
+ fileName: metadata.customerKey,
515
+ fileExt: fileExt,
492
516
  content: filecontent,
493
517
  encoding: 'base64',
494
518
  });
@@ -499,9 +523,9 @@ class Asset extends MetadataType {
499
523
  for (const targetDir of targetDirArr) {
500
524
  for (const extractedFile of fileList) {
501
525
  File.writeToFile(
502
- [targetDir, ...extractedFile.pathArr],
503
- extractedFile.filename,
504
- extractedFile.fileext,
526
+ [targetDir, ...extractedFile.subFolder],
527
+ extractedFile.fileName,
528
+ extractedFile.fileExt,
505
529
  extractedFile.content,
506
530
  extractedFile.encoding || null
507
531
  );
@@ -511,8 +535,8 @@ class Asset extends MetadataType {
511
535
 
512
536
  /**
513
537
  * parses retrieved Metadata before saving
514
- * @param {Object} metadata a single asset definition
515
- * @returns {Object} parsed metadata definition
538
+ * @param {AssetItem} metadata a single asset definition
539
+ * @returns {CodeExtractItem} parsed metadata definition
516
540
  */
517
541
  static parseMetadata(metadata) {
518
542
  // folder
@@ -538,11 +562,11 @@ class Asset extends MetadataType {
538
562
  }
539
563
  /**
540
564
  * helper for this.preDeployTasks() that loads extracted code content back into JSON
541
- * @param {Object} metadata a single asset definition
542
- * @param {String} deployDir directory of deploy files
543
- * @param {String} subType asset-subtype name
544
- * @param {String} [templateName] name of the template used to built defintion (prior applying templating)
545
- * @returns {Promise<Object[]>} fileList for templating (disregarded during deployment)
565
+ * @param {AssetItem} metadata a single asset definition
566
+ * @param {string} deployDir directory of deploy files
567
+ * @param {AssetSubType} subType asset-subtype name
568
+ * @param {string} [templateName] name of the template used to built defintion (prior applying templating)
569
+ * @returns {Promise<MetadataType.CodeExtract[]>} fileList for templating (disregarded during deployment)
546
570
  */
547
571
  static async _mergeCode(metadata, deployDir, subType, templateName) {
548
572
  const subtypeExtension = `.${this.definition.type}-${subType}-meta`;
@@ -578,9 +602,9 @@ class Asset extends MetadataType {
578
602
  if (templateName) {
579
603
  // to use this method in templating, store a copy of the info in fileList
580
604
  fileList.push({
581
- pathArr: [...subDirArr, metadata.customerKey],
582
- filename: 'index' + subtypeExtension,
583
- fileext: 'html',
605
+ subFolder: [...subDirArr, metadata.customerKey],
606
+ fileName: 'index' + subtypeExtension,
607
+ fileExt: 'html',
584
608
  content: metadata.views.html.content,
585
609
  });
586
610
  }
@@ -623,9 +647,9 @@ class Asset extends MetadataType {
623
647
  if (templateName) {
624
648
  // to use this method in templating, store a copy of the info in fileList
625
649
  fileList.push({
626
- pathArr: subDirArr,
627
- filename: metadata.customerKey + subtypeExtension,
628
- fileext: 'html',
650
+ subFolder: subDirArr,
651
+ fileName: metadata.customerKey + subtypeExtension,
652
+ fileExt: 'html',
629
653
  content: metadata.views.text.content,
630
654
  });
631
655
  }
@@ -658,9 +682,9 @@ class Asset extends MetadataType {
658
682
  if (templateName) {
659
683
  // to use this method in templating, store a copy of the info in fileList
660
684
  fileList.push({
661
- pathArr: subDirArr,
662
- filename: metadata.customerKey + subtypeExtension,
663
- fileext: 'html',
685
+ subFolder: subDirArr,
686
+ fileName: metadata.customerKey + subtypeExtension,
687
+ fileExt: 'html',
664
688
  content: metadata.content,
665
689
  });
666
690
  }
@@ -672,12 +696,12 @@ class Asset extends MetadataType {
672
696
  /**
673
697
  * helper for this.preDeployTasks() that loads extracted code content back into JSON
674
698
  * @param {Object} metadataSlots metadata.views.html.slots or deeper slots.<>.blocks.<>.slots
675
- * @param {String[]} readDirArr directory of deploy files
676
- * @param {String} subtypeExtension asset-subtype name ending on -meta
677
- * @param {String[]} subDirArr directory of files w/o leading deploy dir
699
+ * @param {string[]} readDirArr directory of deploy files
700
+ * @param {string} subtypeExtension asset-subtype name ending on -meta
701
+ * @param {string[]} subDirArr directory of files w/o leading deploy dir
678
702
  * @param {Object[]} fileList directory of files w/o leading deploy dir
679
- * @param {String} customerKey external key of template (could have been changed if used during templating)
680
- * @param {String} [templateName] name of the template used to built defintion (prior applying templating)
703
+ * @param {string} customerKey external key of template (could have been changed if used during templating)
704
+ * @param {string} [templateName] name of the template used to built defintion (prior applying templating)
681
705
  * @returns {Promise<void>} -
682
706
  */
683
707
  static async _mergeCode_slots(
@@ -696,13 +720,13 @@ class Asset extends MetadataType {
696
720
  if (slotObj.blocks) {
697
721
  for (const block in slotObj.blocks) {
698
722
  if (Object.prototype.hasOwnProperty.call(slotObj.blocks, block)) {
699
- const filename = `${slot}-${block}${subtypeExtension}`;
723
+ const fileName = `${slot}-${block}${subtypeExtension}`;
700
724
  if (
701
725
  File.existsSync(
702
726
  File.normalizePath([
703
727
  ...readDirArr,
704
728
  'blocks',
705
- `${filename}.html`,
729
+ `${fileName}.html`,
706
730
  ])
707
731
  )
708
732
  ) {
@@ -710,15 +734,15 @@ class Asset extends MetadataType {
710
734
  // if an extracted block was found, save it back into JSON
711
735
  slotObj.blocks[block].content = await File.readFile(
712
736
  [...readDirArr, 'blocks'],
713
- filename,
737
+ fileName,
714
738
  'html'
715
739
  );
716
740
  if (templateName) {
717
741
  // to use this method in templating, store a copy of the info in fileList
718
742
  fileList.push({
719
- pathArr: [...subDirArr, customerKey, 'blocks'],
720
- filename: filename,
721
- fileext: 'html',
743
+ subFolder: [...subDirArr, customerKey, 'blocks'],
744
+ fileName: fileName,
745
+ fileExt: 'html',
722
746
  content: slotObj.blocks[block].content,
723
747
  });
724
748
  }
@@ -744,8 +768,8 @@ class Asset extends MetadataType {
744
768
  /**
745
769
  * helper for this.parseMetadata() that finds code content in JSON and extracts it
746
770
  * to allow saving that separately and formatted
747
- * @param {Object} metadata a single asset definition
748
- * @returns {Object} { json: metadata, codeArr: object[], subFolder: string[] }
771
+ * @param {AssetItem} metadata a single asset definition
772
+ * @returns {CodeExtractItem} { json: metadata, codeArr: object[], subFolder: string[] }
749
773
  */
750
774
  static _extractCode(metadata) {
751
775
  const codeArr = [];
@@ -835,8 +859,8 @@ class Asset extends MetadataType {
835
859
  }
836
860
  }
837
861
  /**
838
- * Returns file contents mapped to their filename without '.json' ending
839
- * @param {String} dir directory that contains '.json' files to be read
862
+ * Returns file contents mapped to their fileName without '.json' ending
863
+ * @param {string} dir directory that contains '.json' files to be read
840
864
  * @returns {Object} fileName => fileContent map
841
865
  */
842
866
  static getJsonFromFS(dir) {
@@ -850,7 +874,7 @@ class Asset extends MetadataType {
850
874
  files.forEach((dirent) => {
851
875
  try {
852
876
  let thisDir = currentdir;
853
- let filename = dirent.name;
877
+ let fileName = dirent.name;
854
878
  if (dirent.isDirectory()) {
855
879
  // complex types with more than one extracted piece of code are saved in their
856
880
  // own subfolder (with folder name = CustomerKey)
@@ -860,20 +884,20 @@ class Asset extends MetadataType {
860
884
  );
861
885
  subfolderFiles.forEach((subFileName) => {
862
886
  if (subFileName.endsWith('-meta.json')) {
863
- filename = subFileName;
887
+ fileName = subFileName;
864
888
  thisDir = File.normalizePath([currentdir, dirent.name]);
865
889
  }
866
890
  });
867
891
  }
868
- if (filename.endsWith('-meta.json')) {
892
+ if (fileName.endsWith('-meta.json')) {
869
893
  const fileContent = File.readJSONFile(
870
894
  thisDir,
871
- filename,
895
+ fileName,
872
896
  true,
873
897
  false
874
898
  );
875
899
  // subtype will change the metadata suffix length
876
- const fileNameWithoutEnding = filename.slice(
900
+ const fileNameWithoutEnding = fileName.slice(
877
901
  0,
878
902
  -17 - subtype.length
879
903
  );
@@ -895,9 +919,9 @@ class Asset extends MetadataType {
895
919
  }
896
920
  /**
897
921
  * check template directory for complex types that open subfolders for their subtypes
898
- * @param {String} templateDir Directory where metadata templates are stored
899
- * @param {String} templateName name of the metadata file
900
- * @returns {string} subtype name
922
+ * @param {string} templateDir Directory where metadata templates are stored
923
+ * @param {string} templateName name of the metadata file
924
+ * @returns {AssetSubType} subtype name
901
925
  */
902
926
  static findSubType(templateDir, templateName) {
903
927
  const typeDirArr = [this.definition.type];
@@ -928,11 +952,11 @@ class Asset extends MetadataType {
928
952
  }
929
953
  /**
930
954
  * optional method used for some types to try a different folder structure
931
- * @param {String} templateDir Directory where metadata templates are stored
932
- * @param {String[]} typeDirArr current subdir for this type
933
- * @param {String} templateName name of the metadata template
934
- * @param {String} fileName name of the metadata template file w/o extension
935
- * @returns {Object} metadata
955
+ * @param {string} templateDir Directory where metadata templates are stored
956
+ * @param {string[]} typeDirArr current subdir for this type
957
+ * @param {string} templateName name of the metadata template
958
+ * @param {string} fileName name of the metadata template file w/o extension
959
+ * @returns {AssetItem} metadata
936
960
  */
937
961
  static async readSecondaryFolder(templateDir, typeDirArr, templateName, fileName) {
938
962
  // handles subtypes that create 1 folder per asset -> currently causes the below File.ReadFile to error out