From cb89209a108ffc793fc48ccfa0daa20b1981d1a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 26 Jan 2024 14:01:36 +0100 Subject: [PATCH 01/11] #164: support delete importFile --- lib/metadataTypes/ImportFile.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/metadataTypes/ImportFile.js b/lib/metadataTypes/ImportFile.js index 26efb0f3c..1b385f798 100644 --- a/lib/metadataTypes/ImportFile.js +++ b/lib/metadataTypes/ImportFile.js @@ -285,6 +285,21 @@ 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 {boolean} deletion success status + */ + 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 From f7595442f945b6281c04b256bdcbc1d822e8db97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 26 Jan 2024 18:23:45 +0100 Subject: [PATCH 02/11] #164: support delete for fileTransfer --- docs/dist/documentation.md | 13 ++++++++ lib/metadataTypes/FileTransfer.js | 31 +++++++++++++++++++ .../delete-response.json | 1 + test/type.fileTransfer.test.js | 14 ++------- 4 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/delete-response.json diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 1f3eeaf3f..98b504327 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -2744,6 +2744,7 @@ FileTransfer MetadataType * [.update(fileTransfer)](#FileTransfer.update) ⇒ Promise * [.preDeployTasks(metadata)](#FileTransfer.preDeployTasks) ⇒ Promise * [.parseMetadata(metadata)](#FileTransfer.parseMetadata) ⇒ TYPE.MetadataTypeItem + * [.deleteByKey(customerKey)](#FileTransfer.deleteByKey) ⇒ boolean @@ -2842,6 +2843,18 @@ parses retrieved Metadata before saving | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single fileTransfer activity definition | + + +### FileTransfer.deleteByKey(customerKey) ⇒ boolean +Delete a metadata item from the specified business unit + +**Kind**: static method of [FileTransfer](#FileTransfer) +**Returns**: boolean - deletion success status + +| Param | Type | Description | +| --- | --- | --- | +| customerKey | string | Identifier of data extension | + ## Filter ⇐ [MetadataType](#MetadataType) diff --git a/lib/metadataTypes/FileTransfer.js b/lib/metadataTypes/FileTransfer.js index 35067f816..817ee6d4c 100644 --- a/lib/metadataTypes/FileTransfer.js +++ b/lib/metadataTypes/FileTransfer.js @@ -162,6 +162,37 @@ 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.} 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.name === name : item.customerKey === key)); + return found?.id || null; + } + + /** + * Delete a metadata item from the specified business unit + * + * @param {string} customerKey Identifier of data extension + * @returns {boolean} deletion success status + */ + 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 diff --git a/test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/delete-response.json b/test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/delete-response.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/resources/9999999/automation/v1/filetransfers/72c328ac-f5b0-4e37-91d3-a775666f15a6/delete-response.json @@ -0,0 +1 @@ +{} diff --git a/test/type.fileTransfer.test.js b/test/type.fileTransfer.test.js index 1bb0f10e0..188a09658 100644 --- a/test/type.fileTransfer.test.js +++ b/test/type.fileTransfer.test.js @@ -172,19 +172,11 @@ describe('type: fileTransfer', () => { const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'fileTransfer', - 'testExisting_fileTranfer' + 'testExisting_fileTransfer' ); // THEN - assert.equal( - process.exitCode, - 1, - 'deleteByKey should have thrown an error due to lack of support' - ); - assert.equal( - isDeleted, - false, - 'deleteByKey should have returned false due to lack of support' - ); + assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); + assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); From 7319c33c7081ba18498f54c6e153ab949f23115e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 26 Jan 2024 18:28:16 +0100 Subject: [PATCH 03/11] #164: support delete for importFile - test case --- .../delete-response.txt | 0 test/type.importFile.test.js | 12 ++---------- 2 files changed, 2 insertions(+), 10 deletions(-) create mode 100644 test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/delete-response.txt diff --git a/test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/delete-response.txt b/test/resources/9999999/automation/v1/imports/9d16f42c-2260-ed11-b849-48df37d1de8b/delete-response.txt new file mode 100644 index 000000000..e69de29bb diff --git a/test/type.importFile.test.js b/test/type.importFile.test.js index 7e90a8de3..21ad11d73 100644 --- a/test/type.importFile.test.js +++ b/test/type.importFile.test.js @@ -204,16 +204,8 @@ describe('type: importFile', () => { 'testExisting_importFile' ); // THEN - assert.equal( - process.exitCode, - 1, - 'deleteByKey should have thrown an error due to lack of support' - ); - assert.equal( - isDeleted, - false, - 'deleteByKey should have returned false due to lack of support' - ); + assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); + assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); From e8a285d5bcd2e6580e40167854fe814e89e53250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 26 Jan 2024 18:57:18 +0100 Subject: [PATCH 04/11] #164: support delete for fileTransfer --- docs/dist/documentation.md | 13 +++++++++++++ lib/metadataTypes/FileTransfer.js | 4 +++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 98b504327..b204520cf 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -2232,6 +2232,7 @@ DataExtract MetadataType * [.update(dataExtract)](#DataExtract.update) ⇒ Promise * [.preDeployTasks(metadata)](#DataExtract.preDeployTasks) ⇒ TYPE.MetadataTypeItem * [.parseMetadata(metadata)](#DataExtract.parseMetadata) ⇒ TYPE.MetadataTypeItem + * [.deleteByKey(customerKey)](#DataExtract.deleteByKey) ⇒ boolean @@ -2330,6 +2331,18 @@ parses retrieved Metadata before saving | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single dataExtract activity definition | + + +### DataExtract.deleteByKey(customerKey) ⇒ boolean +Delete a metadata item from the specified business unit + +**Kind**: static method of [DataExtract](#DataExtract) +**Returns**: boolean - deletion success status + +| Param | Type | Description | +| --- | --- | --- | +| customerKey | string | Identifier of data extension | + ## DataExtractType ⇐ [MetadataType](#MetadataType) diff --git a/lib/metadataTypes/FileTransfer.js b/lib/metadataTypes/FileTransfer.js index 817ee6d4c..62fa606f8 100644 --- a/lib/metadataTypes/FileTransfer.js +++ b/lib/metadataTypes/FileTransfer.js @@ -174,7 +174,9 @@ class FileTransfer extends MetadataType { 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.name === name : item.customerKey === key)); + const found = items.find((item) => + name ? item[this.definition.nameField] === name : item[this.definition.keyField] === key + ); return found?.id || null; } From ffdaa8c4464c97f8eeb45a4c73055d99720d6c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 26 Jan 2024 18:59:41 +0100 Subject: [PATCH 05/11] #164: support delete for dataExtract --- lib/metadataTypes/DataExtract.js | 33 +++++++++++++++++++ .../delete-response.txt | 1 + test/type.dataExtract.test.js | 14 ++------ 3 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/delete-response.txt diff --git a/lib/metadataTypes/DataExtract.js b/lib/metadataTypes/DataExtract.js index c6cdf0168..ae6bf299c 100644 --- a/lib/metadataTypes/DataExtract.js +++ b/lib/metadataTypes/DataExtract.js @@ -157,6 +157,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.} 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 {boolean} deletion success status + */ + 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 diff --git a/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/delete-response.txt b/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/delete-response.txt new file mode 100644 index 000000000..d86bac9de --- /dev/null +++ b/test/resources/9999999/automation/v1/dataextracts/56c5370a-f988-4f36-b0ee-0f876573f6d7/delete-response.txt @@ -0,0 +1 @@ +OK diff --git a/test/type.dataExtract.test.js b/test/type.dataExtract.test.js index 12cde0fb5..bf5aafe07 100644 --- a/test/type.dataExtract.test.js +++ b/test/type.dataExtract.test.js @@ -174,19 +174,11 @@ describe('type: dataExtract', () => { const isDeleted = await handler.deleteByKey( 'testInstance/testBU', 'dataExtract', - 'testExisting_fileTranfer' + 'testExisting_dataExtract' ); // THEN - assert.equal( - process.exitCode, - 1, - 'deleteByKey should have thrown an error due to lack of support' - ); - assert.equal( - isDeleted, - false, - 'deleteByKey should have returned false due to lack of support' - ); + assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); + assert.equal(isDeleted, true, 'deleteByKey should have returned true'); return; }); }); From a6bc86c8341d071161baf77707ef4e96db678b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 26 Jan 2024 19:19:57 +0100 Subject: [PATCH 06/11] #164: support delete for script --- docs/dist/documentation.md | 25 ++++++++++ lib/metadataTypes/Script.js | 50 +++++++++++++++++++ .../delete-response.txt | 1 + test/type.script.test.js | 15 +++++- 4 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/delete-response.txt diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index b204520cf..944797e37 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -5254,6 +5254,8 @@ Script MetadataType * [.parseMetadata(metadata)](#Script.parseMetadata) ⇒ TYPE.CodeExtractItem * [.prepExtractedCode(metadataScript, metadataName)](#Script.prepExtractedCode) ⇒ Object * [.getFilesToCommit(keyArr)](#Script.getFilesToCommit) ⇒ Array.<string> + * [.deleteByKey(customerKey)](#Script.deleteByKey) ⇒ boolean + * [.postDeleteTasks(customerKey)](#Script.postDeleteTasks) ⇒ void @@ -5449,6 +5451,29 @@ additionally, the documentation for dataExtension and automation should be retur | --- | --- | --- | | keyArr | Array.<string> | customerkey of the metadata | + + +### Script.deleteByKey(customerKey) ⇒ boolean +Delete a metadata item from the specified business unit + +**Kind**: static method of [Script](#Script) +**Returns**: boolean - deletion success status + +| Param | Type | Description | +| --- | --- | --- | +| customerKey | string | Identifier of data extension | + + + +### Script.postDeleteTasks(customerKey) ⇒ void +clean up after deleting a metadata item + +**Kind**: static method of [Script](#Script) + +| Param | Type | Description | +| --- | --- | --- | +| customerKey | string | Identifier of metadata item | + ## SendClassification ⇐ [MetadataType](#MetadataType) diff --git a/lib/metadataTypes/Script.js b/lib/metadataTypes/Script.js index e84ea214d..2c56bd6ad 100644 --- a/lib/metadataTypes/Script.js +++ b/lib/metadataTypes/Script.js @@ -324,6 +324,56 @@ class Script extends MetadataType { ]); return fileList; } + /** + * helper to allow us to select single metadata entries via REST + * + * @private + * @param {string} key customer key + * @returns {Promise.} 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=key%20eq%20' + encodeURIComponent(key); + const results = await this.client.rest.get('/automation/v1/scripts/' + filter); + const items = results?.items || []; + const found = items.find((item) => + name ? item[this.definition.nameField] === name : item[this.definition.keyField] === key + ); + return found?.ssjsActivityId || null; + } + + /** + * Delete a metadata item from the specified business unit + * + * @param {string} customerKey Identifier of data extension + * @returns {boolean} deletion success status + */ + 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('/automation/v1/scripts/' + objectId, customerKey); + } + /** + * clean up after deleting a metadata item + * + * @param {string} customerKey Identifier of metadata item + * @returns {void} + */ + static async postDeleteTasks(customerKey) { + // delete local copy: retrieve/cred/bu/.../...-meta.json + // delete local copy: retrieve/cred/bu/.../...-meta.ssjs + // delete local copy: retrieve/cred/bu/.../...-meta.html + await super.postDeleteTasks(customerKey, [ + `${this.definition.type}-meta.ssjs`, + `${this.definition.type}-meta.html`, + ]); + } } // Assign definition & cache to static attributes diff --git a/test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/delete-response.txt b/test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/delete-response.txt new file mode 100644 index 000000000..d86bac9de --- /dev/null +++ b/test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/delete-response.txt @@ -0,0 +1 @@ +OK diff --git a/test/type.script.test.js b/test/type.script.test.js index 215136ab5..330553518 100644 --- a/test/type.script.test.js +++ b/test/type.script.test.js @@ -372,7 +372,20 @@ describe('type: script', () => { return; }); }); - describe('Delete ================', () => {}); + describe('Delete ================', () => { + it('Should delete the item', async () => { + // WHEN + const isDeleted = await handler.deleteByKey( + 'testInstance/testBU', + 'script', + 'testExisting_script' + ); + // THEN + assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); + assert.equal(isDeleted, true, 'deleteByKey should have returned true'); + return; + }); + }); describe('CI/CD ================', () => { it('Should return a list of files based on their type and key', async () => { // WHEN From 1dc5597228a3f58a491d55c9a89ae264b99f425a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 26 Jan 2024 19:21:19 +0100 Subject: [PATCH 07/11] #164: cleanup --- test/type.dataExtract.test.js | 2 +- test/type.fileTransfer.test.js | 2 +- test/type.importFile.test.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/type.dataExtract.test.js b/test/type.dataExtract.test.js index bf5aafe07..a2beb9ffe 100644 --- a/test/type.dataExtract.test.js +++ b/test/type.dataExtract.test.js @@ -169,7 +169,7 @@ describe('type: dataExtract', () => { }); }); describe('Delete ================', () => { - it('Should NOT delete the item', async () => { + it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', diff --git a/test/type.fileTransfer.test.js b/test/type.fileTransfer.test.js index 188a09658..b4c18386b 100644 --- a/test/type.fileTransfer.test.js +++ b/test/type.fileTransfer.test.js @@ -167,7 +167,7 @@ describe('type: fileTransfer', () => { }); }); describe('Delete ================', () => { - it('Should NOT delete the item', async () => { + it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', diff --git a/test/type.importFile.test.js b/test/type.importFile.test.js index 21ad11d73..42e12a286 100644 --- a/test/type.importFile.test.js +++ b/test/type.importFile.test.js @@ -196,7 +196,7 @@ describe('type: importFile', () => { }); }); describe('Delete ================', () => { - it('Should NOT delete the item', async () => { + it('Should delete the item', async () => { // WHEN const isDeleted = await handler.deleteByKey( 'testInstance/testBU', From 50edae3ae059d30f0c9b064b8406a9526e7008a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Mon, 29 Jan 2024 14:17:03 +0100 Subject: [PATCH 08/11] #164: refactoring --- docs/dist/documentation.md | 128 +++++------------------- lib/metadataTypes/ContentArea.js | 11 +- lib/metadataTypes/DataExtensionField.js | 12 --- lib/metadataTypes/DataExtract.js | 20 +--- lib/metadataTypes/Email.js | 9 -- lib/metadataTypes/FileTransfer.js | 19 +--- lib/metadataTypes/ImportFile.js | 21 ++-- lib/metadataTypes/MetadataType.js | 2 +- lib/metadataTypes/Script.js | 23 ++--- 9 files changed, 50 insertions(+), 195 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 944797e37..b441b4e3f 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -1767,9 +1767,8 @@ ContentArea MetadataType * [ContentArea](#ContentArea) ⇐ [MetadataType](#MetadataType) * [.retrieve(retrieveDir, [_], [__], [key])](#ContentArea.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> - * [.postRetrieveTasks(metadata)](#ContentArea.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem * [.setFolderPath(metadata)](#ContentArea.setFolderPath) - * [.parseMetadata(metadata)](#ContentArea.parseMetadata) ⇒ TYPE.MetadataTypeItem + * [.postRetrieveTasks(metadata)](#ContentArea.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem @@ -1786,18 +1785,6 @@ Retrieves SOAP based metadata of metadata type into local filesystem. executes c | [__] | void | unused parameter | | [key] | string | customer key of single item to retrieve | - - -### ContentArea.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem -manages post retrieve steps - -**Kind**: static method of [ContentArea](#ContentArea) -**Returns**: TYPE.MetadataTypeItem - parsed item - -| Param | Type | Description | -| --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single item | - ### ContentArea.setFolderPath(metadata) @@ -1809,9 +1796,9 @@ generic script that retrieves the folder path from cache and updates the given m | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single script activity definition | - + -### ContentArea.parseMetadata(metadata) ⇒ TYPE.MetadataTypeItem +### ContentArea.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem parses retrieved Metadata before saving **Kind**: static method of [ContentArea](#ContentArea) @@ -2227,11 +2214,10 @@ DataExtract MetadataType * [.retrieve(retrieveDir, [_], [__], [key])](#DataExtract.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveForCache()](#DataExtract.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveAsTemplate(templateDir, name, templateVariables)](#DataExtract.retrieveAsTemplate) ⇒ Promise.<TYPE.MetadataTypeItemObj> - * [.postRetrieveTasks(fileTransfer)](#DataExtract.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem * [.create(dataExtract)](#DataExtract.create) ⇒ Promise * [.update(dataExtract)](#DataExtract.update) ⇒ Promise * [.preDeployTasks(metadata)](#DataExtract.preDeployTasks) ⇒ TYPE.MetadataTypeItem - * [.parseMetadata(metadata)](#DataExtract.parseMetadata) ⇒ TYPE.MetadataTypeItem + * [.postRetrieveTasks(metadata)](#DataExtract.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem * [.deleteByKey(customerKey)](#DataExtract.deleteByKey) ⇒ boolean @@ -2271,18 +2257,6 @@ Retrieve a specific dataExtract Definition by Name | name | string | name of the metadata file | | templateVariables | TYPE.TemplateMap | variables to be replaced in the metadata | - - -### DataExtract.postRetrieveTasks(fileTransfer) ⇒ TYPE.MetadataTypeItem -manages post retrieve steps - -**Kind**: static method of [DataExtract](#DataExtract) -**Returns**: TYPE.MetadataTypeItem - metadata - -| Param | Type | Description | -| --- | --- | --- | -| fileTransfer | TYPE.MetadataTypeItem | a single fileTransfer | - ### DataExtract.create(dataExtract) ⇒ Promise @@ -2319,17 +2293,17 @@ prepares a dataExtract for deployment | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single dataExtract activity definition | - + -### DataExtract.parseMetadata(metadata) ⇒ TYPE.MetadataTypeItem -parses retrieved Metadata before saving +### DataExtract.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem +manages post retrieve steps **Kind**: static method of [DataExtract](#DataExtract) -**Returns**: TYPE.MetadataTypeItem - Array with one metadata object and one sql string +**Returns**: TYPE.MetadataTypeItem - metadata | Param | Type | Description | | --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single dataExtract activity definition | +| metadata | TYPE.MetadataTypeItem | a single item | @@ -2414,7 +2388,6 @@ Email MetadataType * [.retrieve(retrieveDir, [_], [__], [key])](#Email.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.saveResults(results, retrieveDir, [overrideType], [templateVariables])](#Email.saveResults) ⇒ Promise.<TYPE.MetadataTypeMap> * [.postRetrieveTasks(metadata)](#Email.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem - * [.parseMetadata(metadata)](#Email.parseMetadata) ⇒ TYPE.MetadataTypeItem @@ -2458,18 +2431,6 @@ manages post retrieve steps | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single query | - - -### Email.parseMetadata(metadata) ⇒ TYPE.MetadataTypeItem -parses retrieved Metadata before saving - -**Kind**: static method of [Email](#Email) -**Returns**: TYPE.MetadataTypeItem - Array with one metadata object and one sql string - -| Param | Type | Description | -| --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single query activity definition | - ## EmailSend ⇐ [MetadataType](#MetadataType) @@ -2752,11 +2713,10 @@ FileTransfer MetadataType * [.retrieve(retrieveDir, [_], [__], [key])](#FileTransfer.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveForCache()](#FileTransfer.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveAsTemplate(templateDir, name, templateVariables)](#FileTransfer.retrieveAsTemplate) ⇒ Promise.<TYPE.MetadataTypeItemObj> - * [.postRetrieveTasks(metadata)](#FileTransfer.postRetrieveTasks) ⇒ Array.<object> * [.create(fileTransfer)](#FileTransfer.create) ⇒ Promise * [.update(fileTransfer)](#FileTransfer.update) ⇒ Promise * [.preDeployTasks(metadata)](#FileTransfer.preDeployTasks) ⇒ Promise - * [.parseMetadata(metadata)](#FileTransfer.parseMetadata) ⇒ TYPE.MetadataTypeItem + * [.postRetrieveTasks(metadata)](#FileTransfer.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem * [.deleteByKey(customerKey)](#FileTransfer.deleteByKey) ⇒ boolean @@ -2796,18 +2756,6 @@ Retrieve a specific File Transfer Definition by Name | name | string | name of the metadata file | | templateVariables | TYPE.TemplateMap | variables to be replaced in the metadata | - - -### FileTransfer.postRetrieveTasks(metadata) ⇒ Array.<object> -manages post retrieve steps - -**Kind**: static method of [FileTransfer](#FileTransfer) -**Returns**: Array.<object> - metadata - -| Param | Type | Description | -| --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single fileTransfer activity definition | - ### FileTransfer.create(fileTransfer) ⇒ Promise @@ -2844,10 +2792,10 @@ prepares a fileTransfer for deployment | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single fileTransfer activity definition | - + -### FileTransfer.parseMetadata(metadata) ⇒ TYPE.MetadataTypeItem -parses retrieved Metadata before saving +### FileTransfer.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem +manages post retrieve steps **Kind**: static method of [FileTransfer](#FileTransfer) **Returns**: TYPE.MetadataTypeItem - parsed metadata @@ -3056,11 +3004,10 @@ ImportFile MetadataType * [.retrieve(retrieveDir, [_], [__], [key])](#ImportFile.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveForCache([_], [__], [key])](#ImportFile.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveAsTemplate(templateDir, name, templateVariables)](#ImportFile.retrieveAsTemplate) ⇒ Promise.<TYPE.MetadataTypeItemObj> - * [.postRetrieveTasks(importDef)](#ImportFile.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem * [.create(importFile)](#ImportFile.create) ⇒ Promise * [.update(importFile)](#ImportFile.update) ⇒ Promise * [.preDeployTasks(metadata)](#ImportFile.preDeployTasks) ⇒ Promise - * [.parseMetadata(metadata)](#ImportFile.parseMetadata) ⇒ TYPE.MetadataTypeItem + * [.postRetrieveTasks(metadata)](#ImportFile.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem * [.deleteByKey(customerKey)](#ImportFile.deleteByKey) ⇒ boolean @@ -3108,18 +3055,6 @@ Retrieve a specific Import Definition by Name | name | string | name of the metadata file | | templateVariables | TYPE.TemplateMap | variables to be replaced in the metadata | - - -### ImportFile.postRetrieveTasks(importDef) ⇒ TYPE.MetadataTypeItem -manages post retrieve steps - -**Kind**: static method of [ImportFile](#ImportFile) -**Returns**: TYPE.MetadataTypeItem - metadata - -| Param | Type | Description | -| --- | --- | --- | -| importDef | TYPE.MetadataTypeItem | a single importDef | - ### ImportFile.create(importFile) ⇒ Promise @@ -3156,17 +3091,17 @@ prepares a import definition for deployment | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single importDef | - + -### ImportFile.parseMetadata(metadata) ⇒ TYPE.MetadataTypeItem -parses retrieved Metadata before saving +### ImportFile.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem +manages post retrieve steps **Kind**: static method of [ImportFile](#ImportFile) -**Returns**: TYPE.MetadataTypeItem - parsed metadata definition +**Returns**: TYPE.MetadataTypeItem - parsed metadata | Param | Type | Description | | --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single import definition | +| metadata | TYPE.MetadataTypeItem | a single item | @@ -5243,7 +5178,6 @@ Script MetadataType * [.retrieve(retrieveDir, [_], [__], [key])](#Script.retrieve) ⇒ Promise.<{metadata: TYPE.ScriptMap, type: string}> * [.retrieveForCache()](#Script.retrieveForCache) ⇒ Promise.<{metadata: TYPE.ScriptMap, type: string}> * [.retrieveAsTemplate(templateDir, name, templateVariables)](#Script.retrieveAsTemplate) ⇒ Promise.<{metadata: TYPE.Script, type: string}> - * [.postRetrieveTasks(metadata)](#Script.postRetrieveTasks) ⇒ TYPE.CodeExtractItem * [.update(script)](#Script.update) ⇒ Promise * [.create(script)](#Script.create) ⇒ Promise * [._mergeCode(metadata, deployDir, [templateName])](#Script._mergeCode) ⇒ Promise.<string> @@ -5251,7 +5185,7 @@ Script MetadataType * [.buildDefinitionForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#Script.buildDefinitionForNested) ⇒ Promise.<Array.<Array.<string>>> * [.buildTemplateForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#Script.buildTemplateForNested) ⇒ Promise.<Array.<Array.<string>>> * [._buildForNested(templateDir, targetDir, metadata, templateVariables, templateName, mode)](#Script._buildForNested) ⇒ Promise.<Array.<Array.<string>>> - * [.parseMetadata(metadata)](#Script.parseMetadata) ⇒ TYPE.CodeExtractItem + * [.postRetrieveTasks(metadata)](#Script.postRetrieveTasks) ⇒ TYPE.CodeExtractItem * [.prepExtractedCode(metadataScript, metadataName)](#Script.prepExtractedCode) ⇒ Object * [.getFilesToCommit(keyArr)](#Script.getFilesToCommit) ⇒ Array.<string> * [.deleteByKey(customerKey)](#Script.deleteByKey) ⇒ boolean @@ -5294,18 +5228,6 @@ Retrieve a specific Script by Name | name | string | name of the metadata file | | templateVariables | TYPE.TemplateMap | variables to be replaced in the metadata | - - -### Script.postRetrieveTasks(metadata) ⇒ TYPE.CodeExtractItem -manages post retrieve steps - -**Kind**: static method of [Script](#Script) -**Returns**: TYPE.CodeExtractItem - Array with one metadata object and one ssjs string - -| Param | Type | Description | -| --- | --- | --- | -| metadata | TYPE.ScriptItem | a single script | - ### Script.update(script) ⇒ Promise @@ -5413,22 +5335,22 @@ handles extracted code if any are found for complex types | templateName | string | name of the template to be built | | mode | 'definition' \| 'template' | defines what we use this helper for | - + -### Script.parseMetadata(metadata) ⇒ TYPE.CodeExtractItem -Splits the script metadata into two parts and parses in a standard manner +### Script.postRetrieveTasks(metadata) ⇒ TYPE.CodeExtractItem +manages post retrieve steps **Kind**: static method of [Script](#Script) **Returns**: TYPE.CodeExtractItem - a single item with code parts extracted | Param | Type | Description | | --- | --- | --- | -| metadata | TYPE.ScriptItem | a single script activity definition | +| metadata | TYPE.ScriptItem | a single item | ### Script.prepExtractedCode(metadataScript, metadataName) ⇒ Object -helper for [parseMetadata](#Script.parseMetadata) and [_buildForNested](#Script._buildForNested) +helper for [postRetrieveTasks](#Script.postRetrieveTasks) and [_buildForNested](#Script._buildForNested) **Kind**: static method of [Script](#Script) **Returns**: Object - returns found extension and file content diff --git a/lib/metadataTypes/ContentArea.js b/lib/metadataTypes/ContentArea.js index a67049c92..f9d18edb7 100644 --- a/lib/metadataTypes/ContentArea.js +++ b/lib/metadataTypes/ContentArea.js @@ -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 * @@ -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); diff --git a/lib/metadataTypes/DataExtensionField.js b/lib/metadataTypes/DataExtensionField.js index ec0eeb329..c1f93fae7 100644 --- a/lib/metadataTypes/DataExtensionField.js +++ b/lib/metadataTypes/DataExtensionField.js @@ -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); diff --git a/lib/metadataTypes/DataExtract.js b/lib/metadataTypes/DataExtract.js index ae6bf299c..01dc2e8e4 100644 --- a/lib/metadataTypes/DataExtract.js +++ b/lib/metadataTypes/DataExtract.js @@ -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 ) ); @@ -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 * @@ -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', diff --git a/lib/metadataTypes/Email.js b/lib/metadataTypes/Email.js index f4b3c0d4c..7c17111c6 100644 --- a/lib/metadataTypes/Email.js +++ b/lib/metadataTypes/Email.js @@ -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); diff --git a/lib/metadataTypes/FileTransfer.js b/lib/metadataTypes/FileTransfer.js index 62fa606f8..6fc6310d5 100644 --- a/lib/metadataTypes/FileTransfer.js +++ b/lib/metadataTypes/FileTransfer.js @@ -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 ) ); @@ -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 * @@ -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', @@ -162,6 +152,7 @@ class FileTransfer extends MetadataType { return metadata; } + /** * helper to allow us to select single metadata entries via REST * diff --git a/lib/metadataTypes/ImportFile.js b/lib/metadataTypes/ImportFile.js index 1b385f798..4199931b2 100644 --- a/lib/metadataTypes/ImportFile.js +++ b/lib/metadataTypes/ImportFile.js @@ -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 ) ); @@ -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 * @@ -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, @@ -285,6 +275,7 @@ class ImportFile extends MetadataType { delete metadata.updateTypeId; return metadata; } + /** * Delete a metadata item from the specified business unit * diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 7d30ab4d2..874515599 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -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 diff --git a/lib/metadataTypes/Script.js b/lib/metadataTypes/Script.js index 2c56bd6ad..63f1979c6 100644 --- a/lib/metadataTypes/Script.js +++ b/lib/metadataTypes/Script.js @@ -51,16 +51,6 @@ class Script extends MetadataType { ); } - /** - * manages post retrieve steps - * - * @param {TYPE.ScriptItem} metadata a single script - * @returns {TYPE.CodeExtractItem} Array with one metadata object and one ssjs string - */ - static postRetrieveTasks(metadata) { - return this.parseMetadata(metadata); - } - /** * Updates a single Script * @@ -211,7 +201,7 @@ class Script extends MetadataType { // get SSJS from filesystem let code = await this._mergeCode(metadata, templateDir, templateName); // try to remove script tags and decide on file extension (html/ssjs) - const file = Script.prepExtractedCode(code, metadata.name); + const file = this.prepExtractedCode(code, metadata.name); const fileExt = file.fileExt; code = fileExt === 'ssjs' ? file.code.replace(/^\n/, '') : file.code; // apply templating @@ -255,19 +245,19 @@ class Script extends MetadataType { } /** - * Splits the script metadata into two parts and parses in a standard manner + * manages post retrieve steps * - * @param {TYPE.ScriptItem} metadata a single script activity definition + * @param {TYPE.ScriptItem} metadata a single item * @returns {TYPE.CodeExtractItem} a single item with code parts extracted */ - static parseMetadata(metadata) { + static postRetrieveTasks(metadata) { // folder super.setFolderPath(metadata); // extract SSJS const codeArr = []; // keep between tags - const { fileExt, code } = Script.prepExtractedCode(metadata.script, metadata.name); + const { fileExt, code } = this.prepExtractedCode(metadata.script, metadata.name); delete metadata.script; codeArr.push({ subFolder: null, @@ -278,8 +268,9 @@ class Script extends MetadataType { return { json: metadata, codeArr: codeArr, subFolder: null }; } + /** - * helper for {@link Script.parseMetadata} and {@link Script._buildForNested} + * helper for {@link Script.postRetrieveTasks} and {@link Script._buildForNested} * * @param {string} metadataScript the code of the file * @param {string} metadataName the name of the metadata From 3c96236f9e7c6b1815a246969d6ac4729ecfad29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Mon, 29 Jan 2024 15:55:14 +0100 Subject: [PATCH 09/11] #164: support delete for asset --- docs/dist/documentation.md | 26 +++++ lib/metadataTypes/Asset.js | 60 ++++++++++ test/resourceFactory.js | 62 ++++++++++- .../content/assets/950143/delete-response.txt | 1 + ...sponse-customerKey=testExisting_asset.json | 105 ++++++++++++++++++ test/type.asset.test.js | 14 +++ 6 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 test/resources/9999999/asset/v1/content/assets/950143/delete-response.txt create mode 100644 test/resources/9999999/asset/v1/content/assets/get-response-customerKey=testExisting_asset.json diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index b441b4e3f..9cec6282b 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -891,6 +891,8 @@ FileTransfer MetadataType * [.findSubType(templateDir, templateName)](#Asset.findSubType) ⇒ Promise.<TYPE.AssetSubType> * [.readSecondaryFolder(templateDir, typeDirArr, templateName, fileName)](#Asset.readSecondaryFolder) ⇒ TYPE.AssetItem * [.getFilesToCommit(keyArr)](#Asset.getFilesToCommit) ⇒ Array.<string> + * [.deleteByKey(customerKey)](#Asset.deleteByKey) ⇒ boolean + * [.postDeleteTasks(customerKey)](#Asset.postDeleteTasks) ⇒ void @@ -1266,6 +1268,30 @@ additionally, the documentation for dataExtension and automation should be retur | --- | --- | --- | | keyArr | Array.<string> | customerkey of the metadata | + + +### Asset.deleteByKey(customerKey) ⇒ boolean +Delete a metadata item from the specified business unit + +**Kind**: static method of [Asset](#Asset) +**Returns**: boolean - deletion success status + +| Param | Type | Description | +| --- | --- | --- | +| customerKey | string | Identifier of data extension | + + + +### Asset.postDeleteTasks(customerKey) ⇒ void +clean up after deleting a metadata item +cannot use the generic method due to the complexity of how assets are saved to disk + +**Kind**: static method of [Asset](#Asset) + +| Param | Type | Description | +| --- | --- | --- | +| customerKey | string | Identifier of metadata item | + ## AttributeGroup ⇐ [MetadataType](#MetadataType) diff --git a/lib/metadataTypes/Asset.js b/lib/metadataTypes/Asset.js index 61f5517c7..61ea7b52a 100644 --- a/lib/metadataTypes/Asset.js +++ b/lib/metadataTypes/Asset.js @@ -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.} 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 {boolean} deletion success status + */ + 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 diff --git a/test/resourceFactory.js b/test/resourceFactory.js index 30407d340..e9141d0a9 100644 --- a/test/resourceFactory.js +++ b/test/resourceFactory.js @@ -252,8 +252,52 @@ export const handleRESTRequest = async (config) => { config.method + '-response' ) .replace(':', '_'); // replace : with _ for Windows + const testPathFilter = filterName + ? testPath + + '-' + + urlObj.searchParams.get('$filter').replaceAll(' eq ', '=').replaceAll(' ', '') + : null; + if (testPathFilter && (await fs.pathExists(testPathFilter + '.json'))) { + // build filter logic to ensure templating works + if (filterName) { + const response = JSON.parse( + await fs.readFile(testPathFilter + '.json', { + encoding: 'utf8', + }) + ); + response.items = response.items.filter((def) => def.name == filterName); + response.count = response.items.length; + return [200, JSON.stringify(response)]; + } else { + return [ + 200, + await fs.readFile(testPathFilter + '.json', { + encoding: 'utf8', + }), + ]; + } + } else if (testPathFilter && (await fs.pathExists(testPathFilter + '.txt'))) { + return [ + 200, + await fs.readFile(testPathFilter + '.txt', { + encoding: 'utf8', + }), + ]; + } else if (await fs.pathExists(testPath + '.json')) { + if (testPathFilter) { + /* eslint-disable no-console */ + console.log( + `${color.bgYellow}${color.fgBlack}TEST-WARNING${ + color.reset + }: You are loading your reponse from ${ + testPath + '.json' + } instead of the more specific ${ + testPathFilter + '.json' + }. Make sure this is intended` + ); + /* eslint-enable no-console */ + } - if (await fs.pathExists(testPath + '.json')) { // build filter logic to ensure templating works if (filterName) { const response = JSON.parse( @@ -273,6 +317,20 @@ export const handleRESTRequest = async (config) => { ]; } } else if (await fs.pathExists(testPath + '.txt')) { + if (testPathFilter) { + /* eslint-disable no-console */ + console.log( + `${color.bgYellow}${color.fgBlack}TEST-WARNING${ + color.reset + }: You are loading your reponse from ${ + testPath + '.txt' + } instead of the more specific ${ + testPathFilter + '.txt' + }. Make sure this is intended` + ); + /* eslint-enable no-console */ + } + return [ 200, await fs.readFile(testPath + '.txt', { @@ -282,7 +340,7 @@ export const handleRESTRequest = async (config) => { } else { /* eslint-disable no-console */ console.log( - `${color.bgRed}${color.fgBlack}TEST-ERROR${color.reset}: Please create file ${testPath}.json/.txt` + `${color.bgRed}${color.fgBlack}TEST-ERROR${color.reset}: Please create file ${testPath}.json/.txt${filterName ? ` or ${testPathFilter}.json/.txt` : ''}` ); /* eslint-enable no-console */ process.exitCode = 404; diff --git a/test/resources/9999999/asset/v1/content/assets/950143/delete-response.txt b/test/resources/9999999/asset/v1/content/assets/950143/delete-response.txt new file mode 100644 index 000000000..d86bac9de --- /dev/null +++ b/test/resources/9999999/asset/v1/content/assets/950143/delete-response.txt @@ -0,0 +1 @@ +OK diff --git a/test/resources/9999999/asset/v1/content/assets/get-response-customerKey=testExisting_asset.json b/test/resources/9999999/asset/v1/content/assets/get-response-customerKey=testExisting_asset.json new file mode 100644 index 000000000..0964cfb60 --- /dev/null +++ b/test/resources/9999999/asset/v1/content/assets/get-response-customerKey=testExisting_asset.json @@ -0,0 +1,105 @@ +{ + "count": 1, + "page": 1, + "pageSize": 50, + "links": {}, + "items": [ + { + "id": 950143, + "customerKey": "testExisting_asset", + "objectID": "198ad191-59ae-44d1-9981-ffa71b076ad9", + "contentType": "text/html", + "assetType": { + "id": 205, + "name": "webpage", + "displayName": "Web Page" + }, + "version": 1, + "name": "testExisting_asset", + "owner": { + "id": 717319337, + "email": "joern.berkefeld@accenture.com", + "name": "Jörn Berkefeld", + "userId": "717319337" + }, + "createdDate": "2021-09-13T12:14:02.32-06:00", + "createdBy": { + "id": 717319337, + "email": "joern.berkefeld@accenture.com", + "name": "Jörn Berkefeld", + "userId": "717319337" + }, + "modifiedDate": "2023-08-02T07:10:29.553-06:00", + "modifiedBy": { + "id": 700304523, + "name": "SFMC DEVOPS app user", + "userId": "700304523" + }, + "enterpriseId": 111111, + "memberId": 999999, + "status": { + "id": 1, + "name": "Draft" + }, + "thumbnail": { + "thumbnailUrl": "/v1/assets/950143/thumbnail" + }, + "category": { + "id": 667369 + }, + "meta": { + "globalStyles": { + "isLocked": false, + "body": { + "max-width": "1280px", + "color": "#000000", + "font-family": "Arial", + "font-size": "12px", + "margin": "0px auto" + }, + "template": { + "background-color": "#FFFFFF", + "border": "none", + "box-sizing": "border-box", + "padding": "0px", + "width": "100%" + } + } + }, + "views": { + "html": { + "thumbnail": {}, + "content": "\n\n \n \n \n \n \n \n
\n
\n
\n
\n
\n
\n
\n \n\n", + "slots": { + "col1": { + "content": "
", + "design": "

