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/164 enhance delete to support all metadata types (REST) #1192

229 changes: 114 additions & 115 deletions docs/dist/documentation.md

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions lib/metadataTypes/Asset.js
Original file line number Diff line number Diff line change
Expand Up @@ -1629,6 +1629,66 @@ class Asset extends MetadataType {
).flat();
return fileList;
}
/**
* helper to allow us to select single metadata entries via REST
*
* @private
* @param {string} key customer key
* @returns {Promise.<string>} objectId or enpty string
*/
static async _getObjectIdForSingleRetrieve(key) {
const name = key.startsWith('name:') ? key.slice(5) : null;
const filter = name
? '?$filter=name%20eq%20' + encodeURIComponent(name)
: '?$filter=customerKey%20eq%20' + encodeURIComponent(key);

const results = await this.client.rest.get('/asset/v1/content/assets/' + filter);
const items = results?.items || [];
const found = items.find((item) =>
name ? item[this.definition.nameField] === name : item[this.definition.keyField] === key
);
return found?.id || null;
}

/**
* Delete a metadata item from the specified business unit
*
* @param {string} customerKey Identifier of data extension
* @returns {Promise.<boolean>} deletion success flag
*/
static async deleteByKey(customerKey) {
// delete only works with the query's object id
const objectId = customerKey ? await this._getObjectIdForSingleRetrieve(customerKey) : null;
if (!objectId) {
Util.logger.error(` - ${this.definition.type} not found`);
return false;
}
return super.deleteByKeyREST('/asset/v1/content/assets/' + objectId, customerKey);
}

/**
* clean up after deleting a metadata item
* cannot use the generic method due to the complexity of how assets are saved to disk
*
* @param {string} customerKey Identifier of metadata item
* @returns {void}
*/
static async postDeleteTasks(customerKey) {
const fileArr = await this.getFilesToCommit([customerKey]);

// check if asset sits in its own folder
const ownFolderIndex =
fileArr[0].indexOf(customerKey + '\\') > 0
? fileArr[0].indexOf(customerKey + '\\')
: fileArr[0].indexOf(customerKey + '/');
if (ownFolderIndex > 0) {
fileArr.push(fileArr[0].slice(0, ownFolderIndex + customerKey.length));
}

for (const filePath of fileArr) {
await File.remove(filePath);
}
}
}

