Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/1301 no owner check for assets + Task/905 test callout payloads #1308

Merged
merged 10 commits into from
May 8, 2024
19 changes: 12 additions & 7 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,13 @@ yargs(hideBin(process.argv))
alias: 'ks',
group: 'Options for deploy:',
describe:
'allows you to add a suffix to the key of the metadata to be deployed. Only works together with changeKeyField',
'allows you to add a suffix to the key of the metadata to be deployed',
})
.option('noMidSuffix', {
type: 'boolean',
group: 'Options for deploy:',
describe:
'for asset: disables the automatic addition of the MID to the key of the deployed metadata when deploying cross-BU. Should be used with --keySuffix or with templating-based suffixes',
})
.option('changeKeyField', {
type: 'string',
Expand All @@ -112,33 +118,32 @@ yargs(hideBin(process.argv))
type: 'boolean',
alias: 'fr',
group: 'Options for deploy:',
describe: 'optionally deploy from retrieve folder',
describe: 'deploy from retrieve folder',
})
.option('refresh', {
type: 'boolean',
alias: 'r',
group: 'Options for deploy:',
describe:
'optional for asset-message: runs refresh command for related triggeredSends after deploy',
'for asset-message: runs refresh command for related triggeredSends after deploy',
})
.option('execute', {
type: 'boolean',
alias: 'e',
group: 'Options for deploy:',
describe:
'optional: executes item after deploy; this will run the item once immediately',
describe: 'executes item after deploy; this will run the item once immediately',
})
.option('schedule', {
type: 'boolean',
alias: 's',
group: 'Options for deploy:',
describe:
'optionally start existing schedule instead of running item once immediately (only works for automations)',
'start existing schedule instead of running item once immediately (only works for automations)',
})
.option('fixShared', {
group: 'Options for deploy:',
describe:
"optionally ensure that updates to shared DataExtensions become visible in child BU's data designer (SF Known issue W-11031095)",
"ensure that updates to shared DataExtensions become visible in child BU's data designer (SF Known issue W-11031095)",
});
},
handler: (argv) => {
Expand Down
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class Mcdev {
'like',
'noLogColors',
'noLogFile',
'noMidSuffix',
'refresh',
'_runningTest',
'schedule',
Expand Down
1 change: 1 addition & 0 deletions lib/metadataTypes/Asset.js
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ class Asset extends MetadataType {

// only execute #3 if we are deploying / copying from one BU to another, not while using mcdev as a developer tool
if (
!Util.OPTIONS.noMidSuffix &&
this.buObject.mid &&
metadata.memberId !== this.buObject.mid &&
!metadata[this.definition.keyField].endsWith(this.buObject.mid)
Expand Down
76 changes: 61 additions & 15 deletions lib/metadataTypes/MetadataType.js
Original file line number Diff line number Diff line change
Expand Up @@ -683,11 +683,25 @@ class MetadataType {
metadataToUpdate,
metadataToCreate
) {
const normalizedKey = File.reverseFilterIllegalFilenames(
let normalizedKey = File.reverseFilterIllegalFilenames(
metadataMap[metadataKey][this.definition.keyField]
);

// Update if it already exists; Create it if not
const maxKeyLength = this.definition.maxKeyLength || 36;

// make sure keySuffix always has a string value
Util.OPTIONS.keySuffix = Util.OPTIONS.keySuffix ? Util.OPTIONS.keySuffix.trim() : '';
if (Util.OPTIONS.keySuffix && !cache.getByKey(this.definition.type, normalizedKey)) {
// to ensure we go into update mode like we would with appending the MID to asset-keys, recreated the normalized key here
const newKey = this.getNewKey(
this.definition.keyField,
metadataMap[metadataKey],
maxKeyLength
);

normalizedKey = File.reverseFilterIllegalFilenames(newKey);
}
if (
Util.logger.level === 'debug' &&
metadataMap[metadataKey][this.definition.idField] &&
Expand Down Expand Up @@ -716,6 +730,7 @@ class MetadataType {
if (!this.hasChanged(cachedVersion, metadataMap[metadataKey])) {
hasError = true;
}

if (Util.OPTIONS.changeKeyField) {
if (this.definition.keyField == this.definition.idField) {
Util.logger.error(
Expand All @@ -738,10 +753,11 @@ class MetadataType {
` - --changeKeyField is set to the same value as the keyField for ${this.definition.type}. Skipping change.`
);
} else if (metadataMap[metadataKey][Util.OPTIONS.changeKeyField]) {
Util.OPTIONS.keySuffix = Util.OPTIONS.keySuffix
? Util.OPTIONS.keySuffix.trim()
: '';
const newKey = this.getNewKey(metadataMap[metadataKey], maxKeyLength);
const newKey = this.getNewKey(
Util.OPTIONS.changeKeyField,
metadataMap[metadataKey],
maxKeyLength
);

if (
metadataMap[metadataKey][Util.OPTIONS.changeKeyField] +
Expand Down Expand Up @@ -769,6 +785,9 @@ class MetadataType {
}
}
} else if (Util.OPTIONS.changeKeyValue) {
if (Util.OPTIONS.keySuffix !== '') {
Util.logger.warn(`Ignoring --keySuffix as --changeKeyValue is set.`);
}
// NOTE: trim twice while getting the newKey value to remove leading spaces before limiting the length
const newKey = Util.OPTIONS.changeKeyValue.trim().slice(0, maxKeyLength).trim();
if (Util.OPTIONS.changeKeyValue.trim().length > maxKeyLength) {
Expand Down Expand Up @@ -800,6 +819,21 @@ class MetadataType {
Util.changedKeysMap[this.definition.type] ||= {};
Util.changedKeysMap[this.definition.type][newKey] = metadataKey;
}
} else if (Util.OPTIONS.keySuffix && Util.OPTIONS.keySuffix !== '') {
// assume we simply want to append a suffix
const newKey = this.getNewKey(
this.definition.keyField,
metadataMap[metadataKey],
maxKeyLength
);
Util.logger.info(
` - Changing ${this.definition.type} key from ${metadataKey} to ${newKey} via --keySuffix=${Util.OPTIONS.keySuffix}`
);
metadataMap[metadataKey][this.definition.keyField] = newKey;

// ensure we can delete the old file(s) after the successful update
Util.changedKeysMap[this.definition.type] ||= {};
Util.changedKeysMap[this.definition.type][newKey] = metadataKey;
}

if (hasError) {
Expand All @@ -824,6 +858,19 @@ class MetadataType {
metadataToCreate.push(null);
return 'skip';
} else {
if (Util.OPTIONS.keySuffix && Util.OPTIONS.keySuffix !== '') {
// assume we simply want to append a suffix
const newKey = this.getNewKey(
this.definition.keyField,
metadataMap[metadataKey],
maxKeyLength
);
Util.logger.info(
` - Changing ${this.definition.type} key from ${metadataKey} to ${newKey} via --keySuffix=${Util.OPTIONS.keySuffix}`
);
metadataMap[metadataKey][this.definition.keyField] = newKey;
}

metadataToCreate.push(metadataMap[metadataKey]);
return 'create';
}
Expand Down Expand Up @@ -2188,7 +2235,7 @@ class MetadataType {
}) is too long for a key${Util.OPTIONS.keySuffix.length ? ' (including the suffix ' + Util.OPTIONS.keySuffix + ')' : ''}. Consider renaming your item. Key will be equal first ${maxKeyLength} characters of the name`
);
}
const newKey = this.getNewKey(item, maxKeyLength);
const newKey = this.getNewKey(this.definition.nameField, item, maxKeyLength);
if (newKey != item[this.definition.keyField] && !this.definition.keyIsFixed) {
// add key but make sure to turn it into string or else numeric keys will be filtered later
keysForDeploy.push(item[this.definition.keyField] + '');
Expand All @@ -2214,22 +2261,21 @@ class MetadataType {
/**
* helper for getKeysForFixing and createOrUpdate
*
* @param {string} baseField name of the field to start the new key with
* @param {MetadataTypeItem} metadataItem -
* @param {number} maxKeyLength -
* @returns {string} newKey
*/
static getNewKey(metadataItem, maxKeyLength) {
static getNewKey(baseField, metadataItem, maxKeyLength) {
const keySuffix = Util.OPTIONS.keySuffix;
let newKey;
newKey = (metadataItem[this.definition.nameField] + '')
.trim()
.slice(0, maxKeyLength)
.trim();
if (Util.OPTIONS.keySuffix.length && !newKey.endsWith(Util.OPTIONS.keySuffix)) {
newKey = (metadataItem[baseField] + '').trim().slice(0, maxKeyLength).trim();
if (keySuffix.length && !newKey.endsWith(keySuffix)) {
newKey =
(metadataItem[this.definition.nameField] + '')
(metadataItem[baseField] + '')
.trim()
.slice(0, maxKeyLength - Util.OPTIONS.keySuffix.length)
.trim() + Util.OPTIONS.keySuffix;
.slice(0, maxKeyLength - keySuffix.length)
.trim() + keySuffix;
}

return newKey;
Expand Down
43 changes: 29 additions & 14 deletions lib/util/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,22 +149,37 @@ function setupSDK(sessionKey, authObject) {
} else if (msg.headers?.Authorization) {
msg.headers.Authorization = 'Bearer *** TOKEN REMOVED ***';
}
if (Util.OPTIONS.api === 'cli') {
console.log(`${Util.color.fgMagenta}API REQUEST >>${Util.color.reset}`, msg); // eslint-disable-line no-console
} else if (Util.OPTIONS.api === 'log') {
let data;
if (msg.data) {
data = msg.data;
delete msg.data;
}
Util.logger.debug('API REQUEST >> ' + JSON.stringify(msg, null, 2));
if (data) {
// printing it separately leads to better formatting
Util.logger.debug(
'API REQUEST body >> \n ' +
(typeof data === 'string' ? data : JSON.stringify(data, null, 2))
switch (Util.OPTIONS.api) {
case 'cli': {
/* eslint-disable no-console */
console.log(
`${Util.color.fgMagenta}API REQUEST >>${Util.color.reset}`,
msg
);
/* eslint-enable no-console */

break;
}
case 'log': {
let data;
if (msg.data) {
data = msg.data;
delete msg.data;
}
Util.logger.debug('API REQUEST >> ' + JSON.stringify(msg, null, 2));
if (data) {
// printing it separately leads to better formatting
Util.logger.debug(
'API REQUEST body >> \n ' +
(typeof data === 'string'
? data
: JSON.stringify(data, null, 2))
);
}

break;
}
// No default
}
},
logResponse: (res) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "testNew_query",
"key": "testNew_query",
"description": "created on deploy",
"targetKey": "testExisting_dataExtensionShared",
"createdDate": "2022-04-26T15:21:16.453",
"modifiedDate": "2022-04-26T16:04:15.88",
"targetUpdateTypeName": "Overwrite",
"isFrozen": false,
"r__folder_Path": "Query"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SELECT
SubscriberKey as testField
FROM
_Subscribers
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<table
cellpadding="0"
cellspacing="0"
width="100%"
role="presentation"
style="min-width: 100%"
class="stylingblock-content-wrapper"
>
<tr>
<td class="stylingblock-content-wrapper camarker-inner">foobar</td>
</tr>
</table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"customerKey": "testNew_asset",
"assetType": {
"name": "textblock",
"displayName": "Text Block"
},
"fileProperties": {
"fileName": "testNew_asset"
},
"name": "testNew_asset",
"description": "bla bla",
"owner": {
"email": "joern.berkefeld@accenture.com",
"name": "Jörn Berkefeld"
},
"createdDate": "2022-10-14T08:54:26.643-06:00",
"createdBy": {
"email": "joern.berkefeld@accenture.com",
"name": "Jörn Berkefeld"
},
"modifiedDate": "2024-05-06T07:18:33.787-06:00",
"modifiedBy": {
"name": "SFMC DEVOPS app user"
},
"memberId": 1111111,
"status": {
"name": "Draft"
},
"meta": {
"wrapperStyles": {
"mobile": {
"visible": true
}
}
},
"availableViews": [],
"modelVersion": 2,
"r__folder_Path": "Content Builder"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"count": 0,
"page": 1,
"pageSize": 50,
"items": []
}
18 changes: 18 additions & 0 deletions test/resources/1111111/automation/v1/queries/post-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"queryDefinitionId": "549f0568-607c-4940-afef-437965094d-keySuffix",
"name": "testNew_query",
"key": "testNew_query_DEV",
"description": "created on deploy",
"queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\n",
"targetName": "testExisting_dataExtensionShared",
"targetKey": "testExisting_dataExtensionShared",
"targetId": "21711373-72c1-ec11-b83b-shared",
"targetDescription": "",
"createdDate": "2022-04-26T15:21:16.453",
"modifiedDate": "2022-04-26T16:04:15.88",
"targetUpdateTypeId": 0,
"targetUpdateTypeName": "Overwrite",
"validatedQueryText": "SET NOCOUNT ON; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;\r\n\r\nINSERT INTO C518001158.[testDataExtension] ([testField])\r\nSELECT querydef.[testField]\r\nFROM (SELECT SubscriberKey as testField FROM C518001158._Subscribers ) AS querydef \r\nSELECT @rcInsert = @@ROWCOUNT;;\r\n",
"categoryId": 9991,
"isFrozen": false
}
Loading
Loading