mcdev 7.1.1 → 7.1.2

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 (67) hide show
  1. package/.gitattributes +2 -0
  2. package/.github/ISSUE_TEMPLATE/bug.yml +1 -0
  3. package/.github/PULL_REQUEST_TEMPLATE/pr_template_release.md +5 -5
  4. package/@types/lib/index.d.ts.map +1 -1
  5. package/@types/lib/metadataTypes/Asset.d.ts +2 -0
  6. package/@types/lib/metadataTypes/Asset.d.ts.map +1 -1
  7. package/@types/lib/metadataTypes/Folder.d.ts.map +1 -1
  8. package/@types/lib/metadataTypes/Journey.d.ts +433 -17
  9. package/@types/lib/metadataTypes/Journey.d.ts.map +1 -1
  10. package/@types/lib/metadataTypes/MetadataType.d.ts +9 -2
  11. package/@types/lib/metadataTypes/MetadataType.d.ts.map +1 -1
  12. package/@types/lib/metadataTypes/definitions/Asset.definition.d.ts +2 -0
  13. package/@types/lib/metadataTypes/definitions/Journey.definition.d.ts +433 -17
  14. package/@types/lib/util/cache.d.ts +2 -1
  15. package/@types/lib/util/cache.d.ts.map +1 -1
  16. package/@types/lib/util/util.d.ts.map +1 -1
  17. package/@types/types/mcdev.d.d.ts +4 -4
  18. package/@types/types/mcdev.d.d.ts.map +1 -1
  19. package/eslint.config.js +1 -0
  20. package/lib/cli.js +5 -0
  21. package/lib/index.js +2 -1
  22. package/lib/metadataTypes/Asset.js +86 -20
  23. package/lib/metadataTypes/Folder.js +15 -7
  24. package/lib/metadataTypes/Journey.js +3 -8
  25. package/lib/metadataTypes/MetadataType.js +37 -16
  26. package/lib/metadataTypes/definitions/Asset.definition.js +2 -0
  27. package/lib/metadataTypes/definitions/Event.definition.js +4 -4
  28. package/lib/metadataTypes/definitions/Journey.definition.js +438 -22
  29. package/lib/util/cache.js +4 -3
  30. package/lib/util/util.js +7 -2
  31. package/package.json +2 -2
  32. package/test/mockRoot/.mcdevrc.json +1 -1
  33. package/test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_htmlblock-matchName-create.asset-block-meta.html +23 -0
  34. package/test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_htmlblock-matchName-create.asset-block-meta.json +41 -0
  35. package/test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_htmlblock-matchName-fail.asset-block-meta.html +23 -0
  36. package/test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_htmlblock-matchName-fail.asset-block-meta.json +41 -0
  37. package/test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_htmlblock-matchName.asset-block-meta.html +23 -0
  38. package/test/mockRoot/deploy/testInstance/testBU/asset/block/testExisting_asset_htmlblock-matchName.asset-block-meta.json +41 -0
  39. package/test/resourceFactory.js +13 -17
  40. package/test/resources/9999999/asset/v1/content/assets/1295064/patch-response.json +59 -0
  41. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN1,3,14,15,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,205,206,210,211,212,213,215,216,217,218,219,220,221,222,223,224.json +219 -0
  42. package/test/resources/9999999/asset/v1/content/assets/query/{post-response-assetType.idIN205,206,230,232,1,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,14,193,194,15,195,196,197,198,199,200,201,202,203,210,211,212,213,3,215,216,217,218,219,220,221,222.json → post-response-assetType.idIN1,3,4,14,15,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,205,206,210,211,212,213,214,215,216,217,218,219,220,221,222.json} +19 -16
  43. package/test/resources/9999999/asset/v1/content/assets/query/{post-response-assetType.idIN205,206,230,232,1,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,14,193,194,15,195,196,197,198,199,200,201,202,203,210,211,212,213,3,207,208,209,5,214,4,215,216.json → post-response-assetType.idIN1,3,4,5,14,15,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,205,206,207,208,209,210,211,212,213,214,215,216,217,218.json} +77 -25
  44. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN219,220,221,222,223,224,225,226,227,228,230,232.json +32 -0
  45. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN223,224,225,226,227,228,230,232.json +32 -0
  46. package/test/resources/9999999/interaction/v1/interactions/get-response.json +1 -1
  47. package/test/resources/9999999/interaction/v1/interactions/key_testExisting_journey_Multistep/get-response.json +5 -1
  48. package/test/resources/9999999/journey/build-expected.json +0 -1
  49. package/test/resources/9999999/journey/get-multistep-expected.json +8 -6
  50. package/test/resources/9999999/journey/template-expected.json +0 -1
  51. package/test/resources/9999999/triggeredSend/build-expected.json +2 -1
  52. package/test/resources/9999999/triggeredSend/get-expected.json +2 -1
  53. package/test/resources/9999999/triggeredSend/template-expected.json +2 -1
  54. package/test/resources/9999999/triggeredSendDefinition/retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml +1 -1
  55. package/test/type.asset.test.js +117 -2
  56. package/test/utils.js +30 -1
  57. package/types/mcdev.d.js +2 -2
  58. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN223,224,225,226,227,228,214,4.json +0 -35
  59. package/test/resources/9999999/asset/v1/content/assets/query/post-response-assetType.idIN223,224,225,226,227,228.json +0 -7
  60. /package/test/resources/9999999/asset/v1/content/assets/query/{post-response-assetType.idIN205,206,230,232,1.json → post-response-assetType.idIN1,205,206,230,232.json} +0 -0
  61. /package/test/resources/9999999/asset/v1/content/assets/query/{post-response-assetType.idIN205,206,230,232,1,207,208,209,5.json → post-response-assetType.idIN1,5,205,206,207,208,209,230,232.json} +0 -0
  62. /package/test/resources/9999999/asset/v1/content/assets/query/{post-response-assetType.idIN174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,14.json → post-response-assetType.idIN14,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192.json} +0 -0
  63. /package/test/resources/9999999/asset/v1/content/assets/query/{post-response-assetType.idIN193,194,15.json → post-response-assetType.idIN15,193,194.json} +0 -0
  64. /package/test/resources/9999999/asset/v1/content/assets/query/{post-response-assetType.idIN217,218,219,220,221,222,223,224,225,226,227,228.json → post-response-assetType.idIN225,226,227,228,230,232.json} +0 -0
  65. /package/test/resources/9999999/asset/v1/content/assets/query/{post-response-assetType.idIN195,196,197,198,199,200,201,202,203,210,211,212,213,3.json → post-response-assetType.idIN3,195,196,197,198,199,200,201,202,203,210,211,212,213.json} +0 -0
  66. /package/test/resources/9999999/asset/v1/content/assets/query/{post-response-assetType.idIN214,4.json → post-response-assetType.idIN4,214.json} +0 -0
  67. /package/test/resources/9999999/asset/v1/content/assets/query/{post-response-assetType.idIN207,208,209,5.json → post-response-assetType.idIN5,207,208,209.json} +0 -0