Drop blocks or content here

", + "blocks": { + "bgbqbbx4we9": { + "assetType": { + "id": 197, + "name": "htmlblock" + }, + "content": "
\n%%[FOR @I=1 TO 1000 DO\n SET @a = CONCAT(IIF(MOD(@i, 3)==0, \"Fizz\", \"\"), IIF(MOD(@i,5)==0,\"Buzz\",\"\"), IIF(MOD(@i, 7)==0, \"Boing\", \"\"), IIF(MOD(@i,11)==0,\"Bang\",\"\"))\nOUTPUT(CONCAT(@a, IIF(LENGTH(@a)>0, \"\", @i), \"
\"))NEXT @i\n]%%\n
", + "design": "
", + "meta": { + "wrapperStyles": { + "mobile": { + "visible": true + } + } + }, + "modelVersion": 2 + } + }, + "modelVersion": 2 + } + }, + "modelVersion": 2 + } + }, + "availableViews": ["html"], + "modelVersion": 2 + } + ] +} diff --git a/test/type.asset.test.js b/test/type.asset.test.js index df709ace5..959ce797e 100644 --- a/test/type.asset.test.js +++ b/test/type.asset.test.js @@ -81,4 +81,18 @@ describe('type: asset', () => { return; }); }); + describe('Delete ================', () => { + it('Should delete the item', async () => { + // WHEN + const isDeleted = await handler.deleteByKey( + 'testInstance/testBU', + 'asset', + 'testExisting_asset' + ); + // THEN + assert.equal(process.exitCode, 0, 'deleteByKey should not have thrown an error'); + assert.equal(isDeleted, true, 'deleteByKey should have returned true'); + return; + }); + }); }); From b60afe8d3218cf5853e8642075c7b8235ec37377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Mon, 29 Jan 2024 16:11:54 +0100 Subject: [PATCH 10/11] #164: jsdoc cleanup --- docs/dist/documentation.md | 48 +++++++++++++++---------------- lib/metadataTypes/Asset.js | 2 +- lib/metadataTypes/DataExtract.js | 2 +- lib/metadataTypes/FileTransfer.js | 2 +- lib/metadataTypes/ImportFile.js | 2 +- lib/metadataTypes/MetadataType.js | 4 +-- lib/metadataTypes/Query.js | 2 +- lib/metadataTypes/Script.js | 2 +- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 9cec6282b..10baca458 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -891,7 +891,7 @@ FileTransfer MetadataType * [.findSubType(templateDir, templateName)](#Asset.findSubType) ⇒ Promise.<TYPE.AssetSubType> * [.readSecondaryFolder(templateDir, typeDirArr, templateName, fileName)](#Asset.readSecondaryFolder) ⇒ TYPE.AssetItem * [.getFilesToCommit(keyArr)](#Asset.getFilesToCommit) ⇒ Array.<string> - * [.deleteByKey(customerKey)](#Asset.deleteByKey) ⇒ boolean + * [.deleteByKey(customerKey)](#Asset.deleteByKey) ⇒ Promise.<boolean> * [.postDeleteTasks(customerKey)](#Asset.postDeleteTasks) ⇒ void @@ -1270,11 +1270,11 @@ additionally, the documentation for dataExtension and automation should be retur -### Asset.deleteByKey(customerKey) ⇒ boolean +### Asset.deleteByKey(customerKey) ⇒ Promise.<boolean> Delete a metadata item from the specified business unit **Kind**: static method of [Asset](#Asset) -**Returns**: boolean - deletion success status +**Returns**: Promise.<boolean> - deletion success flag | Param | Type | Description | | --- | --- | --- | @@ -2244,7 +2244,7 @@ DataExtract MetadataType * [.update(dataExtract)](#DataExtract.update) ⇒ Promise * [.preDeployTasks(metadata)](#DataExtract.preDeployTasks) ⇒ TYPE.MetadataTypeItem * [.postRetrieveTasks(metadata)](#DataExtract.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem - * [.deleteByKey(customerKey)](#DataExtract.deleteByKey) ⇒ boolean + * [.deleteByKey(customerKey)](#DataExtract.deleteByKey) ⇒ Promise.<boolean> @@ -2333,11 +2333,11 @@ manages post retrieve steps -### DataExtract.deleteByKey(customerKey) ⇒ boolean +### DataExtract.deleteByKey(customerKey) ⇒ Promise.<boolean> Delete a metadata item from the specified business unit **Kind**: static method of [DataExtract](#DataExtract) -**Returns**: boolean - deletion success status +**Returns**: Promise.<boolean> - deletion success flag | Param | Type | Description | | --- | --- | --- | @@ -2743,7 +2743,7 @@ FileTransfer MetadataType * [.update(fileTransfer)](#FileTransfer.update) ⇒ Promise * [.preDeployTasks(metadata)](#FileTransfer.preDeployTasks) ⇒ Promise * [.postRetrieveTasks(metadata)](#FileTransfer.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem - * [.deleteByKey(customerKey)](#FileTransfer.deleteByKey) ⇒ boolean + * [.deleteByKey(customerKey)](#FileTransfer.deleteByKey) ⇒ Promise.<boolean> @@ -2832,11 +2832,11 @@ manages post retrieve steps -### FileTransfer.deleteByKey(customerKey) ⇒ boolean +### FileTransfer.deleteByKey(customerKey) ⇒ Promise.<boolean> Delete a metadata item from the specified business unit **Kind**: static method of [FileTransfer](#FileTransfer) -**Returns**: boolean - deletion success status +**Returns**: Promise.<boolean> - deletion success flag | Param | Type | Description | | --- | --- | --- | @@ -3034,7 +3034,7 @@ ImportFile MetadataType * [.update(importFile)](#ImportFile.update) ⇒ Promise * [.preDeployTasks(metadata)](#ImportFile.preDeployTasks) ⇒ Promise * [.postRetrieveTasks(metadata)](#ImportFile.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem - * [.deleteByKey(customerKey)](#ImportFile.deleteByKey) ⇒ boolean + * [.deleteByKey(customerKey)](#ImportFile.deleteByKey) ⇒ Promise.<boolean> @@ -3131,11 +3131,11 @@ manages post retrieve steps -### ImportFile.deleteByKey(customerKey) ⇒ boolean +### ImportFile.deleteByKey(customerKey) ⇒ Promise.<boolean> Delete a metadata item from the specified business unit **Kind**: static method of [ImportFile](#ImportFile) -**Returns**: boolean - deletion success status +**Returns**: Promise.<boolean> - deletion success flag | Param | Type | Description | | --- | --- | --- | @@ -3444,8 +3444,8 @@ Provides default functionality that can be overwritten by child metadata type cl * [.document([metadata], [isDeploy])](#MetadataType.document) ⇒ void * [.deleteByKey(customerKey)](#MetadataType.deleteByKey) ⇒ boolean * [.postDeleteTasks(customerKey, [additionalExtensions])](#MetadataType.postDeleteTasks) ⇒ Promise.<void> - * [.deleteByKeySOAP(customerKey, [overrideKeyField], [handleOutside])](#MetadataType.deleteByKeySOAP) ⇒ boolean - * [.deleteByKeyREST(url, key, [handleOutside])](#MetadataType.deleteByKeyREST) ⇒ boolean + * [.deleteByKeySOAP(customerKey, [overrideKeyField], [handleOutside])](#MetadataType.deleteByKeySOAP) ⇒ Promise.<boolean> + * [.deleteByKeyREST(url, key, [handleOutside])](#MetadataType.deleteByKeyREST) ⇒ Promise.<boolean> * [.readBUMetadataForType(readDir, [listBadKeys], [buMetadata])](#MetadataType.readBUMetadataForType) ⇒ object * [.getFilesToCommit(keyArr)](#MetadataType.getFilesToCommit) ⇒ Promise.<Array.<string>> * [.getKeysForFixing(metadataMap)](#MetadataType.getKeysForFixing) ⇒ Array.<string> @@ -4239,11 +4239,11 @@ clean up after deleting a metadata item -### MetadataType.deleteByKeySOAP(customerKey, [overrideKeyField], [handleOutside]) ⇒ boolean +### MetadataType.deleteByKeySOAP(customerKey, [overrideKeyField], [handleOutside]) ⇒ Promise.<boolean> Delete a data extension from the specified business unit **Kind**: static method of [MetadataType](#MetadataType) -**Returns**: boolean - deletion success flag +**Returns**: Promise.<boolean> - deletion success flag | Param | Type | Description | | --- | --- | --- | @@ -4253,11 +4253,11 @@ Delete a data extension from the specified business unit -### MetadataType.deleteByKeyREST(url, key, [handleOutside]) ⇒ boolean +### MetadataType.deleteByKeyREST(url, key, [handleOutside]) ⇒ Promise.<boolean> Delete a data extension from the specified business unit **Kind**: static method of [MetadataType](#MetadataType) -**Returns**: boolean - deletion success flag +**Returns**: Promise.<boolean> - deletion success flag | Param | Type | Description | | --- | --- | --- | @@ -4887,7 +4887,7 @@ Query MetadataType * [.buildTemplateForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#Query.buildTemplateForNested) ⇒ Promise.<Array.<Array.<string>>> * [.getFilesToCommit(keyArr)](#Query.getFilesToCommit) ⇒ Array.<string> * [.getErrorsREST(ex)](#Query.getErrorsREST) ⇒ Array.<string> \| void - * [.deleteByKey(customerKey)](#Query.deleteByKey) ⇒ boolean + * [.deleteByKey(customerKey)](#Query.deleteByKey) ⇒ Promise.<boolean> * [.postDeleteTasks(customerKey)](#Query.postDeleteTasks) ⇒ void * [.postDeployTasks(upsertResults)](#Query.postDeployTasks) @@ -5067,11 +5067,11 @@ Standardizes a check for multiple messages but adds query specific filters to er -### Query.deleteByKey(customerKey) ⇒ boolean +### Query.deleteByKey(customerKey) ⇒ Promise.<boolean> Delete a metadata item from the specified business unit **Kind**: static method of [Query](#Query) -**Returns**: boolean - deletion success status +**Returns**: Promise.<boolean> - deletion success flag | Param | Type | Description | | --- | --- | --- | @@ -5214,7 +5214,7 @@ Script MetadataType * [.postRetrieveTasks(metadata)](#Script.postRetrieveTasks) ⇒ TYPE.CodeExtractItem * [.prepExtractedCode(metadataScript, metadataName)](#Script.prepExtractedCode) ⇒ Object * [.getFilesToCommit(keyArr)](#Script.getFilesToCommit) ⇒ Array.<string> - * [.deleteByKey(customerKey)](#Script.deleteByKey) ⇒ boolean + * [.deleteByKey(customerKey)](#Script.deleteByKey) ⇒ Promise.<boolean> * [.postDeleteTasks(customerKey)](#Script.postDeleteTasks) ⇒ void @@ -5401,11 +5401,11 @@ additionally, the documentation for dataExtension and automation should be retur -### Script.deleteByKey(customerKey) ⇒ boolean +### Script.deleteByKey(customerKey) ⇒ Promise.<boolean> Delete a metadata item from the specified business unit **Kind**: static method of [Script](#Script) -**Returns**: boolean - deletion success status +**Returns**: Promise.<boolean> - deletion success flag | Param | Type | Description | | --- | --- | --- | diff --git a/lib/metadataTypes/Asset.js b/lib/metadataTypes/Asset.js index 61ea7b52a..badfeb065 100644 --- a/lib/metadataTypes/Asset.js +++ b/lib/metadataTypes/Asset.js @@ -1654,7 +1654,7 @@ class Asset 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.} deletion success flag */ static async deleteByKey(customerKey) { // delete only works with the query's object id diff --git a/lib/metadataTypes/DataExtract.js b/lib/metadataTypes/DataExtract.js index 01dc2e8e4..1d50cd458 100644 --- a/lib/metadataTypes/DataExtract.js +++ b/lib/metadataTypes/DataExtract.js @@ -169,7 +169,7 @@ class DataExtract 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.} deletion success flag */ static async deleteByKey(customerKey) { // delete only works with the query's object id diff --git a/lib/metadataTypes/FileTransfer.js b/lib/metadataTypes/FileTransfer.js index 6fc6310d5..494f77fe9 100644 --- a/lib/metadataTypes/FileTransfer.js +++ b/lib/metadataTypes/FileTransfer.js @@ -175,7 +175,7 @@ class FileTransfer 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.} deletion success flag */ static async deleteByKey(customerKey) { // delete only works with the query's object id diff --git a/lib/metadataTypes/ImportFile.js b/lib/metadataTypes/ImportFile.js index 4199931b2..447e1c0e4 100644 --- a/lib/metadataTypes/ImportFile.js +++ b/lib/metadataTypes/ImportFile.js @@ -280,7 +280,7 @@ class ImportFile 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.} deletion success flag */ static async deleteByKey(customerKey) { // delete only works with the query's object id diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 874515599..bea4107c7 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -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.} deletion success flag */ static async deleteByKeySOAP(customerKey, overrideKeyField, handleOutside) { const metadata = {}; @@ -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.} deletion success flag */ static async deleteByKeyREST(url, key, handleOutside) { try { diff --git a/lib/metadataTypes/Query.js b/lib/metadataTypes/Query.js index a7cd501a7..1fffc67d2 100644 --- a/lib/metadataTypes/Query.js +++ b/lib/metadataTypes/Query.js @@ -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.} deletion success flag */ static async deleteByKey(customerKey) { // delete only works with the query's object id diff --git a/lib/metadataTypes/Script.js b/lib/metadataTypes/Script.js index 63f1979c6..702cdfb33 100644 --- a/lib/metadataTypes/Script.js +++ b/lib/metadataTypes/Script.js @@ -339,7 +339,7 @@ class Script 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.} deletion success flag */ static async deleteByKey(customerKey) { // delete only works with the query's object id From f067b063e7c424662add5db3a6e7e913e55f91bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Mon, 29 Jan 2024 16:14:51 +0100 Subject: [PATCH 11/11] #164: cleanup --- .../assets/get-response-customerKey=testExisting_asset.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/resources/9999999/asset/v1/content/assets/get-response-customerKey=testExisting_asset.json b/test/resources/9999999/asset/v1/content/assets/get-response-customerKey=testExisting_asset.json index 0964cfb60..6c91edf43 100644 --- a/test/resources/9999999/asset/v1/content/assets/get-response-customerKey=testExisting_asset.json +++ b/test/resources/9999999/asset/v1/content/assets/get-response-customerKey=testExisting_asset.json @@ -81,7 +81,7 @@ "name": "htmlblock" }, "content": "
\n%%[FOR @I=1 TO 1000 DO\n SET @a = CONCAT(IIF(MOD(@i, 3)==0, \"Fizz\", \"\"), IIF(MOD(@i,5)==0,\"Buzz\",\"\"), IIF(MOD(@i, 7)==0, \"Boing\", \"\"), IIF(MOD(@i,11)==0,\"Bang\",\"\"))\nOUTPUT(CONCAT(@a, IIF(LENGTH(@a)>0, \"\", @i), \"
\"))NEXT @i\n]%%\n
", - "design": "
", + "design": "
", "meta": { "wrapperStyles": { "mobile": {