Skip to content

Commit

Permalink
Merge pull request #1192 from Accenture/feature/164-enhance-delete-to…
Browse files Browse the repository at this point in the history
…-support-all-metadata-types-rest

Feature/164 enhance `delete` to support all metadata types (REST)
  • Loading branch information
JoernBerkefeld authored Jan 29, 2024
2 parents bc0261e + f067b06 commit ca82130
Show file tree
Hide file tree
Showing 23 changed files with 541 additions and 248 deletions.
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

0 comments on commit ca82130

Please sign in to comment.