package/lib/index.js CHANGED
@@ -93,6 +93,7 @@ class Mcdev {
93
93
  'json',
94
94
  'keySuffix',
95
95
  'like',
96
+ 'matchName',
96
97
  'noLogColors',
97
98
  'noLogFile',
98
99
  'noUpdate',
@@ -731,7 +732,7 @@ class Mcdev {
731
732
  MetadataTypeInfo[type].buObject = buObject;
732
733
  await MetadataTypeInfo[type].refresh(keyArr);
733
734
  } catch (ex) {
734
- Util.logger.errorStack(ex, 'mcdev.refresh ' + ex.message);
735
+ Util.logger.errorStack(ex, 'mcdev.refresh');
735
736
  }
736
737
  }
737
738
  }
@@ -237,9 +237,9 @@ class Asset extends MetadataType {
237
237
  const subtypeIdsList = key
238
238
  ? [null]
239
239
  : Util.chunk(
240
- extendedSubTypeArr?.map(
241
- (subTypeItemName) => this.definition.typeMapping[subTypeItemName]
242
- ),
240
+ extendedSubTypeArr
241
+ ?.map((subTypeItemName) => this.definition.typeMapping[subTypeItemName])
242
+ .sort((a, b) => a - b),
243
243
  50
244
244
  );
245
245
  const uri = '/asset/v1/content/assets/query' + (loadShared ? '?scope=shared' : '');
@@ -779,22 +779,24 @@ class Asset extends MetadataType {
779
779
  metadata[this.definition.keyField].slice(0, Math.max(0, 36 - suffix.length)) +
780
780
  suffix;
781
781
  }
782
- // #4 make sure the name is unique
783
- const assetCache = cache.getCache()[this.definition.type];
784
- const namesInFolder = Object.keys(assetCache)
785
- .filter((key) => assetCache[key].category.id === metadata.category.id)
786
- .map((key) => ({
787
- type: this.#getMainSubtype(assetCache[key].assetType.name),
788
- key: key,
789
- name: assetCache[key].name,
790
- }));
791
- // if the name is already in the folder for a different key, add a number to the end
792
- metadata[this.definition.nameField] = this._findUniqueName(
793
- metadata[this.definition.keyField],
794
- metadata[this.definition.nameField],
795
- this.#getMainSubtype(metadata.assetType.name),
796
- namesInFolder
797
- );
782
+ if (!Util.OPTIONS.matchName) {
783
+ // #4 make sure the name is unique
784
+ const assetCache = cache.getCache()[this.definition.type];
785
+ const namesInFolder = Object.keys(assetCache)
786
+ .filter((key) => assetCache[key].category.id === metadata.category.id)
787
+ .map((key) => ({
788
+ type: this.#getMainSubtype(assetCache[key].assetType.name),
789
+ key: key,
790
+ name: assetCache[key].name,
791
+ }));
792
+ // if the name is already in the folder for a different key, add a number to the end
793
+ metadata[this.definition.nameField] = this._findUniqueName(
794
+ metadata[this.definition.keyField],
795
+ metadata[this.definition.nameField],
796
+ this.#getMainSubtype(metadata.assetType.name),
797
+ namesInFolder
798
+ );
799
+ }
798
800
  return metadata;
799
801
  }