// Assign definition to static attributes
Expand Down
11 changes: 1 addition & 10 deletions lib/metadataTypes/ContentArea.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,6 @@ class ContentArea extends MetadataType {
// !dont activate `await File.initPrettier('html');` as we only want to retrieve for migration and formatting might mess with the outcome
return super.retrieveSOAP(retrieveDir, requestParams, key);
}
/**
* manages post retrieve steps
*
* @param {TYPE.MetadataTypeItem} metadata a single item
* @returns {TYPE.MetadataTypeItem} parsed item
*/
static postRetrieveTasks(metadata) {
return this.parseMetadata(metadata);
}
/**
* generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve
*
Expand Down Expand Up @@ -79,7 +70,7 @@ class ContentArea extends MetadataType {
* @param {TYPE.MetadataTypeItem} metadata a single item
* @returns {TYPE.MetadataTypeItem} parsed item
*/
static parseMetadata(metadata) {
static postRetrieveTasks(metadata) {
// folder
this.setFolderPath(metadata);

Expand Down
12 changes: 0 additions & 12 deletions lib/metadataTypes/DataExtensionField.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,6 @@ class DataExtensionField extends MetadataType {
* @returns {TYPE.DataExtensionFieldItem} metadata
*/
static postRetrieveTasks(metadata, forDataExtension) {
return this._parseMetadata(metadata, forDataExtension);
}

/**
* parses retrieved Metadata before saving
*
* @private
* @param {TYPE.DataExtensionFieldItem} metadata a single record
* @param {boolean} forDataExtension when used by DataExtension class we remove more fields
* @returns {TYPE.DataExtensionFieldItem} parsed metadata definition
*/
static _parseMetadata(metadata, forDataExtension) {
if (forDataExtension) {
// remove fields according to definition
this.keepRetrieveFields(metadata);
Expand Down
53 changes: 38 additions & 15 deletions lib/metadataTypes/DataExtract.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class DataExtract extends MetadataType {
const originalKey = extended[this.definition.keyField];
const val = JSON.parse(
Util.replaceByObject(
JSON.stringify(this.parseMetadata(extended)),
JSON.stringify(this.postRetrieveTasks(extended)),
templateVariables
)
);
Expand All @@ -86,16 +86,6 @@ class DataExtract extends MetadataType {
}
}

/**
* manages post retrieve steps
*
* @param {TYPE.MetadataTypeItem} fileTransfer a single fileTransfer
* @returns {TYPE.MetadataTypeItem} metadata
*/
static postRetrieveTasks(fileTransfer) {
return this.parseMetadata(fileTransfer);
}

/**
* Creates a single Data Extract
*
Expand Down Expand Up @@ -136,12 +126,12 @@ class DataExtract extends MetadataType {
return metadata;
}
/**
* parses retrieved Metadata before saving
* manages post retrieve steps
*
* @param {TYPE.MetadataTypeItem} metadata a single dataExtract activity definition
* @returns {TYPE.MetadataTypeItem} Array with one metadata object and one sql string
* @param {TYPE.MetadataTypeItem} metadata a single item
* @returns {TYPE.MetadataTypeItem} metadata
*/
static parseMetadata(metadata) {
static postRetrieveTasks(metadata) {
try {
metadata.r__dataExtractType_name = cache.searchForField(
'dataExtractType',
Expand All @@ -157,6 +147,39 @@ class DataExtract extends MetadataType {
}
return JSON.parse(JSON.stringify(metadata));
}
/**
* helper to allow us to select single metadata entries via REST
*
* @private
* @param {string} key customer key
* @returns {Promise.<string>} objectId or enpty string
*/
static async _getObjectIdForSingleRetrieve(key) {
const name = key.startsWith('name:') ? key.slice(5) : null;
const filter = name ? '?$filter=name%20eq%20' + encodeURIComponent(name) : '';
const results = await this.client.rest.get('/automation/v1/dataextracts/' + filter);
const items = results?.items || [];
const found = items.find((item) =>
name ? item[this.definition.nameField] === name : item[this.definition.keyField] === key
);
return found?.dataExtractDefinitionId || null;
}

/**
* Delete a metadata item from the specified business unit
*
* @param {string} customerKey Identifier of data extension
* @returns {Promise.<boolean>} deletion success flag
*/
static async deleteByKey(customerKey) {
// delete only works with the query's object id
const objectId = customerKey ? await this._getObjectIdForSingleRetrieve(customerKey) : null;
if (!objectId) {
Util.logger.error(` - dataExtract not found`);
return false;
}
return super.deleteByKeyREST('/automation/v1/dataextracts/' + objectId, customerKey);
}
}

// Assign definition to static attributes
Expand Down
9 changes: 0 additions & 9 deletions lib/metadataTypes/Email.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,6 @@ class Email extends MetadataType {
* @returns {TYPE.MetadataTypeItem} Array with one metadata object and one query string
*/
static postRetrieveTasks(metadata) {
return this.parseMetadata(metadata);
}
/**
* parses retrieved Metadata before saving
*
* @param {TYPE.MetadataTypeItem} metadata a single query activity definition
* @returns {TYPE.MetadataTypeItem} Array with one metadata object and one sql string
*/
static parseMetadata(metadata) {
// folder
super.setFolderPath(metadata);

Expand Down
52 changes: 38 additions & 14 deletions lib/metadataTypes/FileTransfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class FileTransfer extends MetadataType {
const originalKey = extended[this.definition.keyField];
const val = JSON.parse(
Util.replaceByObject(
JSON.stringify(this.parseMetadata(extended)),
JSON.stringify(this.postRetrieveTasks(extended)),
templateVariables
)
);
Expand All @@ -86,17 +86,6 @@ class FileTransfer extends MetadataType {
}
}

/**
* manages post retrieve steps
*
* @param {TYPE.MetadataTypeItem} metadata a single fileTransfer activity definition
* @returns {object[]} metadata
*/
static postRetrieveTasks(metadata) {
const values = this.parseMetadata(metadata);
return values;
}

/**
* Creates a single File Transfer
*
Expand Down Expand Up @@ -139,13 +128,14 @@ class FileTransfer extends MetadataType {
}
return metadata;
}

/**
* parses retrieved Metadata before saving
* manages post retrieve steps
*
* @param {TYPE.MetadataTypeItem} metadata a single fileTransfer activity definition
* @returns {TYPE.MetadataTypeItem} parsed metadata
*/
static parseMetadata(metadata) {
static postRetrieveTasks(metadata) {
try {
metadata.r__fileLocation_name = cache.searchForField(
'fileLocation',
Expand All @@ -162,6 +152,40 @@ class FileTransfer extends MetadataType {

return metadata;
}

/**
* helper to allow us to select single metadata entries via REST
*
* @private
* @param {string} key customer key
* @returns {Promise.<string>} objectId or enpty string
*/
static async _getObjectIdForSingleRetrieve(key) {
const name = key.startsWith('name:') ? key.slice(5) : null;
const filter = name ? '?$filter=name%20eq%20' + encodeURIComponent(name) : '';
const results = await this.client.rest.get('/automation/v1/filetransfers/' + filter);
const items = results?.items || [];
const found = items.find((item) =>
name ? item[this.definition.nameField] === name : item[this.definition.keyField] === key
);
return found?.id || null;
}

/**
* Delete a metadata item from the specified business unit
*
* @param {string} customerKey Identifier of data extension
* @returns {Promise.<boolean>} deletion success flag
*/
static async deleteByKey(customerKey) {
// delete only works with the query's object id
const objectId = customerKey ? await this._getObjectIdForSingleRetrieve(customerKey) : null;
if (!objectId) {
Util.logger.error(` - fileTransfer not found`);
return false;
}
return super.deleteByKeyREST('/automation/v1/filetransfers/' + objectId, customerKey);
}
}

// Assign definition to static attributes
Expand Down
36 changes: 21 additions & 15 deletions lib/metadataTypes/ImportFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class ImportFile extends MetadataType {
const originalKey = metadata[this.definition.keyField];
const val = JSON.parse(
Util.replaceByObject(
JSON.stringify(this.parseMetadata(metadata)),
JSON.stringify(this.postRetrieveTasks(metadata)),
templateVariables
)
);
Expand Down Expand Up @@ -127,16 +127,6 @@ class ImportFile extends MetadataType {
return response?.Results?.length ? response.Results[0].ObjectID : null;
}

/**
* manages post retrieve steps
*
* @param {TYPE.MetadataTypeItem} importDef a single importDef
* @returns {TYPE.MetadataTypeItem} metadata
*/
static postRetrieveTasks(importDef) {
return this.parseMetadata(importDef);
}

/**
* Creates a single Import File
*
Expand Down Expand Up @@ -221,12 +211,12 @@ class ImportFile extends MetadataType {
}

/**
* parses retrieved Metadata before saving
* manages post retrieve steps
*
* @param {TYPE.MetadataTypeItem} metadata a single import definition
* @returns {TYPE.MetadataTypeItem} parsed metadata definition
* @param {TYPE.MetadataTypeItem} metadata a single item
* @returns {TYPE.MetadataTypeItem} parsed metadata
*/
static parseMetadata(metadata) {
static postRetrieveTasks(metadata) {
metadata.r__fileLocation_name = cache.searchForField(
'fileLocation',
metadata.fileTransferLocationId,
Expand Down Expand Up @@ -285,6 +275,22 @@ class ImportFile extends MetadataType {
delete metadata.updateTypeId;
return metadata;
}

/**
* Delete a metadata item from the specified business unit
*
* @param {string} customerKey Identifier of data extension
* @returns {Promise.<boolean>} deletion success flag
*/
static async deleteByKey(customerKey) {
// delete only works with the query's object id
const objectId = customerKey ? await this._getObjectIdForSingleRetrieve(customerKey) : null;
if (!objectId) {
Util.logger.error(` - import not found`);
return false;
}
return super.deleteByKeyREST('/automation/v1/imports/' + objectId, customerKey);
}
}

// Assign definition to static attributes
Expand Down
6 changes: 3 additions & 3 deletions lib/metadataTypes/MetadataType.js
Original file line number Diff line number Diff line change
Expand Up @@ -1558,7 +1558,7 @@ class MetadataType {
* @returns {?boolean} true: filter value found; false: filter value not found; null: no filter defined
*/
static _filterOther(myFilter, metadataEntry) {
// not possible to check r__folder_Path before parseMetadata was run; handled in `isFilteredFolder()`
// not possible to check r__folder_Path before postRetrieveTasks was run; handled in `isFilteredFolder()`
if (
!myFilter ||
!Object.keys(myFilter).filter((item) => item !== 'r__folder_Path').length
Expand Down Expand Up @@ -2021,7 +2021,7 @@ class MetadataType {
* @param {string} customerKey Identifier of metadata
* @param {string} [overrideKeyField] optionally change the name of the key field if the api uses a different name
* @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method
* @returns {boolean} deletion success flag
* @returns {Promise.<boolean>} deletion success flag
*/
static async deleteByKeySOAP(customerKey, overrideKeyField, handleOutside) {
const metadata = {};
Expand Down Expand Up @@ -2056,7 +2056,7 @@ class MetadataType {
* @param {string} url endpoint
* @param {string} key Identifier of metadata
* @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method
* @returns {boolean} deletion success flag
* @returns {Promise.<boolean>} deletion success flag
*/
static async deleteByKeyREST(url, key, handleOutside) {
try {
Expand Down
2 changes: 1 addition & 1 deletion lib/metadataTypes/Query.js
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ class Query extends MetadataType {
* Delete a metadata item from the specified business unit
*
* @param {string} customerKey Identifier of data extension
* @returns {boolean} deletion success status
* @returns {Promise.<boolean>} deletion success flag
*/
static async deleteByKey(customerKey) {
// delete only works with the query's object id
Expand Down
Loading
Loading