diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index ca20c5d90..8a8030911 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -195,6 +195,9 @@ Provides default functionality that can be overwritten by child metadata type cl
Mcdev.(selectedType, buObject)Array.<string>

helper for Mcdev.#runOnBU

+
Mcdev.(cred, bu, type, [keyArr])Promise.<Array.<string>>
+

Updates the key to match the name field

+
Automation.(metadata)boolean

helper for postRetrieveTasks and execute

@@ -519,7 +522,7 @@ main class * [.schedule(businessUnit, [selectedType], [keys])](#Mcdev.schedule) ⇒ Promise.<Object.<string, Array.<string>>> * [.execute(businessUnit, [selectedType], [keys])](#Mcdev.execute) ⇒ Promise.<Object.<string, Array.<string>>> * [.pause(businessUnit, [selectedType], [keys])](#Mcdev.pause) ⇒ Promise.<Object.<string, Array.<string>>> - * [.fixKeys(businessUnit, type, [keys])](#Mcdev.fixKeys) ⇒ Promise.<Object.<string, Array.<string>>> + * [.fixKeys(businessUnit, selectedType, [keys])](#Mcdev.fixKeys) ⇒ Promise.<Object.<string, Array.<string>>> @@ -815,16 +818,16 @@ pause an item -### Mcdev.fixKeys(businessUnit, type, [keys]) ⇒ Promise.<Object.<string, Array.<string>>> +### Mcdev.fixKeys(businessUnit, selectedType, [keys]) ⇒ Promise.<Object.<string, Array.<string>>> Updates the key to match the name field **Kind**: static method of [Mcdev](#Mcdev) -**Returns**: Promise.<Object.<string, Array.<string>>> - key: business unit name, value: list of affected item keys +**Returns**: Promise.<Object.<string, Array.<string>>> - key: business unit name, value: list of paused item keys | Param | Type | Description | | --- | --- | --- | | businessUnit | string | name of BU | -| type | TYPE.SupportedMetadataTypes | limit execution to given metadata type | +| selectedType | TYPE.SupportedMetadataTypes | limit to given metadata types | | [keys] | Array.<string> | customerkey of the metadata | @@ -8383,7 +8386,7 @@ run a method across BUs | Param | Type | Description | | --- | --- | --- | -| methodName | 'execute' \| 'pause' | what to run | +| methodName | 'execute' \| 'pause' \| 'fixKeys' | what to run | | businessUnit | string | name of BU | | [selectedType] | TYPE.SupportedMetadataTypes | limit to given metadata types | | [keys] | Array.<string> | customerkey of the metadata | @@ -8398,7 +8401,7 @@ helper for [Mcdev.#runMethod](Mcdev.#runMethod) | Param | Type | Description | | --- | --- | --- | -| methodName | 'execute' \| 'pause' | what to run | +| methodName | 'execute' \| 'pause' \| 'fixKeys' | what to run | | cred | string | name of Credential | | bu | string | name of BU | | [type] | TYPE.SupportedMetadataTypes | limit execution to given metadata type | @@ -8417,6 +8420,21 @@ helper for [Mcdev.#runOnBU](Mcdev.#runOnBU) | selectedType | TYPE.SupportedMetadataTypes | limit execution to given metadata type | | buObject | TYPE.BuObject | properties for auth | + + +## Mcdev.(cred, bu, type, [keyArr]) ⇒ Promise.<Array.<string>> +Updates the key to match the name field + +**Kind**: global function +**Returns**: Promise.<Array.<string>> - list of keys that were affected + +| Param | Type | Description | +| --- | --- | --- | +| cred | string | name of Credential | +| bu | string | name of BU | +| type | TYPE.SupportedMetadataTypes | limit execution to given metadata type | +| [keyArr] | Array.<string> | customerkey of the metadata | + ## Automation.(metadata) ⇒ boolean diff --git a/lib/index.js b/lib/index.js index 564193366..80d9b80f4 100644 --- a/lib/index.js +++ b/lib/index.js @@ -774,10 +774,21 @@ class Mcdev { static async pause(businessUnit, selectedType, keys) { return this.#runMethod('pause', businessUnit, selectedType, keys); } + /** + * Updates the key to match the name field + * + * @param {string} businessUnit name of BU + * @param {TYPE.SupportedMetadataTypes} selectedType limit to given metadata types + * @param {string[]} [keys] customerkey of the metadata + * @returns {Promise.>} key: business unit name, value: list of paused item keys + */ + static async fixKeys(businessUnit, selectedType, keys) { + return this.#runMethod('fixKeys', businessUnit, selectedType, keys); + } /** * run a method across BUs * - * @param {'execute'|'pause'} methodName what to run + * @param {'execute'|'pause'|'fixKeys'} methodName what to run * @param {string} businessUnit name of BU * @param {TYPE.SupportedMetadataTypes} [selectedType] limit to given metadata types * @param {string[]} [keys] customerkey of the metadata @@ -788,6 +799,7 @@ class Mcdev { let lang_past; let lang_present; let requireKeyOrLike; + let checkMetadataSupport; const resultObj = {}; switch (methodName) { @@ -795,12 +807,21 @@ class Mcdev { lang_past = 'executed'; lang_present = 'executing'; requireKeyOrLike = true; + checkMetadataSupport = true; break; } case 'pause': { lang_past = 'paused'; lang_present = 'pausing'; requireKeyOrLike = true; + checkMetadataSupport = true; + break; + } + case 'fixKeys': { + lang_past = 'fixed keys'; + lang_present = 'fixing keys'; + requireKeyOrLike = false; + checkMetadataSupport = false; break; } } @@ -808,6 +829,7 @@ class Mcdev { Util.logger.info(`mcdev:: ${methodName} ${selectedType}`); const properties = await config.getProperties(); let counter_credBu = 0; + let counter_credKeys = 0; if (!(await config.checkProperties(properties))) { // return null here to avoid seeing 2 error messages for the same issue return resultObj; @@ -815,7 +837,10 @@ class Mcdev { if (!Util._isValidType(selectedType)) { return resultObj; } - if (!Object.prototype.hasOwnProperty.call(MetadataTypeInfo[selectedType], methodName)) { + if ( + checkMetadataSupport && + !Object.prototype.hasOwnProperty.call(MetadataTypeInfo[selectedType], methodName) + ) { Util.logger.error( ` ☇ skipping ${selectedType}: ${methodName} is not supported yet for ${selectedType}` ); @@ -847,6 +872,7 @@ class Mcdev { for (const cred in properties.credentials) { Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`); // reset counter per cred + counter_credKeys = 0; counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { resultObj[cred + '/' + bu] = await this.#runOnBU( @@ -857,11 +883,12 @@ class Mcdev { keys ); counter_credBu++; + counter_credKeys += resultObj[cred + '/' + bu].length; Util.startLogger(true); } counter_credTotal += counter_credBu; Util.logger.info( - `:: ${lang_past} ${selectedType} on ${counter_credBu} BUs for ${cred}` + `:: ${lang_past} for ${counter_credKeys} ${selectedType}s on ${counter_credBu} BUs for ${cred}` ); } Util.logger.info( @@ -899,10 +926,11 @@ class Mcdev { keys ); counter_credBu++; + counter_credKeys += resultObj[cred + '/' + bu].length; Util.startLogger(true); } Util.logger.info( - `:: ${lang_past} ${selectedType} on ${counter_credBu} BUs for ${cred}` + `:: ${lang_past} for ${counter_credKeys} ${selectedType}s on ${counter_credBu} BUs for ${cred}` ); } else { // execute runMethod for the entity on one BU only @@ -921,7 +949,7 @@ class Mcdev { /** * helper for {@link Mcdev.#runMethod} * - * @param {'execute'|'pause'} methodName what to run + * @param {'execute'|'pause'|'fixKeys'} methodName what to run * @param {string} cred name of Credential * @param {string} bu name of BU * @param {TYPE.SupportedMetadataTypes} [type] limit execution to given metadata type @@ -948,18 +976,27 @@ class Mcdev { } Util.logger.info(`:: ${methodName} ${type} on ${cred}/${bu}`); MetadataTypeInfo[type].client = auth.getSDK(buObject); - if (Util.OPTIONS.like && Object.keys(Util.OPTIONS.like).length) { - keyArr = await this.#retrieveKeysWithLike(type, buObject); - } else { - MetadataTypeInfo[type].properties = properties; - MetadataTypeInfo[type].buObject = buObject; - } - if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) { - throw new Error('No keys were provided'); - } - // result will be undefined (false) if methodName is not supported for the type - resultArr.push(...(await MetadataTypeInfo[type][methodName](keyArr))); + MetadataTypeInfo[type].properties = properties; + MetadataTypeInfo[type].buObject = buObject; + switch (methodName) { + case 'fixKeys': { + { + resultArr.push(...(await this.#fixKeys(cred, bu, type, keyArr))); + + break; + } + } + default: { + if (Util.OPTIONS.like && Object.keys(Util.OPTIONS.like).length) { + keyArr = await this.#retrieveKeysWithLike(type, buObject); + } + if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) { + throw new Error('No keys were provided'); + } // result will be undefined (false) if methodName is not supported for the type + resultArr.push(...(await MetadataTypeInfo[type][methodName](keyArr))); + } + } } catch (ex) { Util.logger.errorStack(ex, 'mcdev.' + methodName + ' failed'); } @@ -1025,7 +1062,7 @@ class Mcdev { Util.getGrayMsg( `Identified ${keyArr.length} ${selectedType}${ keyArr.length === 1 ? '' : 's' - } that match${selectedType}${keyArr.length === 1 ? 'es' : ''} the like-filter` + } that match${keyArr.length === 1 ? 'es' : ''} the like-filter` ) ); @@ -1034,34 +1071,24 @@ class Mcdev { /** * Updates the key to match the name field * - * @param {string} businessUnit name of BU + * @param {string} cred name of Credential + * @param {string} bu name of BU * @param {TYPE.SupportedMetadataTypes} type limit execution to given metadata type - * @param {string[]} [keys] customerkey of the metadata - * @returns {Promise.>} key: business unit name, value: list of affected item keys + * @param {string[]} [keyArr] customerkey of the metadata + * @returns {Promise.} list of keys that were affected */ - static async fixKeys(businessUnit, type, keys) { - Util.startLogger(); - Util.logger.info('mcdev:: fixKeys'); - let actuallyFixedKeys = []; - const result = {}; - result[businessUnit] = actuallyFixedKeys; + static async #fixKeys(cred, bu, type, keyArr) { const properties = await config.getProperties(); - if (!(await config.checkProperties(properties))) { - // return null here to avoid seeing 2 error messages for the same issue - return result; - } - if (!type || !Util._isValidType(type)) { - return result; - } + let actuallyFixedKeys = []; + const resultArr = []; if ( MetadataTypeDefinitions[type].keyIsFixed === true || MetadataTypeDefinitions[type].keyField === MetadataTypeDefinitions[type].idField ) { Util.logger.error(`Key cannot be updated for this type`); - return result; + return resultArr; } - let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; const buObject = await Cli.getCredentialObject( properties, @@ -1069,42 +1096,26 @@ class Mcdev { null, true ); - if (buObject !== null) { - cache.initCache(buObject); - cred = buObject.credential; - bu = buObject.businessUnit; - } - Util.logger.info( - `Updating keys for ${type} on ${cred}/${bu}` + - (keys ? Util.getKeysString(keys) : '') + - `\n` - ); - try { - MetadataTypeInfo[type].client = auth.getSDK(buObject); - } catch (ex) { - Util.logger.error(ex.message); - return result; - } try { Util.logger.info(`Retrieving latest versions of ${type} from server`); const retriever = new Retriever(properties, buObject); - const retrieved = await retriever.retrieve([type], keys, null, false); + const retrieved = await retriever.retrieve([type], keyArr, null, false); const metadataMap = Object.values(retrieved)[0][0]; const keysForDeploy = MetadataTypeInfo[type].getKeysForFixing(metadataMap); if (keysForDeploy.length < 1) { Util.logger.error( - `No items found with a key-name mismatch that match your criteria.` + `No items found with a key-name mismatch that match your criteria.\n` ); - return result; + return resultArr; } this.setOptions({ changeKeyField: MetadataTypeDefinitions[type].nameField, fromRetrieve: true, }); - const deployed = await Deployer.deploy(businessUnit, [type], keysForDeploy); + const deployed = await Deployer.deploy(cred + '/' + bu, [type], keysForDeploy); actuallyFixedKeys = Object.keys(Object.values(Object.values(deployed)[0])[0]); - result[cred + '/' + bu] = actuallyFixedKeys; + resultArr.push(...actuallyFixedKeys); const dependentTypes = await Util.getDependentMetadata(type); if (actuallyFixedKeys && actuallyFixedKeys.length) { Util.logger.info( @@ -1124,7 +1135,7 @@ class Mcdev { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } Util.logger.info(`:: Done\n`); - return result; + return resultArr; } } diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index ec2bcc3e7..d7ec522bc 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -891,13 +891,8 @@ class Automation extends MetadataType { if (!metadataMap[key].type) { // create response does not return the type attribute - // el.schedule.timezoneName const scheduleHelper = metadataMap[key].schedule || metadataMap[key].startSource.schedule; - scheduleHelper.timezoneName ||= Util.inverseGet( - this.definition.timeZoneMapping, - scheduleHelper.timezoneId - ); // el.type metadataMap[key].type = scheduleHelper @@ -906,6 +901,15 @@ class Automation extends MetadataType { ? 'triggered' : undefined; + // el.schedule.timezoneName + if (metadataMap[key].type === 'scheduled') { + // not existing for triggered automations + scheduleHelper.timezoneName ||= Util.inverseGet( + this.definition.timeZoneMapping, + scheduleHelper.timezoneId + ); + } + // el.status metadataMap[key].status ||= Util.inverseGet( this.definition.statusMapping, diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 326a2a43a..646a30350 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -2082,9 +2082,11 @@ class MetadataType { ); } else { Util.logger.info( - ` ☇ skipping ${this.definition.type} ${ - item[this.definition.keyField] - }: key does not need to be updated` + Util.getGrayMsg( + ` ☇ skipping ${this.definition.type} ${ + item[this.definition.keyField] + }: key does not need to be updated` + ) ); } } diff --git a/test/type.query.test.js b/test/type.query.test.js index 401c2608e..5e8bcb4d8 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -321,7 +321,7 @@ describe('type: query', () => { ); return; }); - it('Should not fixKeys and deploy', async () => { + it('Should NOT fixKeys and deploy', async () => { // WHEN const resultFixKeys = await handler.fixKeys('testInstance/testBU', 'query', [ 'testExisting_query', @@ -391,7 +391,7 @@ describe('type: query', () => { }); it('Should fixKeys and deploy via --like', async () => { // WHEN - handler.setOptions({ like: { key: 'testExisting_query%' } }); + handler.setOptions({ like: { key: 'testExisting_query_f%' } }); const resultFixKeys = await handler.fixKeys('testInstance/testBU', 'query'); assert.equal( resultFixKeys['testInstance/testBU'].length,