800
802
  /**
@@ -2431,7 +2433,10 @@ class Asset extends MetadataType {
2431
2433
  } catch (ex) {
2432
2434
  if (ex.code !== 200) {
2433
2435
  // dont print error if we simply did not find relevant content blocks
2434
- Util.logger.errorStack(ex, ex.message);
2436
+ Util.logger.errorStack(
2437
+ ex,
2438
+ 'issue with ' + this.definition.type + ' ' + key
2439
+ );
2435
2440
  }
2436
2441
  if (!findAssetKeys) {
2437
2442
  Util.logger.info(
@@ -2539,6 +2544,67 @@ class Asset extends MetadataType {
2539
2544
  }
2540
2545
  }
2541
2546
  }
2547
+ /**
2548
+ * helper for {@link MetadataType.createOrUpdate}
2549
+ *
2550
+ * @param {MetadataTypeItem} metadataItem to be deployed item
2551
+ * @returns {MetadataTypeItem} cached item or undefined
2552
+ */
2553
+ static getCacheMatchedByName(metadataItem) {
2554
+ let cacheMatchedByName;
2555
+
2556
+ if (Util.OPTIONS.matchName) {
2557
+ // make sure to run the search ONLY if OPTIONS.matchName is true and definition.allowMatchingByName signals support
2558
+ const assetCache = cache.getCache()?.asset;
2559
+ const potentials = [];
2560
+ for (const key in assetCache) {
2561
+ const cachedAsset = assetCache[key];
2562
+ if (
2563
+ cachedAsset[this.definition.nameField] ===
2564
+ metadataItem[this.definition.nameField] &&
2565
+ cachedAsset.assetType.id === metadataItem.assetType.id
2566
+ ) {
2567
+ potentials.push(cachedAsset);
2568
+ }
2569
+ }
2570
+ if (potentials.length > 1) {
2571
+ throw new Error(
2572
+ `found multiple name matches in cache for ${this.definition.type} ${metadataItem[this.definition.keyField]} / ${metadataItem[this.definition.nameField]}. Check their keys for more details: ${potentials.map((p) => p[this.definition.keyField]).join(', ')}`
2573
+ );
2574
+ } else if (potentials.length === 1) {
2575
+ const deployFolderPath = cache.searchForField(
2576
+ 'folder',
2577
+ metadataItem.category.id,
2578
+ 'ID',
2579
+ 'Path'
2580
+ );
2581
+ if (potentials[0].category.id === metadataItem.category.id) {
2582
+ cacheMatchedByName = potentials[0];
2583
+
2584
+ Util.logger.info(
2585
+ Util.getGrayMsg(
2586
+ ` - found ${this.definition.type} ${metadataItem[this.definition.keyField]} in cache by name "${metadataItem[this.definition.nameField]}" and folder "${deployFolderPath}": ${cacheMatchedByName[this.definition.keyField]}`
2587
+ )
2588
+ );
2589
+ } else {
2590
+ const cacheFolderPath = cache.searchForField(
2591
+ 'folder',
2592
+ potentials[0].category.id,
2593
+ 'ID',
2594
+ 'Path'
2595
+ );
2596
+ throw new Error(
2597
+ `found ${this.definition.type} ${metadataItem[this.definition.keyField]} in cache by name "${metadataItem[this.definition.nameField]}" but in different folders: "${deployFolderPath}" vs "${cacheFolderPath}": ${potentials[0][this.definition.keyField]}`
2598
+ );
2599
+ }
2600
+ } else {
2601
+ Util.logger.debug(
2602
+ ` - no name-match found for ${this.definition.type} ${metadataItem[this.definition.keyField]}. Creating new asset instead.`
2603
+ );
2604
+ }
2605
+ }
2606
+ return cacheMatchedByName;
2607
+ }
2542
2608
  }
