diff --git a/lib/metadataTypes/Filter.js b/lib/metadataTypes/Filter.js index b45000ff4..c26e25a19 100644 --- a/lib/metadataTypes/Filter.js +++ b/lib/metadataTypes/Filter.js @@ -20,6 +20,7 @@ const MetadataType = require('./MetadataType'); const Util = require('../util/util'); +const cache = require('../util/cache'); const dataTypes = { 1: 'List', @@ -60,8 +61,7 @@ class Filter extends MetadataType { static parseMetadata(metadata) { try { // folder - metadata.r__folder_Path = Util.getFromCache( - this.cache, + metadata.r__folder_Path = cache.searchForField( 'folder', metadata.categoryId, 'ID', @@ -70,8 +70,7 @@ class Filter extends MetadataType { delete metadata.categoryId; // filterDefinition - metadata.r__filterDefinition_CustomerKey = Util.getFromCache( - this.cache, + metadata.r__filterDefinition_CustomerKey = cache.searchForField( 'filterDefinition', metadata.filterDefinitionId, 'id', @@ -84,8 +83,7 @@ class Filter extends MetadataType { // list } else if (metadata.sourceTypeId === 2) { // dataExtension - metadata.r__source_dataExtension_CustomerKey = Util.getFromCache( - this.cache, + metadata.r__source_dataExtension_CustomerKey = cache.searchForField( 'dataExtension', metadata.sourceObjectId, 'ObjectID', @@ -94,7 +92,7 @@ class Filter extends MetadataType { delete metadata.sourceObjectId; delete metadata.sourceTypeId; } else { - Util.logger.error( + Util.logger.warn( `Filter '${metadata.name}' (${metadata.customerKey}): Unsupported source type ${ metadata.sourceTypeId }=${dataTypes[metadata.sourceTypeId]}` @@ -106,8 +104,7 @@ class Filter extends MetadataType { // list } else if (metadata.destinationTypeId === 2) { // dataExtension - metadata.r__destination_dataExtension_CustomerKey = Util.getFromCache( - this.cache, + metadata.r__destination_dataExtension_CustomerKey = cache.searchForField( 'dataExtension', metadata.destinationObjectId, 'ObjectID', @@ -116,7 +113,7 @@ class Filter extends MetadataType { delete metadata.destinationObjectId; delete metadata.destinationTypeId; } else { - Util.logger.error( + Util.logger.warn( `Filter '${metadata.name}' (${ metadata.customerKey }): Unsupported destination type ${metadata.destinationTypeId}=${ @@ -125,7 +122,7 @@ class Filter extends MetadataType { ); } } catch (ex) { - Util.logger.error(`Filter '${metadata.name}' (${metadata.customerKey}): ${ex.message}`); + Util.logger.warn(`Filter '${metadata.name}' (${metadata.customerKey}): ${ex.message}`); } return metadata; } @@ -137,8 +134,7 @@ class Filter extends MetadataType { static async preDeployTasks(metadata) { // folder if (metadata.r__folder_Path) { - metadata.categoryId = Util.getFromCache( - this.cache, + metadata.categoryId = cache.searchForField( 'folder', metadata.r__folder_Path, 'Path', @@ -149,8 +145,7 @@ class Filter extends MetadataType { // filterDefinition if (metadata.r__filterDefinition_CustomerKey) { - metadata.filterDefinitionId = Util.getFromCache( - this.cache, + metadata.filterDefinitionId = cache.searchForField( 'filterDefinition', metadata.r__filterDefinition_CustomerKey, 'CustomerKey', @@ -164,8 +159,7 @@ class Filter extends MetadataType { // list } else if (metadata.r__source_dataExtension_CustomerKey) { // dataExtension - metadata.sourceObjectId = Util.getFromCache( - this.cache, + metadata.sourceObjectId = cache.searchForField( 'dataExtension', metadata.r__source_dataExtension_CustomerKey, 'CustomerKey', @@ -187,8 +181,7 @@ class Filter extends MetadataType { // list } else if (metadata.r__destination_dataExtension_CustomerKey) { // dataExtension - metadata.destinationObjectId = Util.getFromCache( - this.cache, + metadata.destinationObjectId = cache.searchForField( 'dataExtension', metadata.r__destination_dataExtension_CustomerKey, 'CustomerKey', diff --git a/lib/metadataTypes/FilterDefinition.js b/lib/metadataTypes/FilterDefinition.js index 2eeadd855..51abe9516 100644 --- a/lib/metadataTypes/FilterDefinition.js +++ b/lib/metadataTypes/FilterDefinition.js @@ -84,7 +84,8 @@ const MetadataType = require('./MetadataType'); const Util = require('../util/util'); -const xml2js = require('xml2js'); +const cache = require('../util/cache'); +const { XMLBuilder, XMLParser } = require('fast-xml-parser'); /** * FilterDefinition MetadataType @@ -99,52 +100,51 @@ class FilterDefinition extends MetadataType { static async retrieve(retrieveDir) { // #1 get the list via SOAP cause the corresponding REST call has no BU filter apparently // for reference the rest path: '/automation/v1/filterdefinitions?view=categoryinfo' - const keyFieldBak = this.definition.keyField; + const soapFields = ['DataFilter', 'ObjectID', 'CustomerKey', 'Description', 'Name']; - this.definition.keyField = 'CustomerKey'; /** * @type {FilterDefinitionSOAPItemMap[]} */ - const responseObject = await this.retrieveSOAPBody(soapFields); + const responseSOAP = await this.client.soap.retrieveBulk(this.definition.type, soapFields); + console.log('responseSOAP', responseSOAP); + + // backup REST value of the keyField + const keyFieldBak = this.definition.keyField; + this.definition.keyField = 'CustomerKey'; + const responseSOAPMap = this.parseResponseBody(responseSOAP); + // restore the keyField to its REST value this.definition.keyField = keyFieldBak; + console.log('responseSOAPMap', responseSOAPMap); - // convert back to array /** * @type {FilterDefinitionSOAPItem[]} */ - const listResponse = Object.keys(responseObject) - .map((key) => responseObject[key]) - .filter((item) => { - if (item.ObjectState) { - Util.logger.debug( - `Filtered filterDefinition ${item.name}: ${item.ObjectState}` - ); - return false; - } else { - return true; - } - }); + const responseSOAPList = responseSOAP.Results.filter((item) => { + if (item.ObjectState) { + Util.logger.debug(`Filtered filterDefinition ${item.name}: ${item.ObjectState}`); + return false; + } else { + return true; + } + }); // #2 // /automation/v1/filterdefinitions/ - const response = ( + const responseREST = ( await Promise.all( - listResponse.map((item) => - this.client.RestClient.get({ - uri: '/email/v1/filters/filterdefinition/' + item.ObjectID, - }) + responseSOAPList.map((item) => + this.client.rest.get('/email/v1/filters/filterdefinition/' + item.ObjectID) ) ) - ) - .map((item) => item.body) - .map((item) => { - // description is not returned when empty - item.description = item.description || ''; - // add extra info from XML - item.c__soap_DataFilter = responseObject[item.key].DataFilter; - return item; - }); - const results = this.parseResponseBody({ Results: response }); + ).map((item) => { + // description is not returned when empty + item.description = item.description || ''; + // add extra info from XML + item.c__soap_DataFilter = responseSOAPMap[item.key].DataFilter; + return item; + }); + console.log('responseREST', responseREST); + const results = this.parseResponseBody({ Results: responseREST }); if (retrieveDir) { const savedMetadata = await this.saveResults(results, retrieveDir, null, null); Util.logger.info( @@ -153,8 +153,6 @@ class FilterDefinition extends MetadataType { } return { metadata: results, type: this.definition.type }; - - // return super.retrieveSOAPgeneric(retrieveDir); } /** * Retrieves all records for caching @@ -180,8 +178,7 @@ class FilterDefinition extends MetadataType { static async parseMetadata(metadata) { try { // folder - metadata.r__folder_Path = Util.getFromCache( - this.cache, + metadata.r__folder_Path = cache.searchForField( 'folder', metadata.categoryId, 'ID', @@ -191,19 +188,20 @@ class FilterDefinition extends MetadataType { if (metadata.derivedFromType === 2) { // DataExtension - metadata.r__dataExtension_CustomerKey = Util.getFromCache( - this.cache, + metadata.r__dataExtension_CustomerKey = cache.searchForField( 'dataExtension', metadata.derivedFromObjectId, 'ObjectID', 'CustomerKey' ); } + metadata.del__derivedFromObjectId = metadata.derivedFromObjectId; // TEMP for DEBUGGING / remove before release + metadata.del__derivedFromType = metadata.derivedFromType; // TEMP for DEBUGGING / remove before release delete metadata.derivedFromObjectId; delete metadata.derivedFromType; - metadata.c__filterDefinition = await xml2js.parseStringPromise( - metadata.filterDefinitionXml /* , options */ - ); + + const xmlToJson = new XMLParser({ ignoreAttributes: false }); + metadata.c__filterDefinition = xmlToJson.parse(metadata.filterDefinitionXml); // TODO check if Condition ID needs to be resolved or can be ignored } catch (ex) { @@ -220,13 +218,7 @@ class FilterDefinition extends MetadataType { */ static async preDeployTasks(metadata) { // folder - metadata.categoryId = Util.getFromCache( - this.cache, - 'folder', - metadata.r__folder_Path, - 'Path', - 'ID' - ); + metadata.categoryId = cache.searchForField('folder', metadata.r__folder_Path, 'Path', 'ID'); delete metadata.r__folder_Path; if (metadata.derivedFromObjectTypeName === 'SubscriberAttributes') { @@ -238,8 +230,7 @@ class FilterDefinition extends MetadataType { metadata.derivedFromType = 2; if (metadata.r__dataExtension_CustomerKey) { - metadata.derivedFromObjectId = Util.getFromCache( - this.cache, + metadata.derivedFromObjectId = cache.searchForField( 'dataExtension', metadata.r__dataExtension_CustomerKey, 'CustomerKey', @@ -248,6 +239,9 @@ class FilterDefinition extends MetadataType { delete metadata.r__dataExtension_CustomerKey; } } + + const jsonToXml = new XMLBuilder({ ignoreAttributes: false }); + metadata.filterDefinitionXml = jsonToXml.build(metadata.c__filterDefinition); delete metadata.c__filterDefinition; delete metadata.c__soap_DataFilter; diff --git a/package-lock.json b/package-lock.json index b7d320163..5bfecead4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "command-exists": "1.2.9", "conf": "10.1.1", "console.table": "0.10.0", + "fast-xml-parser": "4.0.7", "fs-extra": "10.0.1", "inquirer": "8.2.2", "json-to-table": "4.2.1", diff --git a/package.json b/package.json index 9cce2236d..5f57cba68 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "command-exists": "1.2.9", "conf": "10.1.1", "console.table": "0.10.0", + "fast-xml-parser": "4.0.7", "fs-extra": "10.0.1", "inquirer": "8.2.2", "json-to-table": "4.2.1",