2543
2609
 
2544
2610
  // Assign definition to static attributes
@@ -331,10 +331,7 @@ class Folder extends MetadataType {
331
331
  }
332
332
  }
333
333
  } catch (ex) {
334
- Util.logger.errorStack(
335
- ex,
336
- `Upserting ${this.definition.type} failed: ${ex.message}`
337
- );
334
+ Util.logger.errorStack(ex, `Upserting ${this.definition.type} failed`);
338
335
  }
339
336
  }
340
337
  }
@@ -431,10 +428,16 @@ class Folder extends MetadataType {
431
428
  * @returns {Promise.<any>} Promise of api response
432
429
  */
433
430
  static async update(metadataEntry) {
431
+ if (metadataEntry?.ParentFolder?.ID === 0) {
432
+ Util.logger.debug(
433
+ `${this.definition.type}-${metadataEntry.ContentType}.create:: Cannot create Root Folder: ${metadataEntry.Name}`
434
+ );
435
+ return {};
436
+ }
434
437
  const path = metadataEntry.Path;
435
438
  try {
436
439
  const response = await super.updateSOAP(metadataEntry, true);
437
- if (response) {
440
+ if (response.Results?.[0]?.StatusCode === 'OK') {
438
441
  response.Results[0].Object = metadataEntry;
439
442
  response.Results[0].Object.CustomerKey = metadataEntry.CustomerKey;
440
443
  delete response.Results[0].Object.$;
@@ -488,9 +491,14 @@ class Folder extends MetadataType {
488
491
  );
489
492
  return;
490
493
  }
491
- // retreive ID based on the matching Path of the parent folder
494
+ // retrieve ID based on the matching Path of the parent folder
492
495
  else if (metadata?.ParentFolder?.Path) {
493
- metadata.ParentFolder.ID = cache.getFolderId(metadata.ParentFolder.Path);
496
+ // do not allow mapping folders to other BUs during deploy
497
+ metadata.ParentFolder.ID = cache.getFolderId(
498
+ metadata.ParentFolder.Path,
499
+ undefined,
500
+ false
501
+ );
494
502
  return metadata;
495
503
  } else {
496
504
  Util.metadataLogger(
@@ -545,13 +545,6 @@ class Journey extends MetadataType {
545
545
  );
546
546
  delete configurationArguments.triggeredSendKey;
547
547
  }
548
- if (
549
- configurationArguments.triggeredSendKey &&
550
- configurationArguments.triggeredSend
551
- ) {
552
- // assumption is, that this stores potentially outdated triggeredSend info from the first version of the journey
553
- delete configurationArguments.triggeredSend;
554
- }
555
548
  } catch (ex) {
556
549
  Util.logger.warn(
557
550
  ` - ${this.definition.type} '${metadata[this.definition.nameField]}' (${
@@ -1315,6 +1308,8 @@ class Journey extends MetadataType {
1315
1308
  if (cachedVersion.status === 'Draft') {
1316
1309
  // add version to ensure we update the correct one
1317
1310
  metadataMap[metadataKey].version = cachedVersion.version;
1311
+ // update modifiedDate field to bypass API-error "Another user recently modified this journey. Refresh to edit the latest version."
1312
+ metadataMap[metadataKey].modifiedDate = cachedVersion.modifiedDate;
1318
1313
  } else {
1319
1314
  // remove last entry from metadataToUpdate again
1320
1315
  metadataToUpdate.pop();
@@ -1655,7 +1650,7 @@ class Journey extends MetadataType {
1655
1650
  messages[type].push(
1656
1651
  ` #${counter++}`,
1657
1652
  ` Code: ${msg.errorCode}`,
1658
- ` Details: ${msg.errorDetail}`
1653
+ ` Details: ${msg.errorDetail.split(' EmailID: ').join('\n EmailID: ').split(' Personalization error: ').join('\n Personalization error: ')}`
1659
1654
  );
1660
1655
  if (msg.additionalInfo && Object.keys(msg.additionalInfo).length) {
1661
1656
  messages[type].push(` Additional Info:`);
@@ -549,7 +549,10 @@ class MetadataType {
549
549
  } catch (ex) {
550
550
  if (ex.code !== 200) {
551
551
  // dont print error if we simply did not find relevant content blocks
552
- Util.logger.errorStack(ex, ex.message);
552
+ Util.logger.errorStack(
553
+ ex,
554
+ 'issue with ' + this.definition.type + ' ' + key
555
+ );
553
556
  }
554
557
  if (!findAssetKeys) {
555
558
  Util.logger.info(
@@ -626,17 +629,19 @@ class MetadataType {
626
629
  * test if metadata was actually changed or not to potentially skip it during deployment
627
630
  *
628
631
  * @param {MetadataTypeItem} cachedVersion cached version from the server
629
- * @param {MetadataTypeItem} metadata item to upload
632
+ * @param {MetadataTypeItem} metadataItem item to upload
630
633
  * @param {string} [fieldName] optional field name to use for identifying the record in logs
631
634
  * @param {boolean} [silent] optionally suppress logging
632
635
  * @returns {boolean} true on first identified deviation or false if none are found
633
636
  */
634
- static hasChangedGeneric(cachedVersion, metadata, fieldName, silent) {
637
+ static hasChangedGeneric(cachedVersion, metadataItem, fieldName, silent) {
635
638
  if (!cachedVersion) {
636
639
  return true;
637
640
  }
638
641
  // we do need the full set in other places and hence need to work with a clone here
639
- const clonedMetada = structuredClone(metadata);
642
+ const clonedMetada = structuredClone(metadataItem);
643
+ // keep copy of identifier in case it is among the non-updateable fields
644
+ const identifier = clonedMetada[fieldName || this.definition.keyField];
640
645
  this.removeNotUpdateableFields(clonedMetada);
641
646
  // iterate over what we want to upload rather than what we cached to avoid false positives
642
647
  for (const prop in clonedMetada) {
@@ -652,7 +657,7 @@ class MetadataType {
652
657
  if (clonedMetada[prop] != cachedVersion[prop]) {
653
658
  Util.logger.debug(
654
659
  `${this.definition.type}:: ${
655
- clonedMetada[fieldName || this.definition.keyField]
660
+ identifier
656
661
  }.${prop} changed: '${cachedVersion[prop]}' to '${clonedMetada[prop]}'`
657
662
  );
658
663
  return true;
@@ -661,7 +666,7 @@ class MetadataType {
661
666
  // test complex objects here
662
667
  Util.logger.debug(
663
668
  `${this.definition.type}:: ${
664
- clonedMetada[fieldName || this.definition.keyField]
669
+ identifier
665
670
  }.${prop} changed: '${cachedVersion[prop]}' to '${clonedMetada[prop]}'`
666
671
  );
667
672
  return true;
@@ -669,8 +674,8 @@ class MetadataType {
669
674
  }
670
675
  if (!silent) {
671
676
  Util.logger.verbose(
672
- ` ☇ skipping ${this.definition.type} ${clonedMetada[this.definition.keyField]} / ${
673
- clonedMetada[fieldName || this.definition.nameField]
677
+ ` ☇ skipping ${this.definition.type} ${identifier} / ${
678
+ clonedMetada[this.definition.nameField] || ''
674
679
  }: no change detected`
675
680
  );
676
681
  }
@@ -702,10 +707,13 @@ class MetadataType {
702
707
  // do this in case something went wrong during pre-deploy steps to ensure the total counter is correct
703
708
  hasError = true;
704
709
  deployableMetadata = metadataMap[metadataKey];
705
- Util.logger.error(
710
+
711
+ // * include ": ${ex.message}" in the error if this is ever turned back into Util.logger.error()
712
+ Util.logger.errorStack(
713
+ ex,
706
714
  ` ☇ skipping ${this.definition.type} ${
707
715
  deployableMetadata[this.definition.keyField]
708
- } / ${deployableMetadata[this.definition.nameField]}: ${ex.message}`
716
+ } / ${deployableMetadata[this.definition.nameField]}`
709
717
  );
710
718
  }
711
719
  // if preDeploy returns nothing then it cannot be deployed so skip deployment
@@ -723,10 +731,7 @@ class MetadataType {
723
731
  filteredByPreDeploy++;
724
732
  }
725
733
  } catch (ex) {
726
- Util.logger.errorStack(
727
- ex,
728
- `Upserting ${this.definition.type} failed: ${ex.message}`
729
- );
734
+ Util.logger.errorStack(ex, `Upserting ${this.definition.type} failed`);
730
735
  }
731
736
  }
732
737
  const createLimit = pLimit(10);
@@ -827,6 +832,11 @@ class MetadataType {
827
832
 
828
833
  normalizedKey = File.reverseFilterIllegalFilenames(newKey);
829
834
  }
835
+ const cacheMatchedByKey = cache.getByKey(this.definition.type, normalizedKey);
836
+ const cacheMatchedByName = cacheMatchedByKey
837
+ ? null
838
+ : this.getCacheMatchedByName(metadataMap[metadataKey]);
839
+
830
840
  if (
831
841
  Util.logger.level === 'debug' &&
832
842
  metadataMap[metadataKey][this.definition.idField] &&
@@ -849,9 +859,9 @@ class MetadataType {
849
859
  });
850
860
  return 'update';
851
861
  }
852
- } else if (cache.getByKey(this.definition.type, normalizedKey)) {
862
+ } else if (cacheMatchedByKey || cacheMatchedByName) {
853
863
  // normal way of processing update files
854
- const cachedVersion = cache.getByKey(this.definition.type, normalizedKey);
864
+ const cachedVersion = cacheMatchedByKey || cacheMatchedByName;
855
865
  if (!this.hasChanged(cachedVersion, metadataMap[metadataKey])) {
856
866
  hasError = true;
857
867
  }
@@ -1002,6 +1012,17 @@ class MetadataType {
1002
1012
  }
1003
1013
  }
1004
1014
 
1015
+ /**
1016
+ * helper for {@link MetadataType.createOrUpdate}
1017
+ *
1018
+ * @param {MetadataTypeItem} metadataItem to be deployed item
1019
+ * @returns {MetadataTypeItem} cached item or undefined
1020
+ */
1021
+ static getCacheMatchedByName(metadataItem) {
1022
+ // not supported generically
1023
+ return null;
1024
+ }
1025
+
1005
1026
  /**
1006
1027
  * Creates a single metadata entry via REST
1007
1028
  *
@@ -9,6 +9,7 @@ export default {
9
9
  keyIsFixed: false,
10
10
  keyField: 'customerKey',
11
11
  nameField: 'name',
12
+ folderIdField: 'category.id',
12
13
  createdDateField: 'createdDate',
13
14
  createdNameField: 'createdBy.name',
14
15
  lastmodDateField: 'modifiedDate',
@@ -20,6 +21,7 @@ export default {
20
21
  typeRetrieveByDefault: ['asset', 'code', 'textfile', 'block', 'message', 'template', 'other'],
21
22
  typeName: 'Asset-[Subtype]',
22
23
  stringifyFieldsBeforeTemplate: ['memberId', 'enterpriseId'],
24
+ allowMatchingByName: true,
23
25
  fields: {
24
26
  activeDate: {
25
27
  isCreateable: false,
@@ -263,14 +263,14 @@ export default {
263
263
  template: true,
264
264
  },
265
265
  'configurationArguments.relatedObjectFilterCriteria': {
266
- isCreateable: false,
267
- isUpdateable: false,
266
+ isCreateable: true,
267
+ isUpdateable: true,
268
268
  retrieving: true,
269
269
  template: true,
270
270
  },
271
271
  'configurationArguments.relatedObjectFilterSummary': {
272
- isCreateable: false,
273
- isUpdateable: false,
272
+ isCreateable: true,
273
+ isUpdateable: true,
274
274
  retrieving: true,
275
275
  template: true,
276
276
  },