From fe220e828c60864c02a33404dd1a72affd31acce Mon Sep 17 00:00:00 2001 From: "tulio.natale@accenture.com" Date: Mon, 25 Jul 2022 10:46:27 +0200 Subject: [PATCH 001/208] #78 added function in util.js that checks if the absolute path of the git repo contains words found on cloud services --- docs/dist/documentation.md | 26 ++++++++++++++++++++++++++ lib/index.js | 5 +++++ lib/util/util.js | 19 +++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index b152b9722..2a3c0907f 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -4445,6 +4445,7 @@ CLI entry for SFMC DevTools * [.getRetrieveTypeChoices()](#Util.getRetrieveTypeChoices) ⇒ Array.<TYPE.SupportedMetadataTypes> * [.metadataLogger(level, type, method, payload, [source])](#Util.metadataLogger) ⇒ void * [.replaceByObject(str, obj)](#Util.replaceByObject) ⇒ string \| object + * [.checkPathForCloud(absolutePath)](#Util.checkPathForCloud) ⇒ void * [.inverseGet(objs, val)](#Util.inverseGet) ⇒ string * [.getMetadataHierachy(metadataTypes)](#Util.getMetadataHierachy) ⇒ Array.<string> * [.resolveObjPath(path, obj)](#Util.resolveObjPath) ⇒ any @@ -4605,6 +4606,18 @@ key-value pairs (obj) | str | string \| object | JSON object or its stringified version, which has values to be replaced | | obj | TYPE.TemplateMap | key value object which contains keys to be replaced and values to be replaced with | + + +### Util.checkPathForCloud(absolutePath) ⇒ void +check if git repo is being saved on a cloud service and warns the user + +**Kind**: static method of [Util](#Util) +**Returns**: void - throws errors if problems were found + +| Param | Type | Description | +| --- | --- | --- | +| absolutePath | string | path from root to the project | + ### Util.inverseGet(objs, val) ⇒ string @@ -6197,6 +6210,7 @@ Util that contains logger and simple util methods * [.getRetrieveTypeChoices()](#Util.getRetrieveTypeChoices) ⇒ Array.<TYPE.SupportedMetadataTypes> * [.metadataLogger(level, type, method, payload, [source])](#Util.metadataLogger) ⇒ void * [.replaceByObject(str, obj)](#Util.replaceByObject) ⇒ string \| object + * [.checkPathForCloud(absolutePath)](#Util.checkPathForCloud) ⇒ void * [.inverseGet(objs, val)](#Util.inverseGet) ⇒ string * [.getMetadataHierachy(metadataTypes)](#Util.getMetadataHierachy) ⇒ Array.<string> * [.resolveObjPath(path, obj)](#Util.resolveObjPath) ⇒ any @@ -6357,6 +6371,18 @@ key-value pairs (obj) | str | string \| object | JSON object or its stringified version, which has values to be replaced | | obj | TYPE.TemplateMap | key value object which contains keys to be replaced and values to be replaced with | + + +### Util.checkPathForCloud(absolutePath) ⇒ void +check if git repo is being saved on a cloud service and warns the user + +**Kind**: static method of [Util](#Util) +**Returns**: void - throws errors if problems were found + +| Param | Type | Description | +| --- | --- | --- | +| absolutePath | string | path from root to the project | + ### Util.inverseGet(objs, val) ⇒ string diff --git a/lib/index.js b/lib/index.js index cdf2926f8..9223ab376 100644 --- a/lib/index.js +++ b/lib/index.js @@ -16,6 +16,7 @@ const MetadataTypeInfo = require('./MetadataTypeInfo'); const MetadataTypeDefinitions = require('./MetadataTypeDefinitions'); const Retriever = require('./Retriever'); const cache = require('./util/cache'); +const path = require('node:path'); /** * main class @@ -90,6 +91,8 @@ class Mcdev { static async upgrade(skipInteraction) { Mcdev.setSkipInteraction(skipInteraction); const properties = await config.getProperties(); + const absolutePath = path.resolve(''); + Util.checkPathForCloud(absolutePath); if (!properties) { Util.logger.error('No config found. Please run mcdev init'); return false; @@ -290,6 +293,8 @@ class Mcdev { */ static async initProject(credentialsName, skipInteraction) { Util.logger.info('mcdev:: Setting up project'); + const absolutePath = path.resolve(''); + Util.checkPathForCloud(absolutePath); Mcdev.setSkipInteraction(skipInteraction); const properties = await config.getProperties(!!credentialsName); await Init.initProject(properties, credentialsName, skipInteraction); diff --git a/lib/util/util.js b/lib/util/util.js index 9099a3815..c2d109825 100644 --- a/lib/util/util.js +++ b/lib/util/util.js @@ -79,6 +79,7 @@ const Util = { return false; } }, + /** * ensure provided MarketList exists and it's content including markets and BUs checks out * @@ -272,6 +273,24 @@ const Util = { } return str; }, + + /** + * check if git repo is being saved on a cloud service and warns the user + * + * @param {string} absolutePath path from root to the project + * @returns {void} throws errors if problems were found + */ + checkPathForCloud(absolutePath) { + // popular cloud services and their respective default name for the absolute path + const cloudServices = ['Dropbox', 'OneDrive', 'CloudDocs', 'Google Drive', 'Cloud']; + for (const variable in cloudServices) { + if (absolutePath.includes(cloudServices[variable])) { + Util.logger.warn( + `the git repo is being saved in '${cloudServices[variable]}' and can reduce performance together with git` + ); + } + } + }, /** * get key of an object based on the first matching value * From f9a880c2671c6e99e964ebf9b25a7b30ff97590f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 1 Mar 2023 11:54:42 +0100 Subject: [PATCH 002/208] #711: rename type setDefinition to attributeSetDefinition --- docs/dist/documentation.md | 74 +++++++++---------- lib/MetadataTypeDefinitions.js | 2 +- lib/MetadataTypeInfo.js | 2 +- ...efinition.js => AttributeSetDefinition.js} | 8 +- ...s => AttributeSetDefinition.definition.js} | 2 +- 5 files changed, 44 insertions(+), 44 deletions(-) rename lib/metadataTypes/{SetDefinition.js => AttributeSetDefinition.js} (82%) rename lib/metadataTypes/definitions/{SetDefinition.definition.js => AttributeSetDefinition.definition.js} (99%) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index d720bfd89..e32410bf0 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -20,6 +20,9 @@ Source and target business units are also compared before the deployment to appl
AttributeGroupMetadataType

AttributeGroup MetadataType

+
AttributeSetDefinitionMetadataType
+

AttributeSetDefinition MetadataType

+
AutomationMetadataType

Automation MetadataType

@@ -105,9 +108,6 @@ Provides default functionality that can be overwritten by child metadata type cl
SendClassificationMetadataType

SendClassification MetadataType

-
SetDefinitionMetadataType
-

SetDefinition MetadataType

-
TransactionalEmailTransactionalMessage

TransactionalEmail MetadataType

@@ -1230,6 +1230,40 @@ Retrieves Metadata of schema attribute groups for caching. **Kind**: static method of [AttributeGroup](#AttributeGroup) **Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of metadata + + +## AttributeSetDefinition ⇐ [MetadataType](#MetadataType) +AttributeSetDefinition MetadataType + +**Kind**: global class +**Extends**: [MetadataType](#MetadataType) + +* [AttributeSetDefinition](#AttributeSetDefinition) ⇐ [MetadataType](#MetadataType) + * [.retrieve(retrieveDir, [_], [__], [key])](#AttributeSetDefinition.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> + * [.retrieveForCache()](#AttributeSetDefinition.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> + + + +### AttributeSetDefinition.retrieve(retrieveDir, [_], [__], [key]) ⇒ Promise.<TYPE.MetadataTypeMapObj> +Retrieves Metadata of schema set Definitions. + +**Kind**: static method of [AttributeSetDefinition](#AttributeSetDefinition) +**Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise + +| Param | Type | Description | +| --- | --- | --- | +| retrieveDir | string | Directory where retrieved metadata directory will be saved | +| [_] | void | unused parameter | +| [__] | void | unused parameter | +| [key] | string | customer key of single item to retrieve | + + + +### AttributeSetDefinition.retrieveForCache() ⇒ Promise.<TYPE.MetadataTypeMapObj> +Retrieves Metadata of schema set definitions for caching. + +**Kind**: static method of [AttributeSetDefinition](#AttributeSetDefinition) +**Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise ## Automation ⇐ [MetadataType](#MetadataType) @@ -4582,40 +4616,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 | - - -## SetDefinition ⇐ [MetadataType](#MetadataType) -SetDefinition MetadataType - -**Kind**: global class -**Extends**: [MetadataType](#MetadataType) - -* [SetDefinition](#SetDefinition) ⇐ [MetadataType](#MetadataType) - * [.retrieve(retrieveDir, [_], [__], [key])](#SetDefinition.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> - * [.retrieveForCache()](#SetDefinition.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> - - - -### SetDefinition.retrieve(retrieveDir, [_], [__], [key]) ⇒ Promise.<TYPE.MetadataTypeMapObj> -Retrieves Metadata of schema set Definitions. - -**Kind**: static method of [SetDefinition](#SetDefinition) -**Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise - -| Param | Type | Description | -| --- | --- | --- | -| retrieveDir | string | Directory where retrieved metadata directory will be saved | -| [_] | void | unused parameter | -| [__] | void | unused parameter | -| [key] | string | customer key of single item to retrieve | - - - -### SetDefinition.retrieveForCache() ⇒ Promise.<TYPE.MetadataTypeMapObj> -Retrieves Metadata of schema set definitions for caching. - -**Kind**: static method of [SetDefinition](#SetDefinition) -**Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise ## TransactionalEmail ⇐ [TransactionalMessage](#TransactionalMessage) diff --git a/lib/MetadataTypeDefinitions.js b/lib/MetadataTypeDefinitions.js index 021564d0c..a4d6c1fed 100644 --- a/lib/MetadataTypeDefinitions.js +++ b/lib/MetadataTypeDefinitions.js @@ -7,6 +7,7 @@ const MetadataTypeDefinitions = { accountUser: require('./metadataTypes/definitions/AccountUser.definition'), asset: require('./metadataTypes/definitions/Asset.definition'), attributeGroup: require('./metadataTypes/definitions/AttributeGroup.definition'), + attributeSetDefinition: require('./metadataTypes/definitions/AttributeSetDefinition.definition'), automation: require('./metadataTypes/definitions/Automation.definition'), campaign: require('./metadataTypes/definitions/Campaign.definition'), contentArea: require('./metadataTypes/definitions/ContentArea.definition'), @@ -32,7 +33,6 @@ const MetadataTypeDefinitions = { role: require('./metadataTypes/definitions/Role.definition'), script: require('./metadataTypes/definitions/Script.definition'), sendClassification: require('./metadataTypes/definitions/SendClassification.definition'), - setDefinition: require('./metadataTypes/definitions/SetDefinition.definition'), transactionalEmail: require('./metadataTypes/definitions/TransactionalEmail.definition'), transactionalPush: require('./metadataTypes/definitions/TransactionalPush.definition'), transactionalSMS: require('./metadataTypes/definitions/TransactionalSMS.definition'), diff --git a/lib/MetadataTypeInfo.js b/lib/MetadataTypeInfo.js index 8f6db645b..dbc6e1722 100644 --- a/lib/MetadataTypeInfo.js +++ b/lib/MetadataTypeInfo.js @@ -7,6 +7,7 @@ const MetadataTypeInfo = { accountUser: require('./metadataTypes/AccountUser'), asset: require('./metadataTypes/Asset'), attributeGroup: require('./metadataTypes/AttributeGroup'), + attributeSetDefinition: require('./metadataTypes/AttributeSetDefinition'), automation: require('./metadataTypes/Automation'), campaign: require('./metadataTypes/Campaign'), contentArea: require('./metadataTypes/ContentArea'), @@ -32,7 +33,6 @@ const MetadataTypeInfo = { role: require('./metadataTypes/Role'), script: require('./metadataTypes/Script'), sendClassification: require('./metadataTypes/SendClassification'), - setDefinition: require('./metadataTypes/SetDefinition'), transactionalEmail: require('./metadataTypes/TransactionalEmail'), transactionalPush: require('./metadataTypes/TransactionalPush'), transactionalSMS: require('./metadataTypes/TransactionalSMS'), diff --git a/lib/metadataTypes/SetDefinition.js b/lib/metadataTypes/AttributeSetDefinition.js similarity index 82% rename from lib/metadataTypes/SetDefinition.js rename to lib/metadataTypes/AttributeSetDefinition.js index bcbf64ff0..625920be0 100644 --- a/lib/metadataTypes/SetDefinition.js +++ b/lib/metadataTypes/AttributeSetDefinition.js @@ -4,11 +4,11 @@ const TYPE = require('../../types/mcdev.d'); const MetadataType = require('./MetadataType'); /** - * SetDefinition MetadataType + * AttributeSetDefinition MetadataType * * @augments MetadataType */ -class SetDefinition extends MetadataType { +class AttributeSetDefinition extends MetadataType { /** * Retrieves Metadata of schema set Definitions. * @@ -38,6 +38,6 @@ class SetDefinition extends MetadataType { } // Assign definition to static attributes -SetDefinition.definition = require('../MetadataTypeDefinitions').setDefinition; +AttributeSetDefinition.definition = require('../MetadataTypeDefinitions').attributeSetDefinition; -module.exports = SetDefinition; +module.exports = AttributeSetDefinition; diff --git a/lib/metadataTypes/definitions/SetDefinition.definition.js b/lib/metadataTypes/definitions/AttributeSetDefinition.definition.js similarity index 99% rename from lib/metadataTypes/definitions/SetDefinition.definition.js rename to lib/metadataTypes/definitions/AttributeSetDefinition.definition.js index e5b7f9176..b30ea4a2b 100644 --- a/lib/metadataTypes/definitions/SetDefinition.definition.js +++ b/lib/metadataTypes/definitions/AttributeSetDefinition.definition.js @@ -10,7 +10,7 @@ module.exports = { lastmodDateField: null, lastmodNameField: null, restPagination: false, - type: 'setDefinition', + type: 'AttributeSetDefinition', typeDescription: 'BETA: Data Extensions linked to Attribute Groups in Data Designer.', typeRetrieveByDefault: false, typeName: 'Data Designer Set Definitions', From 390ccfceab5548089c8e343136ffa8189656f7dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 1 Mar 2023 16:21:58 +0100 Subject: [PATCH 003/208] #711: resolve attributeSets and attributeGroups as preDeploy/postRetrieve task --- docs/dist/documentation.md | 66 +++++ lib/metadataTypes/AttributeGroup.js | 71 ++++- lib/metadataTypes/AttributeSetDefinition.js | 275 +++++++++++++++++- .../definitions/AttributeGroup.definition.js | 80 ++--- .../AttributeSetDefinition.definition.js | 5 +- 5 files changed, 452 insertions(+), 45 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index e32410bf0..f7b4c17b3 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -1207,6 +1207,8 @@ AttributeGroup MetadataType * [AttributeGroup](#AttributeGroup) ⇐ [MetadataType](#MetadataType) * [.retrieve(retrieveDir, [_], [__], [key])](#AttributeGroup.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveForCache()](#AttributeGroup.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> + * [.postRetrieveTasks(metadata)](#AttributeGroup.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem + * [.preDeployTasks(metadata)](#AttributeGroup.preDeployTasks) ⇒ TYPE.MetadataTypeItem @@ -1230,6 +1232,30 @@ Retrieves Metadata of schema attribute groups for caching. **Kind**: static method of [AttributeGroup](#AttributeGroup) **Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of metadata + + +### AttributeGroup.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem +manages post retrieve steps + +**Kind**: static method of [AttributeGroup](#AttributeGroup) +**Returns**: TYPE.MetadataTypeItem - metadata + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.MetadataTypeItem | a single metadata | + + + +### AttributeGroup.preDeployTasks(metadata) ⇒ TYPE.MetadataTypeItem +prepares for deployment + +**Kind**: static method of [AttributeGroup](#AttributeGroup) +**Returns**: TYPE.MetadataTypeItem - Promise + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.MetadataTypeItem | a single item | + ## AttributeSetDefinition ⇐ [MetadataType](#MetadataType) @@ -1241,6 +1267,9 @@ AttributeSetDefinition MetadataType * [AttributeSetDefinition](#AttributeSetDefinition) ⇐ [MetadataType](#MetadataType) * [.retrieve(retrieveDir, [_], [__], [key])](#AttributeSetDefinition.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveForCache()](#AttributeSetDefinition.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> + * [.parseResponseBody(body, [singleRetrieve])](#AttributeSetDefinition.parseResponseBody) ⇒ TYPE.MetadataTypeMap + * [.postRetrieveTasks(metadata)](#AttributeSetDefinition.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem + * [.preDeployTasks(metadata)](#AttributeSetDefinition.preDeployTasks) ⇒ TYPE.MetadataTypeItem @@ -1264,6 +1293,43 @@ Retrieves Metadata of schema set definitions for caching. **Kind**: static method of [AttributeSetDefinition](#AttributeSetDefinition) **Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise + + +### AttributeSetDefinition.parseResponseBody(body, [singleRetrieve]) ⇒ TYPE.MetadataTypeMap +Builds map of metadata entries mapped to their keyfields + +**Kind**: static method of [AttributeSetDefinition](#AttributeSetDefinition) +**Returns**: TYPE.MetadataTypeMap - keyField => metadata map + +| Param | Type | Description | +| --- | --- | --- | +| body | object | json of response body | +| [singleRetrieve] | string \| number | key of single item to filter by | + + + +### AttributeSetDefinition.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem +manages post retrieve steps + +**Kind**: static method of [AttributeSetDefinition](#AttributeSetDefinition) +**Returns**: TYPE.MetadataTypeItem - metadata + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.MetadataTypeItem | a single metadata | + + + +### AttributeSetDefinition.preDeployTasks(metadata) ⇒ TYPE.MetadataTypeItem +prepares for deployment + +**Kind**: static method of [AttributeSetDefinition](#AttributeSetDefinition) +**Returns**: TYPE.MetadataTypeItem - Promise + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.MetadataTypeItem | a single item | + ## Automation ⇐ [MetadataType](#MetadataType) diff --git a/lib/metadataTypes/AttributeGroup.js b/lib/metadataTypes/AttributeGroup.js index 77b5e008b..395d388af 100644 --- a/lib/metadataTypes/AttributeGroup.js +++ b/lib/metadataTypes/AttributeGroup.js @@ -1,7 +1,9 @@ 'use strict'; -const MetadataType = require('./MetadataType'); const TYPE = require('../../types/mcdev.d'); +const MetadataType = require('./MetadataType'); +const Util = require('../util/util'); +const cache = require('../util/cache'); /** * AttributeGroup MetadataType @@ -18,7 +20,7 @@ class AttributeGroup extends MetadataType { * @param {string} [key] customer key of single item to retrieve * @returns {Promise.} Promise of metadata */ - static retrieve(retrieveDir, _, __, key) { + static async retrieve(retrieveDir, _, __, key) { return super.retrieveREST( retrieveDir, '/hub/v1/contacts/schema/attributeGroups', @@ -35,6 +37,71 @@ class AttributeGroup extends MetadataType { static retrieveForCache() { return super.retrieveREST(null, '/hub/v1/contacts/schema/attributeGroups'); } + /** + * manages post retrieve steps + * + * @param {TYPE.MetadataTypeItem} metadata a single metadata + * @returns {TYPE.MetadataTypeItem} metadata + */ + static postRetrieveTasks(metadata) { + // attributeSetDefinition + for (const attributeSet of metadata.attributeSetIdentifiers) { + try { + const key = cache.searchForField( + 'attributeSetDefinition', + attributeSet.definitionID, + 'definitionID', + 'definitionKey' + ); + if (key !== attributeSet.definitionKey) { + throw new Error( + `AttributeSetDefinition key mismatch. Found ${key} instead of ${attributeSet.definitionKey}` + ); + } + delete attributeSet.definitionID; + delete attributeSet.definitionName; + delete attributeSet.connectingID; + } catch (ex) { + Util.logger.warn( + ` - ${this.definition.type} ${metadata[this.definition.keyField]} (for ${ + attributeSet.definitionKey + }): ${ex.message}` + ); + } + } + // Member ID + delete metadata.mID; + + return metadata; + } + /** + * prepares for deployment + * + * @param {TYPE.MetadataTypeItem} metadata a single item + * @returns {TYPE.MetadataTypeItem} Promise + */ + static async preDeployTasks(metadata) { + // attributeSetDefinition + for (const attributeSet of metadata.attributeSetIdentifiers) { + try { + const as = cache.getByKey('attributeSetDefinition', attributeSet.definitionKey); + attributeSet.definitionID = as.definitionID; + attributeSet.definitionName = as.definitionName?.value; + attributeSet.connectingID = as.connectingID; + } catch (ex) { + Util.logger.warn( + ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ + ex.message + }` + ); + } + } + + // Member ID - set to ID of deployment target automatically + metadata.mID = this.buObject.mid; + + return metadata; + } } // Assign definition to static attributes diff --git a/lib/metadataTypes/AttributeSetDefinition.js b/lib/metadataTypes/AttributeSetDefinition.js index 625920be0..a0fd63c59 100644 --- a/lib/metadataTypes/AttributeSetDefinition.js +++ b/lib/metadataTypes/AttributeSetDefinition.js @@ -2,6 +2,9 @@ const TYPE = require('../../types/mcdev.d'); const MetadataType = require('./MetadataType'); +const AttributeGroup = require('./AttributeGroup'); +const Util = require('../util/util'); +const cache = require('../util/cache'); /** * AttributeSetDefinition MetadataType @@ -18,7 +21,16 @@ class AttributeSetDefinition extends MetadataType { * @param {string} [key] customer key of single item to retrieve * @returns {Promise.} Promise */ - static retrieve(retrieveDir, _, __, key) { + static async retrieve(retrieveDir, _, __, key) { + if (retrieveDir && !cache.getCache()?.attributeGroup) { + // ! attributeGroup and attributeSetDefinition both link to each other. caching attributeGroup here "manually", assuming that it's quicker than the other way round + Util.logger.info(' - Caching dependent Metadata: attributeGroup'); + AttributeGroup.buObject = this.buObject; + AttributeGroup.client = this.client; + AttributeGroup.properties = this.properties; + const result = await AttributeGroup.retrieveForCache(); + cache.setMetadata('attributeGroup', result.metadata); + } return super.retrieveREST( retrieveDir, '/hub/v1/contacts/schema/setDefinitions', @@ -35,6 +47,267 @@ class AttributeSetDefinition extends MetadataType { static retrieveForCache() { return super.retrieveREST(null, '/hub/v1/contacts/schema/setDefinitions'); } + + /** + * Builds map of metadata entries mapped to their keyfields + * + * @param {object} body json of response body + * @param {string|number} [singleRetrieve] key of single item to filter by + * @returns {TYPE.MetadataTypeMap} keyField => metadata map + */ + static parseResponseBody(body, singleRetrieve) { + const metadataStructure = super.parseResponseBody(body, singleRetrieve); + + // make sure we add the entire list to cache before running postRetrieveTasks because of the self-references this type is using + // usually, the cache is only written into after all postRetrieveTasks have been run + cache.setMetadata(this.definition.type, metadataStructure); + + return metadataStructure; + } + + /** + * manages post retrieve steps + * + * @param {TYPE.MetadataTypeItem} metadata a single metadata + * @returns {TYPE.MetadataTypeItem} metadata + */ + static postRetrieveTasks(metadata) { + // folder + if (metadata.storageLogicalType === 'DataExtension') { + // attributeSetDefinition created for Group Connect do not have a folder + super.setFolderPath(metadata); + } + + // source + switch (metadata.storageLogicalType) { + case 'ExactTargetSchema': // synced / shared DEs + case 'DataExtension': { + // local DEs + try { + metadata.r__dataExtension_CustomerKey = cache.searchForField( + 'dataExtension', + metadata.storageReferenceID.value, + 'ObjectID', + 'CustomerKey' + ); + // TODO: check if fields in metadata.sendAttributeStorageName exist in data extension --> error + // TODO: check if fields in data extension exist in metadata.sendAttributeStorageName --> warn + + delete metadata.storageReferenceID; + delete metadata.storageName; + delete metadata.storageObjectInformation; // type ExactTargetSchema only + } catch (ex) { + Util.logger.warn( + ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ + ex.message + }` + ); + } + break; + } + case 'MobileAttributes': { + // TODO: implement + // "storageName": "_MobileAddress", + + break; + } + case 'EnterpriseAttributes': { + // TODO: implement + // "storageName": "_EnterpriseAttribute", + + break; + } + case 'PushAttributes': { + // TODO: implement + // "storageName": "_PushAddress", + + break; + } + } + + // relationships to attributeGroups & AttributeSet + if (Array.isArray(metadata.relationships)) { + for (const relationship of metadata.relationships) { + for (const type of ['left', 'right']) { + switch (relationship[type + 'Item'].relationshipType) { + case 'AttributeGroup': { + try { + relationship[type + 'Item'].r__attributeGroup_definitionKey = + cache.searchForField( + 'attributeGroup', + relationship[type + 'Item']?.identifier, + 'definitionID', + 'definitionKey' + ); + delete relationship[type + 'Item']?.identifier; + } catch (ex) { + Util.logger.warn( + ` - ${this.definition.type} ${ + metadata[this.definition.keyField] + }: ${ex.message}` + ); + } + break; + } + case 'AttributeSet': { + try { + relationship[ + type + 'Item' + ].r__attributeSetDefinition_definitionKey = cache.searchForField( + 'attributeSetDefinition', + relationship[type + 'Item']?.identifier, + 'definitionID', + 'definitionKey' + ); + delete relationship[type + 'Item']?.identifier; + } catch (ex) { + Util.logger.warn( + ` - ${this.definition.type} ${ + metadata[this.definition.keyField] + }: ${ex.message}` + ); + } + break; + } + } + } + } + } + + // Member ID + delete metadata.customObjectOwnerMID; + + return metadata; + } + /** + * prepares for deployment + * + * @param {TYPE.MetadataTypeItem} metadata a single item + * @returns {TYPE.MetadataTypeItem} Promise + */ + static async preDeployTasks(metadata) { + // folder + if (metadata.storageLogicalType) { + // attributeSetDefinition created for Group Connect do not have a folder + super.setFolderId(metadata); + } + + // source + switch (metadata.storageLogicalType) { + case 'ExactTargetSchema': // synced / shared DEs + case 'DataExtension': { + // local DEs + try { + const de = cache.getByKey( + 'dataExtension', + metadata.r__dataExtension_CustomerKey + ); + + metadata.storageReferenceID = { + value: de.ObjectID, + }; + metadata.storageName = de.Name; + if (metadata.storageLogicalType === 'ExactTargetSchema') { + metadata.storageObjectInformation = { + externalObjectAPIName: de.Name.split('_Salesforce')[0], + }; + } + + // TODO: check if fields in metadata.sendAttributeStorageName exist in data extension --> error + // TODO: check if fields in data extension exist in metadata.sendAttributeStorageName --> warn + } catch (ex) { + Util.logger.warn( + ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ + ex.message + }` + ); + } + break; + } + case 'MobileAttributes': { + // TODO: implement + // "storageName": "_MobileAddress", + + break; + } + case 'EnterpriseAttributes': { + // TODO: implement + // "storageName": "_EnterpriseAttribute", + + break; + } + case 'PushAttributes': { + // TODO: implement + // "storageName": "_PushAddress", + + break; + } + } + + // attributeGroups + // relationships to attributeGroups & AttributeSet + if (Array.isArray(metadata.relationships)) { + for (const relationship of metadata.relationships) { + try { + relationship.leftItem.identifier = cache.searchForField( + 'attributeGroup', + relationship.leftItem.r__attributeGroup_definitionKey, + 'definitionKey', + 'definitionID' + ); + delete relationship.leftItem.r__attributeGroup_definitionKey; + } catch (ex) { + Util.logger.warn( + ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ + ex.message + }` + ); + } + } + for (const relationship of metadata.relationships) { + for (const type of ['left', 'right']) { + switch (relationship[type + 'Item'].relationshipType) { + case 'AttributeGroup': { + relationship[type + 'Item'].identifier = cache.searchForField( + 'attributeGroup', + relationship[type + 'Item']?.r__attributeGroup_definitionKey, + 'definitionKey', + 'definitionID' + ); + break; + } + case 'AttributeSet': { + try { + relationship[type + 'Item'].identifier = cache.searchForField( + 'attributeSetDefinition', + relationship[type + 'Item'] + ?.r__attributeSetDefinition_definitionKey, + 'definitionID', + 'definitionKey' + ); + + // get relationship fieldnames + // check if its a self-reference to metadata.valueDefinitions or if it's a reference to another attributeSetDefinition + // TODO: implement + } catch (ex) { + Util.logger.warn( + ` - ${this.definition.type} ${ + metadata[this.definition.keyField] + }: ${ex.message}` + ); + } + break; + } + } + } + } + } + + // Member ID - set to ID of deployment target automatically + metadata.customObjectOwnerMID = this.buObject.mid; + + return metadata; + } } // Assign definition to static attributes diff --git a/lib/metadataTypes/definitions/AttributeGroup.definition.js b/lib/metadataTypes/definitions/AttributeGroup.definition.js index cc6048fd8..a585f64ae 100644 --- a/lib/metadataTypes/definitions/AttributeGroup.definition.js +++ b/lib/metadataTypes/definitions/AttributeGroup.definition.js @@ -1,6 +1,6 @@ module.exports = { bodyIteratorField: 'attributeGroupDefinitions', - dependencies: [], // future may have dependency on Data Extensions + dependencies: ['attributeSetDefinition'], // future may have dependency on Data Extensions hasExtended: false, idField: 'definitionID', keyField: 'definitionKey', @@ -15,223 +15,223 @@ module.exports = { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, applicationKey: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, attributeCount: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, attributeGroupIconKey: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, attributeGroupType: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, attributeSetIdentifiers: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, 'attributeSetIdentifiers[].connectingID.identifierType': { isCreateable: null, isUpdateable: null, - retrieving: false, - template: null, + retrieving: true, + template: false, }, 'attributeSetIdentifiers[].definitionID': { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: false, }, 'attributeSetIdentifiers[].definitionKey': { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, - 'attributeSetIdentifiers[].definitionName.Contact': { + 'attributeSetIdentifiers[].definitionName.value': { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: false, }, 'attributeSetIdentifiers[].namespace': { isCreateable: null, isUpdateable: null, retrieving: false, - template: null, + template: false, }, canAddProperties: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, canAddRelationships: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, canChangeProperties: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, canModify: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, canRemove: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, connectingID: { isCreateable: null, isUpdateable: null, retrieving: false, - template: null, + template: false, }, 'connectingID.identifierType': { isCreateable: null, isUpdateable: null, retrieving: false, - template: null, + template: false, }, containsSchemaAttributes: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, definitionID: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, definitionKey: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, 'definitionName.value': { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, description: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, displayOrder: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, fullyQualifiedName: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, isHidden: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, isOwner: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, isPrimary: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, isSystemDefined: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, localizedDescription: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, 'localizedDescription.resourceSetKey': { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, 'localizedDescription.resourceValueKey': { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, 'localizedDescription.value': { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, mID: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, namespace: { isCreateable: null, isUpdateable: null, retrieving: false, - template: null, + template: false, }, objectState: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, requiredRelationships: { isCreateable: null, isUpdateable: null, retrieving: true, - template: null, + template: true, }, }, }; diff --git a/lib/metadataTypes/definitions/AttributeSetDefinition.definition.js b/lib/metadataTypes/definitions/AttributeSetDefinition.definition.js index b30ea4a2b..f650caf70 100644 --- a/lib/metadataTypes/definitions/AttributeSetDefinition.definition.js +++ b/lib/metadataTypes/definitions/AttributeSetDefinition.definition.js @@ -1,16 +1,17 @@ module.exports = { bodyIteratorField: 'setDefinition', - dependencies: [], // future may have dependency on Data Extensions + dependencies: ['folder-hidden', 'folder-dataextension', 'dataExtension'], // future may have dependency on Data Extensions hasExtended: false, idField: 'definitionID', keyField: 'definitionKey', nameField: 'name', + folderIdField: 'categoryID', createdDateField: 'createDate', createdNameField: 'createdBy', lastmodDateField: null, lastmodNameField: null, restPagination: false, - type: 'AttributeSetDefinition', + type: 'attributeSetDefinition', typeDescription: 'BETA: Data Extensions linked to Attribute Groups in Data Designer.', typeRetrieveByDefault: false, typeName: 'Data Designer Set Definitions', From c5c90f9012d79bf717cf425c3df2978f32be3636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 1 Mar 2023 16:29:32 +0100 Subject: [PATCH 004/208] #711: rename AttributeSetDefinition to AttributeSet --- docs/dist/documentation.md | 52 +++++++++--------- lib/MetadataTypeDefinitions.js | 2 +- lib/MetadataTypeInfo.js | 2 +- lib/metadataTypes/AttributeGroup.js | 10 ++-- ...ributeSetDefinition.js => AttributeSet.js} | 55 ++++++++++++------- .../definitions/AttributeGroup.definition.js | 2 +- ...finition.js => AttributeSet.definition.js} | 3 +- 7 files changed, 72 insertions(+), 54 deletions(-) rename lib/metadataTypes/{AttributeSetDefinition.js => AttributeSet.js} (83%) rename lib/metadataTypes/definitions/{AttributeSetDefinition.definition.js => AttributeSet.definition.js} (99%) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index f7b4c17b3..d88ed78e2 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -20,8 +20,8 @@ Source and target business units are also compared before the deployment to appl
AttributeGroupMetadataType

AttributeGroup MetadataType

-
AttributeSetDefinitionMetadataType
-

AttributeSetDefinition MetadataType

+
AttributeSetMetadataType
+

AttributeSet MetadataType

AutomationMetadataType

Automation MetadataType

@@ -1256,27 +1256,27 @@ prepares for deployment | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single item | - + -## AttributeSetDefinition ⇐ [MetadataType](#MetadataType) -AttributeSetDefinition MetadataType +## AttributeSet ⇐ [MetadataType](#MetadataType) +AttributeSet MetadataType **Kind**: global class **Extends**: [MetadataType](#MetadataType) -* [AttributeSetDefinition](#AttributeSetDefinition) ⇐ [MetadataType](#MetadataType) - * [.retrieve(retrieveDir, [_], [__], [key])](#AttributeSetDefinition.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> - * [.retrieveForCache()](#AttributeSetDefinition.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> - * [.parseResponseBody(body, [singleRetrieve])](#AttributeSetDefinition.parseResponseBody) ⇒ TYPE.MetadataTypeMap - * [.postRetrieveTasks(metadata)](#AttributeSetDefinition.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem - * [.preDeployTasks(metadata)](#AttributeSetDefinition.preDeployTasks) ⇒ TYPE.MetadataTypeItem +* [AttributeSet](#AttributeSet) ⇐ [MetadataType](#MetadataType) + * [.retrieve(retrieveDir, [_], [__], [key])](#AttributeSet.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> + * [.retrieveForCache()](#AttributeSet.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> + * [.parseResponseBody(body, [singleRetrieve])](#AttributeSet.parseResponseBody) ⇒ TYPE.MetadataTypeMap + * [.postRetrieveTasks(metadata)](#AttributeSet.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem + * [.preDeployTasks(metadata)](#AttributeSet.preDeployTasks) ⇒ TYPE.MetadataTypeItem - + -### AttributeSetDefinition.retrieve(retrieveDir, [_], [__], [key]) ⇒ Promise.<TYPE.MetadataTypeMapObj> +### AttributeSet.retrieve(retrieveDir, [_], [__], [key]) ⇒ Promise.<TYPE.MetadataTypeMapObj> Retrieves Metadata of schema set Definitions. -**Kind**: static method of [AttributeSetDefinition](#AttributeSetDefinition) +**Kind**: static method of [AttributeSet](#AttributeSet) **Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise | Param | Type | Description | @@ -1286,19 +1286,19 @@ Retrieves Metadata of schema set Definitions. | [__] | void | unused parameter | | [key] | string | customer key of single item to retrieve | - + -### AttributeSetDefinition.retrieveForCache() ⇒ Promise.<TYPE.MetadataTypeMapObj> +### AttributeSet.retrieveForCache() ⇒ Promise.<TYPE.MetadataTypeMapObj> Retrieves Metadata of schema set definitions for caching. -**Kind**: static method of [AttributeSetDefinition](#AttributeSetDefinition) +**Kind**: static method of [AttributeSet](#AttributeSet) **Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise - + -### AttributeSetDefinition.parseResponseBody(body, [singleRetrieve]) ⇒ TYPE.MetadataTypeMap +### AttributeSet.parseResponseBody(body, [singleRetrieve]) ⇒ TYPE.MetadataTypeMap Builds map of metadata entries mapped to their keyfields -**Kind**: static method of [AttributeSetDefinition](#AttributeSetDefinition) +**Kind**: static method of [AttributeSet](#AttributeSet) **Returns**: TYPE.MetadataTypeMap - keyField => metadata map | Param | Type | Description | @@ -1306,24 +1306,24 @@ Builds map of metadata entries mapped to their keyfields | body | object | json of response body | | [singleRetrieve] | string \| number | key of single item to filter by | - + -### AttributeSetDefinition.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem +### AttributeSet.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem manages post retrieve steps -**Kind**: static method of [AttributeSetDefinition](#AttributeSetDefinition) +**Kind**: static method of [AttributeSet](#AttributeSet) **Returns**: TYPE.MetadataTypeItem - metadata | Param | Type | Description | | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single metadata | - + -### AttributeSetDefinition.preDeployTasks(metadata) ⇒ TYPE.MetadataTypeItem +### AttributeSet.preDeployTasks(metadata) ⇒ TYPE.MetadataTypeItem prepares for deployment -**Kind**: static method of [AttributeSetDefinition](#AttributeSetDefinition) +**Kind**: static method of [AttributeSet](#AttributeSet) **Returns**: TYPE.MetadataTypeItem - Promise | Param | Type | Description | diff --git a/lib/MetadataTypeDefinitions.js b/lib/MetadataTypeDefinitions.js index a4d6c1fed..e49da6535 100644 --- a/lib/MetadataTypeDefinitions.js +++ b/lib/MetadataTypeDefinitions.js @@ -7,7 +7,7 @@ const MetadataTypeDefinitions = { accountUser: require('./metadataTypes/definitions/AccountUser.definition'), asset: require('./metadataTypes/definitions/Asset.definition'), attributeGroup: require('./metadataTypes/definitions/AttributeGroup.definition'), - attributeSetDefinition: require('./metadataTypes/definitions/AttributeSetDefinition.definition'), + attributeSet: require('./metadataTypes/definitions/AttributeSet.definition'), automation: require('./metadataTypes/definitions/Automation.definition'), campaign: require('./metadataTypes/definitions/Campaign.definition'), contentArea: require('./metadataTypes/definitions/ContentArea.definition'), diff --git a/lib/MetadataTypeInfo.js b/lib/MetadataTypeInfo.js index dbc6e1722..cdca5770e 100644 --- a/lib/MetadataTypeInfo.js +++ b/lib/MetadataTypeInfo.js @@ -7,7 +7,7 @@ const MetadataTypeInfo = { accountUser: require('./metadataTypes/AccountUser'), asset: require('./metadataTypes/Asset'), attributeGroup: require('./metadataTypes/AttributeGroup'), - attributeSetDefinition: require('./metadataTypes/AttributeSetDefinition'), + attributeSet: require('./metadataTypes/AttributeSet'), automation: require('./metadataTypes/Automation'), campaign: require('./metadataTypes/Campaign'), contentArea: require('./metadataTypes/ContentArea'), diff --git a/lib/metadataTypes/AttributeGroup.js b/lib/metadataTypes/AttributeGroup.js index 395d388af..fea0b50d6 100644 --- a/lib/metadataTypes/AttributeGroup.js +++ b/lib/metadataTypes/AttributeGroup.js @@ -44,18 +44,18 @@ class AttributeGroup extends MetadataType { * @returns {TYPE.MetadataTypeItem} metadata */ static postRetrieveTasks(metadata) { - // attributeSetDefinition + // attributeSet for (const attributeSet of metadata.attributeSetIdentifiers) { try { const key = cache.searchForField( - 'attributeSetDefinition', + 'attributeSet', attributeSet.definitionID, 'definitionID', 'definitionKey' ); if (key !== attributeSet.definitionKey) { throw new Error( - `AttributeSetDefinition key mismatch. Found ${key} instead of ${attributeSet.definitionKey}` + `AttributeSet key mismatch. Found ${key} instead of ${attributeSet.definitionKey}` ); } delete attributeSet.definitionID; @@ -81,10 +81,10 @@ class AttributeGroup extends MetadataType { * @returns {TYPE.MetadataTypeItem} Promise */ static async preDeployTasks(metadata) { - // attributeSetDefinition + // attributeSet for (const attributeSet of metadata.attributeSetIdentifiers) { try { - const as = cache.getByKey('attributeSetDefinition', attributeSet.definitionKey); + const as = cache.getByKey('attributeSet', attributeSet.definitionKey); attributeSet.definitionID = as.definitionID; attributeSet.definitionName = as.definitionName?.value; attributeSet.connectingID = as.connectingID; diff --git a/lib/metadataTypes/AttributeSetDefinition.js b/lib/metadataTypes/AttributeSet.js similarity index 83% rename from lib/metadataTypes/AttributeSetDefinition.js rename to lib/metadataTypes/AttributeSet.js index a0fd63c59..ddac7ca92 100644 --- a/lib/metadataTypes/AttributeSetDefinition.js +++ b/lib/metadataTypes/AttributeSet.js @@ -7,11 +7,11 @@ const Util = require('../util/util'); const cache = require('../util/cache'); /** - * AttributeSetDefinition MetadataType + * AttributeSet MetadataType * * @augments MetadataType */ -class AttributeSetDefinition extends MetadataType { +class AttributeSet extends MetadataType { /** * Retrieves Metadata of schema set Definitions. * @@ -23,7 +23,7 @@ class AttributeSetDefinition extends MetadataType { */ static async retrieve(retrieveDir, _, __, key) { if (retrieveDir && !cache.getCache()?.attributeGroup) { - // ! attributeGroup and attributeSetDefinition both link to each other. caching attributeGroup here "manually", assuming that it's quicker than the other way round + // ! attributeGroup and attributeSet both link to each other. caching attributeGroup here "manually", assuming that it's quicker than the other way round Util.logger.info(' - Caching dependent Metadata: attributeGroup'); AttributeGroup.buObject = this.buObject; AttributeGroup.client = this.client; @@ -74,7 +74,7 @@ class AttributeSetDefinition extends MetadataType { static postRetrieveTasks(metadata) { // folder if (metadata.storageLogicalType === 'DataExtension') { - // attributeSetDefinition created for Group Connect do not have a folder + // attributeSet created for Group Connect do not have a folder super.setFolderPath(metadata); } @@ -151,15 +151,33 @@ class AttributeSetDefinition extends MetadataType { } case 'AttributeSet': { try { - relationship[ - type + 'Item' - ].r__attributeSetDefinition_definitionKey = cache.searchForField( - 'attributeSetDefinition', - relationship[type + 'Item']?.identifier, - 'definitionID', - 'definitionKey' - ); + relationship[type + 'Item'].r__attributeSet_definitionKey = + cache.searchForField( + 'attributeSet', + relationship[type + 'Item']?.identifier, + 'definitionID', + 'definitionKey' + ); delete relationship[type + 'Item']?.identifier; + + // get relationship fieldnames + // check if its a self-reference to metadata.valueDefinitions or if it's a reference to another attributeSet + const relationshipObj = + relationship[type + 'Item'].r__attributeSet_definitionKey === + metadata.definitionKey + ? metadata + : cache.getByKey( + relationship[type + 'Item'] + .r__attributeSet_definitionKey + ); + // resolve field values + for (const attr of relationship.relationshipAttributes) { + const id = attr[type + 'AttributeID']; + attr['c__' + type + 'FullyQualifiedName'] = + relationshipObj.valueDefinitions.find( + (item) => item.valueDefinitionID === id + ).fullyQualifiedName; + } } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${ @@ -188,7 +206,7 @@ class AttributeSetDefinition extends MetadataType { static async preDeployTasks(metadata) { // folder if (metadata.storageLogicalType) { - // attributeSetDefinition created for Group Connect do not have a folder + // attributeSet created for Group Connect do not have a folder super.setFolderId(metadata); } @@ -279,15 +297,14 @@ class AttributeSetDefinition extends MetadataType { case 'AttributeSet': { try { relationship[type + 'Item'].identifier = cache.searchForField( - 'attributeSetDefinition', - relationship[type + 'Item'] - ?.r__attributeSetDefinition_definitionKey, + 'attributeSet', + relationship[type + 'Item']?.r__attributeSet_definitionKey, 'definitionID', 'definitionKey' ); // get relationship fieldnames - // check if its a self-reference to metadata.valueDefinitions or if it's a reference to another attributeSetDefinition + // check if its a self-reference to metadata.valueDefinitions or if it's a reference to another attributeSet // TODO: implement } catch (ex) { Util.logger.warn( @@ -311,6 +328,6 @@ class AttributeSetDefinition extends MetadataType { } // Assign definition to static attributes -AttributeSetDefinition.definition = require('../MetadataTypeDefinitions').attributeSetDefinition; +AttributeSet.definition = require('../MetadataTypeDefinitions').attributeSet; -module.exports = AttributeSetDefinition; +module.exports = AttributeSet; diff --git a/lib/metadataTypes/definitions/AttributeGroup.definition.js b/lib/metadataTypes/definitions/AttributeGroup.definition.js index a585f64ae..9382df3a4 100644 --- a/lib/metadataTypes/definitions/AttributeGroup.definition.js +++ b/lib/metadataTypes/definitions/AttributeGroup.definition.js @@ -1,6 +1,6 @@ module.exports = { bodyIteratorField: 'attributeGroupDefinitions', - dependencies: ['attributeSetDefinition'], // future may have dependency on Data Extensions + dependencies: ['attributeSet'], // future may have dependency on Data Extensions hasExtended: false, idField: 'definitionID', keyField: 'definitionKey', diff --git a/lib/metadataTypes/definitions/AttributeSetDefinition.definition.js b/lib/metadataTypes/definitions/AttributeSet.definition.js similarity index 99% rename from lib/metadataTypes/definitions/AttributeSetDefinition.definition.js rename to lib/metadataTypes/definitions/AttributeSet.definition.js index f650caf70..bea93f2b9 100644 --- a/lib/metadataTypes/definitions/AttributeSetDefinition.definition.js +++ b/lib/metadataTypes/definitions/AttributeSet.definition.js @@ -3,6 +3,7 @@ module.exports = { dependencies: ['folder-hidden', 'folder-dataextension', 'dataExtension'], // future may have dependency on Data Extensions hasExtended: false, idField: 'definitionID', + keepId: true, keyField: 'definitionKey', nameField: 'name', folderIdField: 'categoryID', @@ -11,7 +12,7 @@ module.exports = { lastmodDateField: null, lastmodNameField: null, restPagination: false, - type: 'attributeSetDefinition', + type: 'attributeSet', typeDescription: 'BETA: Data Extensions linked to Attribute Groups in Data Designer.', typeRetrieveByDefault: false, typeName: 'Data Designer Set Definitions', From e2e887c59c1e4f7ad5c7ca7b7d9225f7b41d066d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 2 Mar 2023 00:10:26 +0100 Subject: [PATCH 005/208] #711: resolve relationshipAttributes for sets --- lib/metadataTypes/AttributeSet.js | 45 +++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/lib/metadataTypes/AttributeSet.js b/lib/metadataTypes/AttributeSet.js index ddac7ca92..c4e76d468 100644 --- a/lib/metadataTypes/AttributeSet.js +++ b/lib/metadataTypes/AttributeSet.js @@ -129,6 +129,12 @@ class AttributeSet extends MetadataType { if (Array.isArray(metadata.relationships)) { for (const relationship of metadata.relationships) { for (const type of ['left', 'right']) { + if ( + relationship[type + 'Item']?.connectingID?.identifierType === + 'FullyQualifiedName' + ) { + delete relationship[type + 'Item'].connectingID; + } switch (relationship[type + 'Item'].relationshipType) { case 'AttributeGroup': { try { @@ -147,6 +153,8 @@ class AttributeSet extends MetadataType { }: ${ex.message}` ); } + // get relationship fieldnames + // TODO: implement break; } case 'AttributeSet': { @@ -167,6 +175,7 @@ class AttributeSet extends MetadataType { metadata.definitionKey ? metadata : cache.getByKey( + 'attributeSet', relationship[type + 'Item'] .r__attributeSet_definitionKey ); @@ -177,6 +186,8 @@ class AttributeSet extends MetadataType { relationshipObj.valueDefinitions.find( (item) => item.valueDefinitionID === id ).fullyQualifiedName; + delete attr[type + 'AttributeID']; + delete attr[type + 'ConnectingID']; } } catch (ex) { Util.logger.warn( @@ -284,6 +295,10 @@ class AttributeSet extends MetadataType { } for (const relationship of metadata.relationships) { for (const type of ['left', 'right']) { + relationship[type + 'Item'].connectingID = relationship[type + 'Item'] + .connectingID || { + identifierType: 'FullyQualifiedName', + }; switch (relationship[type + 'Item'].relationshipType) { case 'AttributeGroup': { relationship[type + 'Item'].identifier = cache.searchForField( @@ -292,6 +307,8 @@ class AttributeSet extends MetadataType { 'definitionKey', 'definitionID' ); + // get relationship fieldnames + // TODO: implement break; } case 'AttributeSet': { @@ -302,10 +319,34 @@ class AttributeSet extends MetadataType { 'definitionID', 'definitionKey' ); - // get relationship fieldnames // check if its a self-reference to metadata.valueDefinitions or if it's a reference to another attributeSet - // TODO: implement + const relationshipObj = + relationship[type + 'Item'].r__attributeSet_definitionKey === + metadata.definitionKey + ? metadata + : cache.getByKey( + 'attributeSet', + relationship[type + 'Item'] + .r__attributeSet_definitionKey + ); + // resolve field values + for (const attr of relationship.relationshipAttributes) { + attr[type + 'AttributeID'] = + relationshipObj.valueDefinitions.find( + (item) => + item.fullyQualifiedName === + attr['c__' + type + 'FullyQualifiedName'] + ).valueDefinitionID; + attr[type + 'ConnectingID'] = attr[type + 'ConnectingID'] || { + identifierType: 'FullyQualifiedName', + }; + + delete attr['c__' + type + 'FullyQualifiedName']; + } + + // cleanup + delete relationship[type + 'Item']?.r__attributeSet_definitionKey; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${ From aa3b710ac2cc64c7476e5e9513e8def4d966f55b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 2 Mar 2023 00:16:07 +0100 Subject: [PATCH 006/208] #711: simplify attributeSetIdentifiers --- lib/metadataTypes/AttributeGroup.js | 47 +++++++++++++++-------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/lib/metadataTypes/AttributeGroup.js b/lib/metadataTypes/AttributeGroup.js index fea0b50d6..1e19e78e5 100644 --- a/lib/metadataTypes/AttributeGroup.js +++ b/lib/metadataTypes/AttributeGroup.js @@ -44,8 +44,11 @@ class AttributeGroup extends MetadataType { * @returns {TYPE.MetadataTypeItem} metadata */ static postRetrieveTasks(metadata) { + // Member ID + delete metadata.mID; + // attributeSet - for (const attributeSet of metadata.attributeSetIdentifiers) { + metadata.attributeSetIdentifiers = metadata.attributeSetIdentifiers.map((attributeSet) => { try { const key = cache.searchForField( 'attributeSet', @@ -58,19 +61,19 @@ class AttributeGroup extends MetadataType { `AttributeSet key mismatch. Found ${key} instead of ${attributeSet.definitionKey}` ); } - delete attributeSet.definitionID; - delete attributeSet.definitionName; - delete attributeSet.connectingID; + return key; } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${metadata[this.definition.keyField]} (for ${ attributeSet.definitionKey }): ${ex.message}` ); + return attributeSet; } - } - // Member ID - delete metadata.mID; + }); + + // requiredRelationships + // TODO: implement return metadata; } @@ -81,25 +84,23 @@ class AttributeGroup extends MetadataType { * @returns {TYPE.MetadataTypeItem} Promise */ static async preDeployTasks(metadata) { - // attributeSet - for (const attributeSet of metadata.attributeSetIdentifiers) { - try { - const as = cache.getByKey('attributeSet', attributeSet.definitionKey); - attributeSet.definitionID = as.definitionID; - attributeSet.definitionName = as.definitionName?.value; - attributeSet.connectingID = as.connectingID; - } catch (ex) { - Util.logger.warn( - ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ - ex.message - }` - ); - } - } - // Member ID - set to ID of deployment target automatically metadata.mID = this.buObject.mid; + // attributeSet + metadata.attributeSetIdentifiers = metadata.attributeSetIdentifiers.map((key) => { + const as = cache.getByKey('attributeSet', key); + return { + definitionKey: key, + definitionID: as.definitionID, + definitionName: as.definitionName, + connectingID: as.connectingID, + }; + }); + + // requiredRelationships + // TODO: implement + return metadata; } } From 45fd2942c0416769e7aa94cda6f0daa276549ac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 2 Mar 2023 00:17:43 +0100 Subject: [PATCH 007/208] #711: disable keepId --- lib/metadataTypes/definitions/AttributeSet.definition.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/metadataTypes/definitions/AttributeSet.definition.js b/lib/metadataTypes/definitions/AttributeSet.definition.js index bea93f2b9..cea97cd10 100644 --- a/lib/metadataTypes/definitions/AttributeSet.definition.js +++ b/lib/metadataTypes/definitions/AttributeSet.definition.js @@ -3,7 +3,6 @@ module.exports = { dependencies: ['folder-hidden', 'folder-dataextension', 'dataExtension'], // future may have dependency on Data Extensions hasExtended: false, idField: 'definitionID', - keepId: true, keyField: 'definitionKey', nameField: 'name', folderIdField: 'categoryID', From 156b2e1852738b05097b11753c5874e4d77e75b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Mon, 6 Mar 2023 23:21:00 +0100 Subject: [PATCH 008/208] #711: enable attributeGroup.create and resolve details for groups and sets --- docs/dist/documentation.md | 92 ++++++++++ lib/metadataTypes/AttributeGroup.js | 64 +++++++ lib/metadataTypes/AttributeSet.js | 108 +++++++++-- .../definitions/AttributeGroup.definition.js | 167 ++++++++++-------- .../definitions/AttributeSet.definition.js | 58 +++--- 5 files changed, 371 insertions(+), 118 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index d88ed78e2..6a4e25eaa 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -20,6 +20,9 @@ Source and target business units are also compared before the deployment to appl
AttributeGroupMetadataType

AttributeGroup MetadataType

+
AttributeRelationshipMetadataType
+

AttributeRelationship MetadataType

+
AttributeSetMetadataType

AttributeSet MetadataType

@@ -1207,6 +1210,7 @@ AttributeGroup MetadataType * [AttributeGroup](#AttributeGroup) ⇐ [MetadataType](#MetadataType) * [.retrieve(retrieveDir, [_], [__], [key])](#AttributeGroup.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveForCache()](#AttributeGroup.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> + * [.create(metadata)](#AttributeGroup.create) ⇒ Promise * [.postRetrieveTasks(metadata)](#AttributeGroup.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem * [.preDeployTasks(metadata)](#AttributeGroup.preDeployTasks) ⇒ TYPE.MetadataTypeItem @@ -1232,6 +1236,18 @@ Retrieves Metadata of schema attribute groups for caching. **Kind**: static method of [AttributeGroup](#AttributeGroup) **Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of metadata + + +### AttributeGroup.create(metadata) ⇒ Promise +Creates a single item + +**Kind**: static method of [AttributeGroup](#AttributeGroup) +**Returns**: Promise - Promise + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.MetadataTypeItem | a single item | + ### AttributeGroup.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem @@ -1256,6 +1272,74 @@ prepares for deployment | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single item | + + +## AttributeRelationship ⇐ [MetadataType](#MetadataType) +AttributeRelationship MetadataType + +**Kind**: global class +**Extends**: [MetadataType](#MetadataType) + +* [AttributeRelationship](#AttributeRelationship) ⇐ [MetadataType](#MetadataType) + * [.retrieve(retrieveDir, [_], [__], [relationshipID], attributeSetId)](#AttributeRelationship.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> + * [.retrieveForCache(_, __, attributeSetId)](#AttributeRelationship.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> + * [.postRetrieveTasks(metadata)](#AttributeRelationship.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem + * [.preDeployTasks(metadata)](#AttributeRelationship.preDeployTasks) ⇒ TYPE.MetadataTypeItem + + + +### AttributeRelationship.retrieve(retrieveDir, [_], [__], [relationshipID], attributeSetId) ⇒ Promise.<TYPE.MetadataTypeMapObj> +Retrieves Metadata of schema attribute groups. + +**Kind**: static method of [AttributeRelationship](#AttributeRelationship) +**Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of metadata + +| Param | Type | Description | +| --- | --- | --- | +| retrieveDir | string | Directory where retrieved metadata directory will be saved | +| [_] | void | unused parameter | +| [__] | void | unused parameter | +| [relationshipID] | string | customer key of single item to retrieve | +| attributeSetId | string | Id of the attribute set for which these relationships are defined | + + + +### AttributeRelationship.retrieveForCache(_, __, attributeSetId) ⇒ Promise.<TYPE.MetadataTypeMapObj> +Retrieves Metadata of schema attribute groups for caching. + +**Kind**: static method of [AttributeRelationship](#AttributeRelationship) +**Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of metadata + +| Param | Type | Description | +| --- | --- | --- | +| _ | void | unused parameter | +| __ | void | unused parameter | +| attributeSetId | string | Id of the attribute set for which these relationships are defined | + + + +### AttributeRelationship.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem +manages post retrieve steps + +**Kind**: static method of [AttributeRelationship](#AttributeRelationship) +**Returns**: TYPE.MetadataTypeItem - metadata + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.MetadataTypeItem | a single metadata | + + + +### AttributeRelationship.preDeployTasks(metadata) ⇒ TYPE.MetadataTypeItem +prepares for deployment + +**Kind**: static method of [AttributeRelationship](#AttributeRelationship) +**Returns**: TYPE.MetadataTypeItem - Promise + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.MetadataTypeItem | a single item | + ## AttributeSet ⇐ [MetadataType](#MetadataType) @@ -1269,6 +1353,7 @@ AttributeSet MetadataType * [.retrieveForCache()](#AttributeSet.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.parseResponseBody(body, [singleRetrieve])](#AttributeSet.parseResponseBody) ⇒ TYPE.MetadataTypeMap * [.postRetrieveTasks(metadata)](#AttributeSet.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem + * [._getSystemValueDefinitions()](#AttributeSet._getSystemValueDefinitions) ⇒ Array.<object> * [.preDeployTasks(metadata)](#AttributeSet.preDeployTasks) ⇒ TYPE.MetadataTypeItem @@ -1318,6 +1403,13 @@ manages post retrieve steps | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single metadata | + + +### AttributeSet.\_getSystemValueDefinitions() ⇒ Array.<object> +helper for [postRetrieveTasks](postRetrieveTasks) + +**Kind**: static method of [AttributeSet](#AttributeSet) +**Returns**: Array.<object> - all system value definitions ### AttributeSet.preDeployTasks(metadata) ⇒ TYPE.MetadataTypeItem diff --git a/lib/metadataTypes/AttributeGroup.js b/lib/metadataTypes/AttributeGroup.js index 1e19e78e5..37abaf8b8 100644 --- a/lib/metadataTypes/AttributeGroup.js +++ b/lib/metadataTypes/AttributeGroup.js @@ -37,6 +37,16 @@ class AttributeGroup extends MetadataType { static retrieveForCache() { return super.retrieveREST(null, '/hub/v1/contacts/schema/attributeGroups'); } + /** + * Creates a single item + * + * @param {TYPE.MetadataTypeItem} metadata a single item + * @returns {Promise} Promise + */ + static create(metadata) { + return super.createREST(metadata, '/hub/v1/contacts/schema/attributeGroups'); + } + /** * manages post retrieve steps * @@ -75,6 +85,31 @@ class AttributeGroup extends MetadataType { // requiredRelationships // TODO: implement + // description is not returned by API when empty. Set to empty string to propose the field as an option to users + metadata.description = metadata.description || ''; + + // applicationKey is only used by system generated attribute groups and otherwise it's empty. + if (metadata.applicationKey === '') { + // remove useless field + delete metadata.applicationKey; + } + + // connectingID.identifierType seems to be always set to 'FullyQualifiedName' - to be sure we check it here and remove it if it's the case + if (metadata.connectingID?.identifierType === 'FullyQualifiedName') { + // remove useless field + delete metadata.connectingID; + } + + // containsSchemaAttributes is only true for system generated attribute groups and otherwise it's false. + if (!metadata.containsSchemaAttributes) { + delete metadata.containsSchemaAttributes; + } + + // isSystemDefined is only true for system generated attribute groups and cannot be deployed + if (!metadata.isSystemDefined) { + delete metadata.isSystemDefined; + } + return metadata; } /** @@ -101,6 +136,35 @@ class AttributeGroup extends MetadataType { // requiredRelationships // TODO: implement + // description is not returned by API when empty. Remove it before deployment if empty + if (metadata.description === '') { + delete metadata.description; + } + + // filter system defined attribute groups + if (metadata.isSystemDefined) { + throw new Error( + ` ☇ skipping ${this.definition.type} ${metadata[this.definition.keyField]} / ${ + metadata[this.definition.nameField] + }: Cannot deploy system defined attribute groups (isSystemDefined: true)` + ); + } + + // connectingID.identifierType seems to be always set to 'FullyQualifiedName' - we remove it during retrieve and auto-set it here again + if (!metadata.connectingID?.identifierType) { + metadata.connectingID = { + identifierType: 'FullyQualifiedName', + }; + } + + // fullyQualifiedName is equal to definitionName.value and needs to be auto-populated for deploy + metadata.fullyQualifiedName = metadata.definitionName?.value; + + // containsSchemaAttributes is only true for system generated attribute groups and otherwise it's false which is why we remove it during retrieve and auto-set it here again + if (!metadata.containsSchemaAttributes) { + metadata.containsSchemaAttributes = false; + } + return metadata; } } diff --git a/lib/metadataTypes/AttributeSet.js b/lib/metadataTypes/AttributeSet.js index c4e76d468..7b855eb32 100644 --- a/lib/metadataTypes/AttributeSet.js +++ b/lib/metadataTypes/AttributeSet.js @@ -56,12 +56,13 @@ class AttributeSet extends MetadataType { * @returns {TYPE.MetadataTypeMap} keyField => metadata map */ static parseResponseBody(body, singleRetrieve) { - const metadataStructure = super.parseResponseBody(body, singleRetrieve); + const metadataCache = super.parseResponseBody(body); // make sure we add the entire list to cache before running postRetrieveTasks because of the self-references this type is using // usually, the cache is only written into after all postRetrieveTasks have been run - cache.setMetadata(this.definition.type, metadataStructure); + cache.setMetadata(this.definition.type, metadataCache); + const metadataStructure = super.parseResponseBody(body, singleRetrieve); return metadataStructure; } @@ -135,6 +136,7 @@ class AttributeSet extends MetadataType { ) { delete relationship[type + 'Item'].connectingID; } + let relationshipObj = null; switch (relationship[type + 'Item'].relationshipType) { case 'AttributeGroup': { try { @@ -154,7 +156,9 @@ class AttributeSet extends MetadataType { ); } // get relationship fieldnames - // TODO: implement + relationshipObj = { + valueDefinitions: this._getSystemValueDefinitions(), + }; break; } case 'AttributeSet': { @@ -170,7 +174,7 @@ class AttributeSet extends MetadataType { // get relationship fieldnames // check if its a self-reference to metadata.valueDefinitions or if it's a reference to another attributeSet - const relationshipObj = + relationshipObj = relationship[type + 'Item'].r__attributeSet_definitionKey === metadata.definitionKey ? metadata @@ -179,16 +183,6 @@ class AttributeSet extends MetadataType { relationship[type + 'Item'] .r__attributeSet_definitionKey ); - // resolve field values - for (const attr of relationship.relationshipAttributes) { - const id = attr[type + 'AttributeID']; - attr['c__' + type + 'FullyQualifiedName'] = - relationshipObj.valueDefinitions.find( - (item) => item.valueDefinitionID === id - ).fullyQualifiedName; - delete attr[type + 'AttributeID']; - delete attr[type + 'ConnectingID']; - } } catch (ex) { Util.logger.warn( ` - ${this.definition.type} ${ @@ -199,6 +193,32 @@ class AttributeSet extends MetadataType { break; } } + try { + // get relationship fieldnames + // resolve field values + for (const attr of relationship.relationshipAttributes) { + const id = attr[type + 'AttributeID']; + const valueDefinition = relationshipObj.valueDefinitions.find( + (item) => item.valueDefinitionID === id + ); + if (valueDefinition) { + attr['c__' + type + 'FullyQualifiedName'] = + valueDefinition.fullyQualifiedName; + delete attr[type + 'AttributeID']; + delete attr[type + 'ConnectingID']; + } else { + throw new Error( + `Could not find ${type}AttributeID ${id} of relationship ${relationship.relationshipID}` + ); + } + } + } catch (ex) { + Util.logger.warn( + ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ + ex.message + }` + ); + } } } } @@ -206,8 +226,32 @@ class AttributeSet extends MetadataType { // Member ID delete metadata.customObjectOwnerMID; + // connectingID.identifierType seems to be always set to 'FullyQualifiedName' - to be sure we check it here and remove it if it's the case + if (metadata.connectingID?.identifierType === 'FullyQualifiedName') { + // remove useless field + delete metadata.connectingID; + } + return metadata; } + + /** + * helper for {@link postRetrieveTasks} + * + * @returns {object[]} all system value definitions + */ + static _getSystemValueDefinitions() { + if (!this.systemValueDefinitions) { + this.systemValueDefinitions = Object.values(cache.getCache()['attributeSet']) + .flatMap((item) => { + if (item.isSystemDefined) { + return item.valueDefinitions; + } + }) + .filter(Boolean); + } + return this.systemValueDefinitions; + } /** * prepares for deployment * @@ -307,8 +351,28 @@ class AttributeSet extends MetadataType { 'definitionKey', 'definitionID' ); + // get relationship fieldnames - // TODO: implement + // resolve field values + for (const attr of relationship.relationshipAttributes) { + const relationshipObj = cache.getByKey( + 'attributeSet', + attr['c__' + type + 'FullyQualifiedName'].split('.')[0] + ); + attr[type + 'AttributeID'] = relationshipObj.valueDefinitions.find( + (item) => + item.fullyQualifiedName === + attr['c__' + type + 'FullyQualifiedName'] + ).valueDefinitionID; + attr[type + 'ConnectingID'] = attr[type + 'ConnectingID'] || { + identifierType: 'FullyQualifiedName', + }; + + delete attr['c__' + type + 'FullyQualifiedName']; + } + + // cleanup + delete relationship[type + 'Item']?.r__attributeGroup_definitionKey; break; } case 'AttributeSet': { @@ -319,6 +383,7 @@ class AttributeSet extends MetadataType { 'definitionID', 'definitionKey' ); + // get relationship fieldnames // check if its a self-reference to metadata.valueDefinitions or if it's a reference to another attributeSet const relationshipObj = @@ -364,6 +429,19 @@ class AttributeSet extends MetadataType { // Member ID - set to ID of deployment target automatically metadata.customObjectOwnerMID = this.buObject.mid; + // connectingID.identifierType seems to be always set to 'FullyQualifiedName' - we remove it during retrieve and auto-set it here again + if (!metadata.connectingID?.identifierType) { + metadata.connectingID = { + identifierType: 'FullyQualifiedName', + }; + } + + // fullyQualifiedName and definitionName.value are equal to 'name' and need to be auto-populated for deploy + metadata.fullyQualifiedName = metadata.name; + metadata.definitionName = { + value: metadata.name, + }; + return metadata; } } diff --git a/lib/metadataTypes/definitions/AttributeGroup.definition.js b/lib/metadataTypes/definitions/AttributeGroup.definition.js index 9382df3a4..ff3e5a049 100644 --- a/lib/metadataTypes/definitions/AttributeGroup.definition.js +++ b/lib/metadataTypes/definitions/AttributeGroup.definition.js @@ -5,45 +5,48 @@ module.exports = { idField: 'definitionID', keyField: 'definitionKey', nameField: 'definitionName.value', - restPagination: false, + restPagination: false, // Hub API does not support pagination and returns everything instead type: 'attributeGroup', typeDescription: 'BETA: Groupings of Set Definitions (Data Extensions) in Data Designer.', typeRetrieveByDefault: false, typeName: 'Data Designer Attribute Groups', fields: { applicationID: { - isCreateable: null, - isUpdateable: null, - retrieving: true, - template: true, + // used by system generated attribute groups only; contains UUID + isCreateable: false, + isUpdateable: false, + retrieving: false, + template: false, }, applicationKey: { - isCreateable: null, - isUpdateable: null, + // used by system generated attribute groups only + isCreateable: false, + isUpdateable: false, retrieving: true, - template: true, + template: false, }, attributeCount: { - isCreateable: null, - isUpdateable: null, + // auto-populated + isCreateable: false, + isUpdateable: false, retrieving: true, - template: true, + template: false, }, attributeGroupIconKey: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, attributeGroupType: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, attributeSetIdentifiers: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, @@ -78,118 +81,123 @@ module.exports = { template: false, }, canAddProperties: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, canAddRelationships: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, canChangeProperties: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, canModify: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, canRemove: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, connectingID: { - isCreateable: null, - isUpdateable: null, - retrieving: false, - template: false, + isCreateable: true, + isUpdateable: true, + retrieving: true, + template: true, }, 'connectingID.identifierType': { - isCreateable: null, - isUpdateable: null, - retrieving: false, - template: false, + isCreateable: true, + isUpdateable: true, + retrieving: true, + template: true, }, containsSchemaAttributes: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, definitionID: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, - template: true, + template: false, }, definitionKey: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, 'definitionName.value': { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, description: { - isCreateable: null, - isUpdateable: null, + // optional field. not returned by API if empty + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, displayOrder: { - isCreateable: null, - isUpdateable: null, + // auto-set to i+1 + isCreateable: false, + isUpdateable: false, retrieving: true, - template: true, + template: false, }, fullyQualifiedName: { - isCreateable: null, - isUpdateable: null, - retrieving: true, - template: true, + // equal to defitionName.value; auto-populated by preDeployTasks + isCreateable: true, + isUpdateable: true, + retrieving: false, + template: false, }, isHidden: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, isOwner: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, isPrimary: { - isCreateable: null, - isUpdateable: null, - retrieving: true, - template: true, + // always false, purpose unknown + isCreateable: false, + isUpdateable: false, + retrieving: false, + template: false, }, isSystemDefined: { - isCreateable: null, - isUpdateable: null, + isCreateable: false, + isUpdateable: false, retrieving: true, - template: true, + template: false, }, localizedDescription: { - isCreateable: null, - isUpdateable: null, - retrieving: true, - template: true, + // always an empty object + isCreateable: false, + isUpdateable: false, + retrieving: false, + template: false, }, 'localizedDescription.resourceSetKey': { isCreateable: null, @@ -210,26 +218,29 @@ module.exports = { template: true, }, mID: { - isCreateable: null, - isUpdateable: null, + // auto-populated in preDeployTask + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, namespace: { - isCreateable: null, - isUpdateable: null, + // always an empty string + isCreateable: false, + isUpdateable: false, retrieving: false, template: false, }, objectState: { - isCreateable: null, - isUpdateable: null, - retrieving: true, - template: true, + // seems to always contain "Created" + isCreateable: false, + isUpdateable: false, + retrieving: false, + template: false, }, requiredRelationships: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, template: true, }, diff --git a/lib/metadataTypes/definitions/AttributeSet.definition.js b/lib/metadataTypes/definitions/AttributeSet.definition.js index cea97cd10..11bc72bd2 100644 --- a/lib/metadataTypes/definitions/AttributeSet.definition.js +++ b/lib/metadataTypes/definitions/AttributeSet.definition.js @@ -10,7 +10,7 @@ module.exports = { createdNameField: 'createdBy', lastmodDateField: null, lastmodNameField: null, - restPagination: false, + restPagination: false, // Hub API does not support pagination and returns everything instead type: 'attributeSet', typeDescription: 'BETA: Data Extensions linked to Attribute Groups in Data Designer.', typeRetrieveByDefault: false, @@ -65,10 +65,10 @@ module.exports = { template: null, }, 'connectingID.identifierType': { - isCreateable: null, - isUpdateable: null, - retrieving: true, - template: null, + isCreateable: true, + isUpdateable: true, + retrieving: false, + template: false, }, createDate: { isCreateable: null, @@ -130,17 +130,25 @@ module.exports = { retrieving: true, template: null, }, + definitionName: { + isCreateable: true, + isUpdateable: true, + retrieving: false, + template: false, + }, 'definitionName.value': { - isCreateable: null, - isUpdateable: null, - retrieving: true, - template: null, + // equal to 'name'; auto-populated by preDeployTasks + isCreateable: true, + isUpdateable: true, + retrieving: false, + template: false, }, fullyQualifiedName: { - isCreateable: null, - isUpdateable: null, - retrieving: true, - template: null, + // equal to 'name'; auto-populated by preDeployTasks + isCreateable: true, + isUpdateable: true, + retrieving: false, + template: false, }, isCustomObjectBacked: { isCreateable: null, @@ -233,28 +241,28 @@ module.exports = { template: null, }, localizedDescription: { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, - template: null, + template: true, }, 'localizedDescription.resourceSetKey': { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, - template: null, + template: true, }, 'localizedDescription.resourceValueKey': { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, - template: null, + template: true, }, 'localizedDescription.value': { - isCreateable: null, - isUpdateable: null, + isCreateable: true, + isUpdateable: true, retrieving: true, - template: null, + template: true, }, name: { isCreateable: null, From 3dc21f8167efddce25a6130db958fc2da5721d88 Mon Sep 17 00:00:00 2001 From: Yulia Likhytska Date: Thu, 8 Jun 2023 10:22:03 +0200 Subject: [PATCH 009/208] 982-feature/added option to execute after deploy --- lib/Deployer.js | 50 ++++++++++++++++++++++++++++--- lib/cli.js | 16 ++++++++-- lib/index.js | 21 +++++++++++-- lib/metadataTypes/MetadataType.js | 24 +++++++++++++-- lib/metadataTypes/Query.js | 12 ++++++++ 5 files changed, 112 insertions(+), 11 deletions(-) diff --git a/lib/Deployer.js b/lib/Deployer.js index 3d064049a..e0070df4c 100644 --- a/lib/Deployer.js +++ b/lib/Deployer.js @@ -47,7 +47,15 @@ class Deployer { * @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder * @returns {Promise.>} deployed metadata per BU (first key: bu name, second key: metadata type) */ - static async deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve) { + static async deploy( + businessUnit, + selectedTypesArr, + keyArr, + fromRetrieve + // , + // isRefresh, + // isExecute + ) { Util.logger.info('mcdev:: Deploy'); const buMultiMetadataTypeMap = {}; const properties = await config.getProperties(); @@ -99,6 +107,9 @@ class Deployer { selectedTypesArr, keyArr, fromRetrieve + // , + // isRefresh, + // isExecute ); buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap; counter_credBu++; @@ -153,6 +164,9 @@ class Deployer { selectedTypesArr, keyArr, fromRetrieve + // , + // isRefresh, + // isExecute ); buMultiMetadataTypeMap[cred + '/' + buPath] = multiMetadataTypeMap; counter_credBu++; @@ -169,6 +183,9 @@ class Deployer { selectedTypesArr, keyArr, fromRetrieve + // , + // isRefresh, + // isExecute ); counter_credBu++; buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap; @@ -190,7 +207,17 @@ class Deployer { * @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder * @returns {Promise.} ensure that BUs are worked on sequentially */ - static async _deployBU(cred, bu, properties, typeArr, keyArr, fromRetrieve) { + static async _deployBU( + cred, + bu, + properties, + typeArr, + keyArr, + fromRetrieve + // , + // isRefresh, + // isExecute + ) { const buPath = `${cred}/${bu}`; Util.logger.info(`:: Deploying to ${buPath}`); const buObject = await Cli.getCredentialObject(properties, buPath, null, true); @@ -201,7 +228,14 @@ class Deployer { const deployer = new Deployer(properties, buObject); try { // await is required or the calls end up conflicting - multiMetadataTypeMap = await deployer._deploy(typeArr, keyArr, fromRetrieve); + multiMetadataTypeMap = await deployer._deploy( + typeArr, + keyArr, + fromRetrieve + // , + // isRefresh, + // isExecute + ); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.deploy failed'); } @@ -218,7 +252,13 @@ class Deployer { * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets * @returns {Promise.} Promise of all deployed metadata */ - async _deploy(typeArr, keyArr, fromRetrieve, isRefresh) { + async _deploy( + typeArr, + keyArr, + fromRetrieve, + isRefresh + // , isExecute + ) { if (await File.pathExists(this.deployDir)) { /** @type {TYPE.MultiMetadataTypeMap} */ this.metadata = Deployer.readBUMetadata(this.deployDir, typeArr); @@ -299,6 +339,8 @@ class Deployer { this.deployDir, this.retrieveDir, isRefresh + // , + // isExecute ); multiMetadataTypeMap[type] = result; cache.mergeMetadata(type, result); diff --git a/lib/cli.js b/lib/cli.js index 931c78b19..454a6a35a 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -39,7 +39,7 @@ yargs }, }) .command({ - command: 'deploy [BU] [TYPE] [KEY] [--fromRetrieve] [--refresh]', + command: 'deploy [BU] [TYPE] [KEY] [--fromRetrieve] [--refresh] [--execute]', aliases: ['d'], desc: 'deploys local metadata to a business unit', builder: (yargs) => { @@ -75,12 +75,24 @@ yargs type: 'boolean', describe: 'optional for asset-message: runs refresh command for related triggeredSends after deploy', + }) + .option('execute', { + type: 'boolean', + describe: 'optional for query: runs execute after deploy', }); }, handler: (argv) => { Mcdev.setOptions(argv); - Mcdev.deploy(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY), argv.fromRetrieve); + Mcdev.deploy( + argv.BU, + csvToArray(argv.TYPE), + csvToArray(argv.KEY), + argv.fromRetrieve + // , + // argv.refresh, + // argv.execute + ); }, }) .command({ diff --git a/lib/index.js b/lib/index.js index 3589f02b6..169b8ec47 100644 --- a/lib/index.js +++ b/lib/index.js @@ -58,6 +58,7 @@ class Mcdev { 'fromRetrieve', 'json', 'refresh', + 'execute', 'skipInteraction', 'noLogFile', ]; @@ -355,9 +356,25 @@ class Mcdev { * @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder * @returns {Promise.>} deployed metadata per BU (first key: bu name, second key: metadata type) */ - static async deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve = false) { + static async deploy( + businessUnit, + selectedTypesArr, + keyArr, + fromRetrieve = false + // , + // isRefresh = false, + // isExecute = false + ) { Util.startLogger(); - return Deployer.deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve); + return Deployer.deploy( + businessUnit, + selectedTypesArr, + keyArr, + fromRetrieve + // , + // isRefresh, + // isExecute + ); } /** diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 92b1686de..314967012 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -111,8 +111,19 @@ class MetadataType { * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets * @returns {Promise.} Promise of keyField => metadata map */ - static async deploy(metadata, deployDir, retrieveDir, isRefresh) { - const upsertResults = await this.upsert(metadata, deployDir, isRefresh); + static async deploy( + metadata, + deployDir, + retrieveDir, + isRefresh + //, isExecute + ) { + const upsertResults = await this.upsert( + metadata, + deployDir, + isRefresh + //, isExecute + ); const savedMetadata = await this.saveResults(upsertResults, retrieveDir, null); if ( this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type) && @@ -540,7 +551,12 @@ class MetadataType { * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets * @returns {Promise.} keyField => metadata map */ - static async upsert(metadataMap, deployDir, isRefresh) { + static async upsert( + metadataMap, + deployDir, + isRefresh + // , isExecute + ) { const orignalMetadataMap = JSON.parse(JSON.stringify(metadataMap)); const metadataToUpdate = []; const metadataToCreate = []; @@ -637,6 +653,8 @@ class MetadataType { orignalMetadataMap, { created: createResults.length, updated: updateResults.length }, isRefresh + // , + // isExecute ); return upsertResults; } diff --git a/lib/metadataTypes/Query.js b/lib/metadataTypes/Query.js index e91496131..7b61d0cb8 100644 --- a/lib/metadataTypes/Query.js +++ b/lib/metadataTypes/Query.js @@ -452,6 +452,18 @@ class Query extends MetadataType { // delete local copy: retrieve/cred/bu/.../...-meta.sql await super.postDeleteTasks(customerKey, [`${this.definition.type}-meta.sql`]); } + /** + * Gets executed after deployment of metadata type + * + * @param metadata metadata mapped by their keyField + * @param {TYPE.MetadataTypeMap} _ originalMetadata to be updated (contains additioanl fields) + * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates + */ + static async postDeployTasks(metadata, _, createdUpdated) { + if (Util.OPTIONS.execute) { + this.execute(Object.keys(metadata)); + } + } } // Assign definition & cache to static attributes From 4ad994e1ca28efdee9efeea146ebcc5d54f6e4d3 Mon Sep 17 00:00:00 2001 From: Yulia Likhytska Date: Mon, 12 Jun 2023 19:37:47 +0200 Subject: [PATCH 010/208] fixKeys command added --- lib/cli.js | 24 +++++ lib/index.js | 154 ++++++++++++++++++++++++++++++ lib/metadataTypes/MetadataType.js | 36 ++++++- 3 files changed, 212 insertions(+), 2 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 931c78b19..d2d626847 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -413,6 +413,30 @@ yargs Mcdev.execute(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); }, }) + .command({ + command: 'fixKeys [TYPE] [KEY]', + aliases: ['fx'], + desc: 'changes the key of the items to match the name', + builder: (yargs) => { + yargs + .positional('BU', { + type: 'string', + describe: 'the business unit where to fix keys', + }) + .positional('TYPE', { + type: 'string', + describe: 'metadata type', + }) + .positional('KEY', { + type: 'string', + describe: 'key(s) of the metadata component(s)', + }); + }, + handler: (argv) => { + Mcdev.setOptions(argv); + Mcdev.fixKeys(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); + }, + }) .command({ command: 'upgrade', aliases: ['up'], diff --git a/lib/index.js b/lib/index.js index 3589f02b6..dc5e05015 100644 --- a/lib/index.js +++ b/lib/index.js @@ -853,6 +853,160 @@ class Mcdev { } return counter_failed === 0 ? true : false; } + /** + * Updates the key to match the name field + * + * @param {string} bu name of BU + * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit execution to given metadata type + * @param {string[]} keyArr customerkey of the metadata + * @returns {Promise.} true if all items were executed, false otherwise + */ + static async fixKeys(bu, selectedTypesArr, keyArr) { + Util.startLogger(); + Util.logger.info('mcdev:: FixKeys'); + const properties = await config.getProperties(); + let counter_credBu = 0; + let counter_failed = 0; + if (!(await config.checkProperties(properties))) { + // return null here to avoid seeing 2 error messages for the same issue + return null; + } + if (Array.isArray(selectedTypesArr)) { + // types and keys can be provided but for each type all provided keys are applied as filter + for (const selectedType of Array.isArray(selectedTypesArr) + ? selectedTypesArr + : Object.keys(selectedTypesArr)) { + if (!Util._isValidType(selectedType)) { + return; + } + } + } + if (businessUnit === '*') { + Util.logger.info('\n :: Updating keys on all BUs for all credentials'); + let counter_credTotal = 0; + for (const cred in properties.credentials) { + Util.logger.info(`\n :: Updating keys on all BUs for ${cred}`); + + for (const bu in properties.credentials[cred].businessUnits) { + if (await this._fixKeysBU(cred, bu, selectedTypesArr, keys)) { + counter_credBu++; + } else { + counter_failed++; + } + Util.startLogger(true); + } + counter_credTotal += counter_credBu; + Util.logger.info( + `\n :: Updated keys on all BUs on ${counter_credBu} BUs for ${cred}\n` + ); + } + Util.logger.info( + `\n :: Updating keys on ${counter_credTotal} BUs in total\n` + ); + } else { + let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; + // to allow all-BU via user selection we need to run this here already + if ( + properties.credentials && + (!properties.credentials[cred] || + (bu !== '*' && !properties.credentials[cred].businessUnits[bu])) + ) { + const buObject = await Cli.getCredentialObject( + properties, + cred === null ? null : cred + '/' + bu, + null, + true + ); + if (buObject === null) { + return; + } else { + cred = buObject.credential; + bu = buObject.businessUnit; + } + } + if (bu === '*' && properties.credentials && properties.credentials[cred]) { + Util.logger.info(`\n :: Updating keys on all BUs for ${cred}`); + let counter_credBu = 0; + for (const bu in properties.credentials[cred].businessUnits) { + if (await this._fixKeysBU(cred, bu, selectedTypesArr, keys)) { + counter_credBu++; + } else { + counter_failed++; + } + Util.startLogger(true); + } + Util.logger.info( + `\n :: Updated keys on ${counter_credBu} BUs for ${cred}\n` + ); + } else { + // update keys on one BU only + if (await this._fixKeysBU(cred, bu, selectedTypesArr, keys)) { + counter_credBu++; + } else { + counter_failed++; + } + Util.logger.info(`\n :: Done\n`); + } + } + if (counter_credBu !== 0) { + Util.logger.info(`\n :: Updated keys on ${counter_credBu} BUs\n`); + } + return counter_failed === 0 ? true : false; + } + + /** + * helper for {@link fixKeys} + * + * @param {string} cred name of Credential + * @param {string} bu name of BU + * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit execution to given metadata type + * @param {string[]} keyArr customerkey of the metadata + * @returns {Promise.} true if all items were executed, false otherwise + */ + static async _fixKeysBU(cred, bu, selectedTypesArr, keyArr) { + const properties = await config.getProperties(); + let counter_failed = 0; + const buObject = await Cli.getCredentialObject( + properties, + cred === null ? null : cred + '/' + bu, + null, + true + ); + // if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) { + // throw new Error('No keys were provided'); + // } + if (!selectedTypesArr || (Array.isArray(selectedTypesArr) && !selectedTypesArr.length)) { + selectedTypesArr = ['asset']; + } + if (buObject !== null) { + cache.initCache(buObject); + cred = buObject.credential; + bu = buObject.businessUnit; + } + Util.logger.info( + `\n :: Updating keys for ${selectedTypesArr.join( + ', ' + )} on ${cred}/${bu}\n` + ); + try { + // more than one type was provided, iterate types and execute items + for (const type of selectedTypesArr) { + try { + MetadataTypeInfo[type].client = auth.getSDK(buObject); + } catch (ex) { + Util.logger.error(ex.message); + return; + } + // result will be undefined (false) if execute is not supported for the type + if (!(await MetadataTypeInfo[type].changeKeyField(keyArr))) { + counter_failed++; + } + } + } catch (ex) { + Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); + } + return counter_failed === 0 ? true : false; + } } module.exports = Mcdev; diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 92b1686de..44f1620e1 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -686,7 +686,7 @@ class MetadataType { hasError = true; } if (Util.OPTIONS.changeKeyField) { - if (this.definition.keyField == this.definition.idField) { + /*if (this.definition.keyField == this.definition.idField) { Util.logger.error( ` - --changeKeyField cannot be used for types that use their ID as key. Skipping change.` ); @@ -731,7 +731,9 @@ class MetadataType { Util.changedKeysMap[this.definition.type] ||= {}; Util.changedKeysMap[this.definition.type][newKey] = metadataKey; } - } + }*/ + + this.changeKeyField(); } else if (Util.OPTIONS.changeKeyValue) { // NOTE: trim twice while getting the newKey value to remove leading spaces before limiting the length const newKey = Util.OPTIONS.changeKeyValue.trim().slice(0, maxKeyLength).trim(); @@ -793,6 +795,36 @@ class MetadataType { } } } + /** + * + */ + static async changeKeyField() { + console.log('**** Changing keys'); + // NOTE: trim twice while getting the newKey value to remove leading spaces before limiting the length + const newKey = (metadataMap[metadataKey][Util.OPTIONS.changeKeyField] + '') + .trim() + .slice(0, maxKeyLength) + .trim(); + if (metadataMap[metadataKey][Util.OPTIONS.changeKeyField] + '' > maxKeyLength) { + Util.logger.warn( + `${this.definition.type} ${this.definition.keyField} may not exceed ${maxKeyLength} characters. Truncated the value in field ${Util.OPTIONS.changeKeyField} to ${newKey}` + ); + } + if (metadataKey == newKey) { + Util.logger.warn( + ` - --changeKeyField(${Util.OPTIONS.changeKeyField}) is providing the current value of the key (${metadataKey}). Skipping change.` + ); + } else { + Util.logger.info( + ` - Changing ${this.definition.type} key from ${metadataKey} to ${newKey} via --changeKeyField=${Util.OPTIONS.changeKeyField}` + ); + metadataMap[metadataKey][this.definition.keyField] = newKey; + + // ensure we can delete the old file(s) after the successful update + Util.changedKeysMap[this.definition.type] ||= {}; + Util.changedKeysMap[this.definition.type][newKey] = metadataKey; + } + } /** * Creates a single metadata entry via REST From 0e6dccd204909b22c60a49df1b5ecc5d7dd98bab Mon Sep 17 00:00:00 2001 From: Yulia Likhytska Date: Mon, 12 Jun 2023 20:07:16 +0200 Subject: [PATCH 011/208] 982-feature/removed comments --- lib/Deployer.js | 50 +++---------------------------- lib/cli.js | 10 +------ lib/index.js | 20 ++----------- lib/metadataTypes/MetadataType.js | 24 ++------------- lib/metadataTypes/Query.js | 4 +-- 5 files changed, 11 insertions(+), 97 deletions(-) diff --git a/lib/Deployer.js b/lib/Deployer.js index e0070df4c..3d064049a 100644 --- a/lib/Deployer.js +++ b/lib/Deployer.js @@ -47,15 +47,7 @@ class Deployer { * @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder * @returns {Promise.>} deployed metadata per BU (first key: bu name, second key: metadata type) */ - static async deploy( - businessUnit, - selectedTypesArr, - keyArr, - fromRetrieve - // , - // isRefresh, - // isExecute - ) { + static async deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve) { Util.logger.info('mcdev:: Deploy'); const buMultiMetadataTypeMap = {}; const properties = await config.getProperties(); @@ -107,9 +99,6 @@ class Deployer { selectedTypesArr, keyArr, fromRetrieve - // , - // isRefresh, - // isExecute ); buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap; counter_credBu++; @@ -164,9 +153,6 @@ class Deployer { selectedTypesArr, keyArr, fromRetrieve - // , - // isRefresh, - // isExecute ); buMultiMetadataTypeMap[cred + '/' + buPath] = multiMetadataTypeMap; counter_credBu++; @@ -183,9 +169,6 @@ class Deployer { selectedTypesArr, keyArr, fromRetrieve - // , - // isRefresh, - // isExecute ); counter_credBu++; buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap; @@ -207,17 +190,7 @@ class Deployer { * @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder * @returns {Promise.} ensure that BUs are worked on sequentially */ - static async _deployBU( - cred, - bu, - properties, - typeArr, - keyArr, - fromRetrieve - // , - // isRefresh, - // isExecute - ) { + static async _deployBU(cred, bu, properties, typeArr, keyArr, fromRetrieve) { const buPath = `${cred}/${bu}`; Util.logger.info(`:: Deploying to ${buPath}`); const buObject = await Cli.getCredentialObject(properties, buPath, null, true); @@ -228,14 +201,7 @@ class Deployer { const deployer = new Deployer(properties, buObject); try { // await is required or the calls end up conflicting - multiMetadataTypeMap = await deployer._deploy( - typeArr, - keyArr, - fromRetrieve - // , - // isRefresh, - // isExecute - ); + multiMetadataTypeMap = await deployer._deploy(typeArr, keyArr, fromRetrieve); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.deploy failed'); } @@ -252,13 +218,7 @@ class Deployer { * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets * @returns {Promise.} Promise of all deployed metadata */ - async _deploy( - typeArr, - keyArr, - fromRetrieve, - isRefresh - // , isExecute - ) { + async _deploy(typeArr, keyArr, fromRetrieve, isRefresh) { if (await File.pathExists(this.deployDir)) { /** @type {TYPE.MultiMetadataTypeMap} */ this.metadata = Deployer.readBUMetadata(this.deployDir, typeArr); @@ -339,8 +299,6 @@ class Deployer { this.deployDir, this.retrieveDir, isRefresh - // , - // isExecute ); multiMetadataTypeMap[type] = result; cache.mergeMetadata(type, result); diff --git a/lib/cli.js b/lib/cli.js index 454a6a35a..39142f263 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -84,15 +84,7 @@ yargs handler: (argv) => { Mcdev.setOptions(argv); - Mcdev.deploy( - argv.BU, - csvToArray(argv.TYPE), - csvToArray(argv.KEY), - argv.fromRetrieve - // , - // argv.refresh, - // argv.execute - ); + Mcdev.deploy(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY), argv.fromRetrieve); }, }) .command({ diff --git a/lib/index.js b/lib/index.js index 169b8ec47..5ee214b46 100644 --- a/lib/index.js +++ b/lib/index.js @@ -356,25 +356,9 @@ class Mcdev { * @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder * @returns {Promise.>} deployed metadata per BU (first key: bu name, second key: metadata type) */ - static async deploy( - businessUnit, - selectedTypesArr, - keyArr, - fromRetrieve = false - // , - // isRefresh = false, - // isExecute = false - ) { + static async deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve = false) { Util.startLogger(); - return Deployer.deploy( - businessUnit, - selectedTypesArr, - keyArr, - fromRetrieve - // , - // isRefresh, - // isExecute - ); + return Deployer.deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve); } /** diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 314967012..92b1686de 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -111,19 +111,8 @@ class MetadataType { * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets * @returns {Promise.} Promise of keyField => metadata map */ - static async deploy( - metadata, - deployDir, - retrieveDir, - isRefresh - //, isExecute - ) { - const upsertResults = await this.upsert( - metadata, - deployDir, - isRefresh - //, isExecute - ); + static async deploy(metadata, deployDir, retrieveDir, isRefresh) { + const upsertResults = await this.upsert(metadata, deployDir, isRefresh); const savedMetadata = await this.saveResults(upsertResults, retrieveDir, null); if ( this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type) && @@ -551,12 +540,7 @@ class MetadataType { * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets * @returns {Promise.} keyField => metadata map */ - static async upsert( - metadataMap, - deployDir, - isRefresh - // , isExecute - ) { + static async upsert(metadataMap, deployDir, isRefresh) { const orignalMetadataMap = JSON.parse(JSON.stringify(metadataMap)); const metadataToUpdate = []; const metadataToCreate = []; @@ -653,8 +637,6 @@ class MetadataType { orignalMetadataMap, { created: createResults.length, updated: updateResults.length }, isRefresh - // , - // isExecute ); return upsertResults; } diff --git a/lib/metadataTypes/Query.js b/lib/metadataTypes/Query.js index 7b61d0cb8..7578b0292 100644 --- a/lib/metadataTypes/Query.js +++ b/lib/metadataTypes/Query.js @@ -456,10 +456,8 @@ class Query extends MetadataType { * Gets executed after deployment of metadata type * * @param metadata metadata mapped by their keyField - * @param {TYPE.MetadataTypeMap} _ originalMetadata to be updated (contains additioanl fields) - * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates */ - static async postDeployTasks(metadata, _, createdUpdated) { + static async postDeployTasks(metadata) { if (Util.OPTIONS.execute) { this.execute(Object.keys(metadata)); } From 4182f3aeee46cd2831de92ebc419e1d02a6c5df6 Mon Sep 17 00:00:00 2001 From: Yulia Likhytska Date: Fri, 16 Jun 2023 21:40:40 +0200 Subject: [PATCH 012/208] 988-bug/read refresh from options --- lib/Deployer.js | 6 ++---- lib/metadataTypes/Asset.js | 7 +++---- lib/metadataTypes/Automation.js | 5 ++--- lib/metadataTypes/Event.js | 5 ++--- lib/metadataTypes/Journey.js | 5 ++--- lib/metadataTypes/MetadataType.js | 21 ++++++++------------- 6 files changed, 19 insertions(+), 30 deletions(-) diff --git a/lib/Deployer.js b/lib/Deployer.js index 3d064049a..49485d2f8 100644 --- a/lib/Deployer.js +++ b/lib/Deployer.js @@ -215,10 +215,9 @@ class Deployer { * @param {TYPE.SupportedMetadataTypes[]} [typeArr] limit deployment to given metadata type (can include subtype) * @param {string[]} [keyArr] limit deployment to given metadata keys * @param {boolean} [fromRetrieve] if true, no folders will be updated/created - * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets * @returns {Promise.} Promise of all deployed metadata */ - async _deploy(typeArr, keyArr, fromRetrieve, isRefresh) { + async _deploy(typeArr, keyArr, fromRetrieve) { if (await File.pathExists(this.deployDir)) { /** @type {TYPE.MultiMetadataTypeMap} */ this.metadata = Deployer.readBUMetadata(this.deployDir, typeArr); @@ -297,8 +296,7 @@ class Deployer { const result = await MetadataTypeInfo[type].deploy( this.metadata[type], this.deployDir, - this.retrieveDir, - isRefresh + this.retrieveDir ); multiMetadataTypeMap[type] = result; cache.mergeMetadata(type, result); diff --git a/lib/metadataTypes/Asset.js b/lib/metadataTypes/Asset.js index 3ff861cce..7c89071c1 100644 --- a/lib/metadataTypes/Asset.js +++ b/lib/metadataTypes/Asset.js @@ -504,11 +504,10 @@ class Asset extends MetadataType { * @param {TYPE.MetadataTypeMap} metadata metadata mapped by their keyField * @param {TYPE.MetadataTypeMap} _ originalMetadata to be updated (contains additioanl fields) * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates - * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets * @returns {Promise.} - */ - static async postDeployTasks(metadata, _, createdUpdated, isRefresh) { - if (isRefresh) { + static async postDeployTasks(metadata, _, createdUpdated) { + if (Util.OPTIONS.refresh) { if (createdUpdated.updated) { // only run this if assets were updated. for created assets we do not expect this._refreshTriggeredSend(metadata); @@ -521,7 +520,7 @@ class Asset extends MetadataType { } /** - * helper for {@link postDeployTasks}. triggers a refresh of active triggerredSendDefinitions associated with the updated asset-message items. Gets executed if isRefresh is true. + * helper for {@link postDeployTasks}. triggers a refresh of active triggerredSendDefinitions associated with the updated asset-message items. Gets executed if refresh option has been set. * * @private * @param {TYPE.MetadataTypeMap} metadata metadata mapped by their keyField diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index 560ed94e3..b2aaefa01 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -452,11 +452,10 @@ class Automation extends MetadataType { * @param {TYPE.AutomationMap} metadata metadata mapped by their keyField * @param {string} targetBU name/shorthand of target businessUnit for mapping * @param {string} retrieveDir directory where metadata after deploy should be saved - * @param {boolean} [isRefresh] optional flag - so far not used by automation * @returns {Promise.} Promise */ - static async deploy(metadata, targetBU, retrieveDir, isRefresh) { - const upsertResults = await this.upsert(metadata, targetBU, isRefresh); + static async deploy(metadata, targetBU, retrieveDir) { + const upsertResults = await this.upsert(metadata, targetBU); const savedMetadata = await this.saveResults(upsertResults, retrieveDir, null); if ( this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type) && diff --git a/lib/metadataTypes/Event.js b/lib/metadataTypes/Event.js index 3062acfd4..864cd925c 100644 --- a/lib/metadataTypes/Event.js +++ b/lib/metadataTypes/Event.js @@ -136,12 +136,11 @@ class Event extends MetadataType { * @param {TYPE.MetadataTypeMap} metadata metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @param {string} retrieveDir directory where metadata after deploy should be saved - * @param {boolean} [isRefresh] optional flag - so far not used by eventDefinition * @returns {Promise.} Promise of keyField => metadata map */ - static async deploy(metadata, deployDir, retrieveDir, isRefresh) { + static async deploy(metadata, deployDir, retrieveDir) { Util.logBeta(this.definition.type); - return super.deploy(metadata, deployDir, retrieveDir, isRefresh); + return super.deploy(metadata, deployDir, retrieveDir); } /** diff --git a/lib/metadataTypes/Journey.js b/lib/metadataTypes/Journey.js index 7c20b2ee3..87e03e2b5 100644 --- a/lib/metadataTypes/Journey.js +++ b/lib/metadataTypes/Journey.js @@ -216,12 +216,11 @@ class Journey extends MetadataType { * @param {TYPE.MetadataTypeMap} metadata metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @param {string} retrieveDir directory where metadata after deploy should be saved - * @param {boolean} [isRefresh] optional flag - so far not used by interaction * @returns {Promise.} Promise of keyField => metadata map */ - static async deploy(metadata, deployDir, retrieveDir, isRefresh) { + static async deploy(metadata, deployDir, retrieveDir) { Util.logBeta(this.definition.type); - return super.deploy(metadata, deployDir, retrieveDir, isRefresh); + return super.deploy(metadata, deployDir, retrieveDir); } /** diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 92b1686de..dd8f99c1e 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -108,11 +108,10 @@ class MetadataType { * @param {TYPE.MetadataTypeMap} metadata metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved * @param {string} retrieveDir directory where metadata after deploy should be saved - * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets * @returns {Promise.} Promise of keyField => metadata map */ - static async deploy(metadata, deployDir, retrieveDir, isRefresh) { - const upsertResults = await this.upsert(metadata, deployDir, isRefresh); + static async deploy(metadata, deployDir, retrieveDir) { + const upsertResults = await this.upsert(metadata, deployDir); const savedMetadata = await this.saveResults(upsertResults, retrieveDir, null); if ( this.properties.metaDataTypes.documentOnRetrieve.includes(this.definition.type) && @@ -131,10 +130,9 @@ class MetadataType { * @param {TYPE.MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create * @param {TYPE.MetadataTypeMap} originalMetadata metadata to be updated (contains additioanl fields) * @param {{created: number, updated: number}} createdUpdated counter representing successful creates/updates - * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets * @returns {void} */ - static postDeployTasks(upsertResults, originalMetadata, createdUpdated, isRefresh) {} + static postDeployTasks(upsertResults, originalMetadata, createdUpdated) {} /** * helper for {@link createREST} @@ -537,10 +535,9 @@ class MetadataType { * * @param {TYPE.MetadataTypeMap} metadataMap metadata mapped by their keyField * @param {string} deployDir directory where deploy metadata are saved - * @param {boolean} [isRefresh] optional flag to indicate that triggeredSend should be refreshed after deployment of assets * @returns {Promise.} keyField => metadata map */ - static async upsert(metadataMap, deployDir, isRefresh) { + static async upsert(metadataMap, deployDir) { const orignalMetadataMap = JSON.parse(JSON.stringify(metadataMap)); const metadataToUpdate = []; const metadataToCreate = []; @@ -632,12 +629,10 @@ class MetadataType { const metadataResults = createResults.concat(updateResults).filter(Boolean); upsertResults = this.parseResponseBody(metadataResults); } - await this.postDeployTasks( - upsertResults, - orignalMetadataMap, - { created: createResults.length, updated: updateResults.length }, - isRefresh - ); + await this.postDeployTasks(upsertResults, orignalMetadataMap, { + created: createResults.length, + updated: updateResults.length, + }); return upsertResults; } From 4093f49bfe64f026eaee372dce83ac5f02768789 Mon Sep 17 00:00:00 2001 From: Yulia Likhytska Date: Fri, 16 Jun 2023 21:43:32 +0200 Subject: [PATCH 013/208] 988-bugfix/temporarily commented out setFolderPath --- lib/metadataTypes/TriggeredSend.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/metadataTypes/TriggeredSend.js b/lib/metadataTypes/TriggeredSend.js index 26b3ca33d..d8a204fbf 100644 --- a/lib/metadataTypes/TriggeredSend.js +++ b/lib/metadataTypes/TriggeredSend.js @@ -127,17 +127,16 @@ class TriggeredSend extends MetadataType { // remove IsPlatformObject, always has to be 'false' delete metadata.IsPlatformObject; // folder - try { - this.setFolderPath(metadata); - } catch { - Util.logger.verbose( - ` ☇ skipping ${this.definition.typeName} '${metadata.Name}'/'${metadata.CustomerKey}': Could not find folder.` - ); - // do not save this TSD because it would not be visible in the user interface - return; - } - - // email + // try { + // this.setFolderPath(metadata); + // } catch { + // Util.logger.verbose( + // ` ☇ skipping ${this.definition.typeName} '${metadata.Name}'/'${metadata.CustomerKey}': Could not find folder.` + // ); + // // do not save this TSD because it would not be visible in the user interface + // return; + // } + // // email try { // classic const classicEmail = cache.searchForField('email', metadata.Email.ID, 'ID', 'Name'); From b4ebec4636b2f76704fe3f60880848885a7d6673 Mon Sep 17 00:00:00 2001 From: Yulia Likhytska Date: Sun, 18 Jun 2023 16:09:39 +0200 Subject: [PATCH 014/208] 38-add-fixKeys-command --- lib/cli.js | 2 +- lib/index.js | 147 ++++++++++-------------------- lib/metadataTypes/MetadataType.js | 36 +------- 3 files changed, 50 insertions(+), 135 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index d2d626847..59bc224ea 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -414,7 +414,7 @@ yargs }, }) .command({ - command: 'fixKeys [TYPE] [KEY]', + command: 'fixKeys [KEY]', aliases: ['fx'], desc: 'changes the key of the items to match the name', builder: (yargs) => { diff --git a/lib/index.js b/lib/index.js index dc5e05015..40ecae412 100644 --- a/lib/index.js +++ b/lib/index.js @@ -859,11 +859,11 @@ class Mcdev { * @param {string} bu name of BU * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit execution to given metadata type * @param {string[]} keyArr customerkey of the metadata - * @returns {Promise.} true if all items were executed, false otherwise + * @returns {Promise.>} deployed metadata per BU (first key: bu name, second key: metadata type) */ - static async fixKeys(bu, selectedTypesArr, keyArr) { + static async fixKeys(businessUnit, type, keys) { Util.startLogger(); - Util.logger.info('mcdev:: FixKeys'); + Util.logger.info('mcdev:: fixKeys'); const properties = await config.getProperties(); let counter_credBu = 0; let counter_failed = 0; @@ -871,83 +871,38 @@ class Mcdev { // return null here to avoid seeing 2 error messages for the same issue return null; } - if (Array.isArray(selectedTypesArr)) { - // types and keys can be provided but for each type all provided keys are applied as filter - for (const selectedType of Array.isArray(selectedTypesArr) - ? selectedTypesArr - : Object.keys(selectedTypesArr)) { - if (!Util._isValidType(selectedType)) { - return; - } - } + //TODO: check if type exists + if (Array.isArray(type) && type.length > 1) { + Util.logger.error('fixKeys expects a single type to be deployed'); + return null; } - if (businessUnit === '*') { - Util.logger.info('\n :: Updating keys on all BUs for all credentials'); - let counter_credTotal = 0; - for (const cred in properties.credentials) { - Util.logger.info(`\n :: Updating keys on all BUs for ${cred}`); - - for (const bu in properties.credentials[cred].businessUnits) { - if (await this._fixKeysBU(cred, bu, selectedTypesArr, keys)) { - counter_credBu++; - } else { - counter_failed++; - } - Util.startLogger(true); - } - counter_credTotal += counter_credBu; - Util.logger.info( - `\n :: Updated keys on all BUs on ${counter_credBu} BUs for ${cred}\n` - ); - } - Util.logger.info( - `\n :: Updating keys on ${counter_credTotal} BUs in total\n` + let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; + // to allow all-BU via user selection we need to run this here already + if ( + properties.credentials && + (!properties.credentials[cred] || + (bu !== '*' && !properties.credentials[cred].businessUnits[bu])) + ) { + const buObject = await Cli.getCredentialObject( + properties, + cred === null ? null : cred + '/' + bu, + null, + true ); - } else { - let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; - // to allow all-BU via user selection we need to run this here already - if ( - properties.credentials && - (!properties.credentials[cred] || - (bu !== '*' && !properties.credentials[cred].businessUnits[bu])) - ) { - const buObject = await Cli.getCredentialObject( - properties, - cred === null ? null : cred + '/' + bu, - null, - true - ); - if (buObject === null) { - return; - } else { - cred = buObject.credential; - bu = buObject.businessUnit; - } - } - if (bu === '*' && properties.credentials && properties.credentials[cred]) { - Util.logger.info(`\n :: Updating keys on all BUs for ${cred}`); - let counter_credBu = 0; - for (const bu in properties.credentials[cred].businessUnits) { - if (await this._fixKeysBU(cred, bu, selectedTypesArr, keys)) { - counter_credBu++; - } else { - counter_failed++; - } - Util.startLogger(true); - } - Util.logger.info( - `\n :: Updated keys on ${counter_credBu} BUs for ${cred}\n` - ); + if (buObject === null) { + return; } else { - // update keys on one BU only - if (await this._fixKeysBU(cred, bu, selectedTypesArr, keys)) { - counter_credBu++; - } else { - counter_failed++; - } - Util.logger.info(`\n :: Done\n`); + cred = buObject.credential; + bu = buObject.businessUnit; } } + // update keys on a BU + if (await this._fixKeysBU(cred, bu, type, keys)) { + counter_credBu++; + } else { + counter_failed++; + } + Util.logger.info(`\n :: Done\n`); if (counter_credBu !== 0) { Util.logger.info(`\n :: Updated keys on ${counter_credBu} BUs\n`); } @@ -961,9 +916,9 @@ class Mcdev { * @param {string} bu name of BU * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit execution to given metadata type * @param {string[]} keyArr customerkey of the metadata - * @returns {Promise.} true if all items were executed, false otherwise + * @returns {Promise.>} deployed metadata per BU (first key: bu name, second key: metadata type) */ - static async _fixKeysBU(cred, bu, selectedTypesArr, keyArr) { + static async _fixKeysBU(cred, bu, type, keyArr) { const properties = await config.getProperties(); let counter_failed = 0; const buObject = await Cli.getCredentialObject( @@ -972,36 +927,28 @@ class Mcdev { null, true ); - // if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) { - // throw new Error('No keys were provided'); - // } - if (!selectedTypesArr || (Array.isArray(selectedTypesArr) && !selectedTypesArr.length)) { - selectedTypesArr = ['asset']; - } if (buObject !== null) { cache.initCache(buObject); cred = buObject.credential; bu = buObject.businessUnit; } - Util.logger.info( - `\n :: Updating keys for ${selectedTypesArr.join( - ', ' - )} on ${cred}/${bu}\n` - ); + Util.logger.info(`\n :: Updating keys for ${type} on ${cred}/${bu}\n`); try { - // more than one type was provided, iterate types and execute items - for (const type of selectedTypesArr) { - try { - MetadataTypeInfo[type].client = auth.getSDK(buObject); - } catch (ex) { - Util.logger.error(ex.message); - return; - } - // result will be undefined (false) if execute is not supported for the type - if (!(await MetadataTypeInfo[type].changeKeyField(keyArr))) { - counter_failed++; - } + try { + MetadataTypeInfo[type].client = auth.getSDK(buObject); + } catch (ex) { + Util.logger.error(ex.message); + return; + } + Util.logger.info('First retrieve'); + await this._retrieveBU(cred, bu, type, keyArr); + Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; + const properties = await config.getProperties(); + if (!(await config.checkProperties(properties))) { + return null; } + properties.directories.deploy = properties.directories.retrieve; + return await Deployer._deployBU(cred, bu, properties, type, keyArr, true); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 44f1620e1..92b1686de 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -686,7 +686,7 @@ class MetadataType { hasError = true; } if (Util.OPTIONS.changeKeyField) { - /*if (this.definition.keyField == this.definition.idField) { + if (this.definition.keyField == this.definition.idField) { Util.logger.error( ` - --changeKeyField cannot be used for types that use their ID as key. Skipping change.` ); @@ -731,9 +731,7 @@ class MetadataType { Util.changedKeysMap[this.definition.type] ||= {}; Util.changedKeysMap[this.definition.type][newKey] = metadataKey; } - }*/ - - this.changeKeyField(); + } } else if (Util.OPTIONS.changeKeyValue) { // NOTE: trim twice while getting the newKey value to remove leading spaces before limiting the length const newKey = Util.OPTIONS.changeKeyValue.trim().slice(0, maxKeyLength).trim(); @@ -795,36 +793,6 @@ class MetadataType { } } } - /** - * - */ - static async changeKeyField() { - console.log('**** Changing keys'); - // NOTE: trim twice while getting the newKey value to remove leading spaces before limiting the length - const newKey = (metadataMap[metadataKey][Util.OPTIONS.changeKeyField] + '') - .trim() - .slice(0, maxKeyLength) - .trim(); - if (metadataMap[metadataKey][Util.OPTIONS.changeKeyField] + '' > maxKeyLength) { - Util.logger.warn( - `${this.definition.type} ${this.definition.keyField} may not exceed ${maxKeyLength} characters. Truncated the value in field ${Util.OPTIONS.changeKeyField} to ${newKey}` - ); - } - if (metadataKey == newKey) { - Util.logger.warn( - ` - --changeKeyField(${Util.OPTIONS.changeKeyField}) is providing the current value of the key (${metadataKey}). Skipping change.` - ); - } else { - Util.logger.info( - ` - Changing ${this.definition.type} key from ${metadataKey} to ${newKey} via --changeKeyField=${Util.OPTIONS.changeKeyField}` - ); - metadataMap[metadataKey][this.definition.keyField] = newKey; - - // ensure we can delete the old file(s) after the successful update - Util.changedKeysMap[this.definition.type] ||= {}; - Util.changedKeysMap[this.definition.type][newKey] = metadataKey; - } - } /** * Creates a single metadata entry via REST From 78186c422b8b1ded66a7fb260ccb020162ef11f7 Mon Sep 17 00:00:00 2001 From: "Likhytska, Yulia (contracted)" Date: Fri, 23 Jun 2023 21:41:06 +0200 Subject: [PATCH 015/208] 982-feature/added a test method for deploy with --execute --- test/type.query.test.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/type.query.test.js b/test/type.query.test.js index edaf72161..5538422c3 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -124,6 +124,18 @@ describe('type: query', () => { return; }); it('Should change the key during update with --changeKeyValue'); + it('Should deploy and execute with --execute', async () => { + handler.setOptions({ execute: true }); + // WHEN + await handler.deploy('testInstance/testBU', ['query'], ['testNew_query']); + // THEN + assert.equal( + process.exitCode, + false, + 'deploy with --execute should not have thrown an error' + ); + return; + }); }); describe('Templating ================', () => { it('Should create a query template via retrieveAsTemplate and build it', async () => { From 8df5736f99922a647feddf01fd7d4df29c51f837 Mon Sep 17 00:00:00 2001 From: "Likhytska, Yulia (contracted)" Date: Sat, 24 Jun 2023 20:49:01 +0200 Subject: [PATCH 016/208] 982-feature/test method --- test/type.query.test.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/test/type.query.test.js b/test/type.query.test.js index 5538422c3..2a3895d1d 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -127,13 +127,28 @@ describe('type: query', () => { it('Should deploy and execute with --execute', async () => { handler.setOptions({ execute: true }); // WHEN - await handler.deploy('testInstance/testBU', ['query'], ['testNew_query']); + await handler.deploy('testInstance/testBU', ['query'], 'testNew_query'); // THEN assert.equal( process.exitCode, false, 'deploy with --execute should not have thrown an error' ); + // confirm created item + assert.deepEqual( + await testUtils.getActualJson('testNew_query', 'query'), + await testUtils.getExpectedJson('9999999', 'query', 'post'), + 'returned metadata was not equal expected for insert query' + ); + expect(file(testUtils.getActualFile('testNew_query', 'query', 'sql'))).to.equal( + file(testUtils.getExpectedFile('9999999', 'query', 'post', 'sql')) + ); + // check number of API calls + assert.equal( + testUtils.getAPIHistoryLength(), + 12, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); return; }); }); From 3c0fa6f14c404c133ee6f033d4ca3740b54a2a54 Mon Sep 17 00:00:00 2001 From: "Likhytska, Yulia (contracted)" Date: Sat, 24 Jun 2023 23:43:31 +0200 Subject: [PATCH 017/208] 988-bug/inform user when a folder was not found and exit function --- lib/metadataTypes/TriggeredSend.js | 18 +++++++++--------- lib/util/cache.js | 3 +++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/metadataTypes/TriggeredSend.js b/lib/metadataTypes/TriggeredSend.js index d8a204fbf..fe201098c 100644 --- a/lib/metadataTypes/TriggeredSend.js +++ b/lib/metadataTypes/TriggeredSend.js @@ -127,15 +127,15 @@ class TriggeredSend extends MetadataType { // remove IsPlatformObject, always has to be 'false' delete metadata.IsPlatformObject; // folder - // try { - // this.setFolderPath(metadata); - // } catch { - // Util.logger.verbose( - // ` ☇ skipping ${this.definition.typeName} '${metadata.Name}'/'${metadata.CustomerKey}': Could not find folder.` - // ); - // // do not save this TSD because it would not be visible in the user interface - // return; - // } + try { + this.setFolderPath(metadata); + } catch { + Util.logger.verbose( + ` ☇ skipping ${this.definition.typeName} '${metadata.Name}'/'${metadata.CustomerKey}': Could not find folder.` + ); + // do not save this TSD because it would not be visible in the user interface + return; + } // // email try { // classic diff --git a/lib/util/cache.js b/lib/util/cache.js index bcea3a35d..894a190c2 100644 --- a/lib/util/cache.js +++ b/lib/util/cache.js @@ -114,6 +114,9 @@ module.exports = { `${metadataType} with ${searchField} '${searchValue}' does not have field '${returnField}'` ); } + } else { + Util.logger.info(`Didn't find a folder with such ID`); + return; } } throw new Error( From 46f5a0518b54aac09176f8bc875ddb4562daa39e Mon Sep 17 00:00:00 2001 From: "Likhytska, Yulia (contracted)" Date: Sun, 25 Jun 2023 10:57:20 +0200 Subject: [PATCH 018/208] 988-bug/error handling --- lib/util/cache.js | 61 +++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/lib/util/cache.js b/lib/util/cache.js index 894a190c2..fef96b328 100644 --- a/lib/util/cache.js +++ b/lib/util/cache.js @@ -88,40 +88,43 @@ module.exports = { * @returns {string|number|boolean} value of specified field. Error is thrown if not found */ searchForField(metadataType, searchValue, searchField, returnField, overrideMID) { - for (const key in dataStore[overrideMID || currentMID]?.[metadataType]) { - if ( - Util.resolveObjPath( - searchField, - dataStore[overrideMID || currentMID][metadataType][key] - ) == searchValue - ) { - try { - if ( - Util.resolveObjPath( - returnField, - dataStore[overrideMID || currentMID][metadataType][key] - ) - ) { - return Util.resolveObjPath( - returnField, - dataStore[overrideMID || currentMID][metadataType][key] + try { + for (const key in dataStore[overrideMID || currentMID]?.[metadataType]) { + if ( + Util.resolveObjPath( + searchField, + dataStore[overrideMID || currentMID][metadataType][key] + ) == searchValue + ) { + try { + if ( + Util.resolveObjPath( + returnField, + dataStore[overrideMID || currentMID][metadataType][key] + ) + ) { + return Util.resolveObjPath( + returnField, + dataStore[overrideMID || currentMID][metadataType][key] + ); + } else { + throw new Error(); // eslint-disable-line unicorn/error-message + } + } catch { + throw new Error( + `${metadataType} with ${searchField} '${searchValue}' does not have field '${returnField}'` ); - } else { - throw new Error(); // eslint-disable-line unicorn/error-message } - } catch { - throw new Error( - `${metadataType} with ${searchField} '${searchValue}' does not have field '${returnField}'` - ); } - } else { - Util.logger.info(`Didn't find a folder with such ID`); - return; } + throw new Error( + `Dependent ${metadataType} with ${searchField}='${searchValue}' was not found on your BU` + ); + } catch (ex) { + Util.logger.error( + ` ☇ skipping ${metadataType}: ID=${searchValue}- not found on server` + ); } - throw new Error( - `Dependent ${metadataType} with ${searchField}='${searchValue}' was not found on your BU` - ); }, /** * standardized method for getting data from cache - adapted for special case of lists From 86fb92c5fd9ab8e304cda065f203f40c0c76b143 Mon Sep 17 00:00:00 2001 From: "Likhytska, Yulia (contracted)" Date: Sun, 25 Jun 2023 11:00:35 +0200 Subject: [PATCH 019/208] 988-bug/minor correction --- lib/metadataTypes/TriggeredSend.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/metadataTypes/TriggeredSend.js b/lib/metadataTypes/TriggeredSend.js index fe201098c..932751285 100644 --- a/lib/metadataTypes/TriggeredSend.js +++ b/lib/metadataTypes/TriggeredSend.js @@ -136,7 +136,7 @@ class TriggeredSend extends MetadataType { // do not save this TSD because it would not be visible in the user interface return; } - // // email + // email try { // classic const classicEmail = cache.searchForField('email', metadata.Email.ID, 'ID', 'Name'); From a4fd1aaa79422978906a7ae9f25c6565ee265052 Mon Sep 17 00:00:00 2001 From: "Likhytska, Yulia (contracted)" Date: Sun, 25 Jun 2023 11:02:59 +0200 Subject: [PATCH 020/208] 988-bug/minor correction --- lib/util/cache.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/cache.js b/lib/util/cache.js index fef96b328..d4fe67247 100644 --- a/lib/util/cache.js +++ b/lib/util/cache.js @@ -120,7 +120,7 @@ module.exports = { throw new Error( `Dependent ${metadataType} with ${searchField}='${searchValue}' was not found on your BU` ); - } catch (ex) { + } catch { Util.logger.error( ` ☇ skipping ${metadataType}: ID=${searchValue}- not found on server` ); From 1466d4dafe23c5d8eb324a4c525fa84e3dd7beda Mon Sep 17 00:00:00 2001 From: "Likhytska, Yulia (contracted)" Date: Sun, 25 Jun 2023 16:52:11 +0200 Subject: [PATCH 021/208] 988-bugfix/error handling --- lib/metadataTypes/TriggeredSend.js | 5 ++- lib/util/cache.js | 58 ++++++++++++++---------------- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/lib/metadataTypes/TriggeredSend.js b/lib/metadataTypes/TriggeredSend.js index 932751285..200ca0ee1 100644 --- a/lib/metadataTypes/TriggeredSend.js +++ b/lib/metadataTypes/TriggeredSend.js @@ -109,12 +109,11 @@ class TriggeredSend extends MetadataType { ); delete metadata[this.definition.folderIdField]; } catch (ex) { - Util.logger.verbose( + Util.logger.error( ` - skipping ${this.definition.type} '${metadata[this.definition.nameField]}' (${ metadata[this.definition.keyField] }): Could not find folder (${ex.message})` ); - throw ex; } } /** @@ -136,7 +135,7 @@ class TriggeredSend extends MetadataType { // do not save this TSD because it would not be visible in the user interface return; } - // email + // // email try { // classic const classicEmail = cache.searchForField('email', metadata.Email.ID, 'ID', 'Name'); diff --git a/lib/util/cache.js b/lib/util/cache.js index d4fe67247..bcea3a35d 100644 --- a/lib/util/cache.js +++ b/lib/util/cache.js @@ -88,43 +88,37 @@ module.exports = { * @returns {string|number|boolean} value of specified field. Error is thrown if not found */ searchForField(metadataType, searchValue, searchField, returnField, overrideMID) { - try { - for (const key in dataStore[overrideMID || currentMID]?.[metadataType]) { - if ( - Util.resolveObjPath( - searchField, - dataStore[overrideMID || currentMID][metadataType][key] - ) == searchValue - ) { - try { - if ( - Util.resolveObjPath( - returnField, - dataStore[overrideMID || currentMID][metadataType][key] - ) - ) { - return Util.resolveObjPath( - returnField, - dataStore[overrideMID || currentMID][metadataType][key] - ); - } else { - throw new Error(); // eslint-disable-line unicorn/error-message - } - } catch { - throw new Error( - `${metadataType} with ${searchField} '${searchValue}' does not have field '${returnField}'` + for (const key in dataStore[overrideMID || currentMID]?.[metadataType]) { + if ( + Util.resolveObjPath( + searchField, + dataStore[overrideMID || currentMID][metadataType][key] + ) == searchValue + ) { + try { + if ( + Util.resolveObjPath( + returnField, + dataStore[overrideMID || currentMID][metadataType][key] + ) + ) { + return Util.resolveObjPath( + returnField, + dataStore[overrideMID || currentMID][metadataType][key] ); + } else { + throw new Error(); // eslint-disable-line unicorn/error-message } + } catch { + throw new Error( + `${metadataType} with ${searchField} '${searchValue}' does not have field '${returnField}'` + ); } } - throw new Error( - `Dependent ${metadataType} with ${searchField}='${searchValue}' was not found on your BU` - ); - } catch { - Util.logger.error( - ` ☇ skipping ${metadataType}: ID=${searchValue}- not found on server` - ); } + throw new Error( + `Dependent ${metadataType} with ${searchField}='${searchValue}' was not found on your BU` + ); }, /** * standardized method for getting data from cache - adapted for special case of lists From fabd3fcb53113445648098e8144d835069c7429d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Mon, 26 Jun 2023 16:01:57 +0200 Subject: [PATCH 022/208] #988: fix check for missing folders to actually cause TSDs to be skipped --- docs/dist/documentation.md | 71 ++++++++---------------------- lib/metadataTypes/TriggeredSend.js | 35 +++------------ 2 files changed, 26 insertions(+), 80 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 8027e7538..f92ac4824 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -371,7 +371,7 @@ Source and target business units are also compared before the deployment to appl * [new Deployer(properties, buObject)](#new_Deployer_new) * _instance_ * [.metadata](#Deployer+metadata) : TYPE.MultiMetadataTypeMap - * [._deploy([typeArr], [keyArr], [fromRetrieve], [isRefresh])](#Deployer+_deploy) ⇒ Promise.<TYPE.MultiMetadataTypeMap> + * [._deploy([typeArr], [keyArr], [fromRetrieve])](#Deployer+_deploy) ⇒ Promise.<TYPE.MultiMetadataTypeMap> * _static_ * [.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve])](#Deployer.deploy) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> * [._deployBU(cred, bu, properties, [typeArr], [keyArr], [fromRetrieve])](#Deployer._deployBU) ⇒ Promise.<TYPE.MultiMetadataTypeMap> @@ -395,7 +395,7 @@ Creates a Deployer, uses v2 auth if v2AuthOptions are passed. **Kind**: instance property of [Deployer](#Deployer) -### deployer.\_deploy([typeArr], [keyArr], [fromRetrieve], [isRefresh]) ⇒ Promise.<TYPE.MultiMetadataTypeMap> +### deployer.\_deploy([typeArr], [keyArr], [fromRetrieve]) ⇒ Promise.<TYPE.MultiMetadataTypeMap> Deploy all metadata that is located in the deployDir **Kind**: instance method of [Deployer](#Deployer) @@ -406,7 +406,6 @@ Deploy all metadata that is located in the deployDir | [typeArr] | Array.<TYPE.SupportedMetadataTypes> | limit deployment to given metadata type (can include subtype) | | [keyArr] | Array.<string> | limit deployment to given metadata keys | | [fromRetrieve] | boolean | if true, no folders will be updated/created | -| [isRefresh] | boolean | optional flag to indicate that triggeredSend should be refreshed after deployment of assets | @@ -798,7 +797,7 @@ FileTransfer MetadataType * [._retrieveExtendedFile(metadata, subType, retrieveDir)](#Asset._retrieveExtendedFile) ⇒ Promise.<void> * [._readExtendedFileFromFS(metadata, subType, deployDir, [pathOnly])](#Asset._readExtendedFileFromFS) ⇒ Promise.<string> * [.postRetrieveTasks(metadata)](#Asset.postRetrieveTasks) ⇒ TYPE.CodeExtractItem - * [.postDeployTasks(metadata, _, createdUpdated, [isRefresh])](#Asset.postDeployTasks) ⇒ Promise.<void> + * [.postDeployTasks(metadata, _, createdUpdated)](#Asset.postDeployTasks) ⇒ Promise.<void> * [.preDeployTasks(metadata, deployDir)](#Asset.preDeployTasks) ⇒ Promise.<TYPE.AssetItem> * [._getMainSubtype(extendedSubType)](#Asset._getMainSubtype) ⇒ string * [.buildDefinitionForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#Asset.buildDefinitionForNested) ⇒ Promise.<void> @@ -959,7 +958,7 @@ manages post retrieve steps -### Asset.postDeployTasks(metadata, _, createdUpdated, [isRefresh]) ⇒ Promise.<void> +### Asset.postDeployTasks(metadata, _, createdUpdated) ⇒ Promise.<void> Gets executed after deployment of metadata type **Kind**: static method of [Asset](#Asset) @@ -970,7 +969,6 @@ Gets executed after deployment of metadata type | metadata | TYPE.MetadataTypeMap | metadata mapped by their keyField | | _ | TYPE.MetadataTypeMap | originalMetadata to be updated (contains additioanl fields) | | createdUpdated | Object | counter representing successful creates/updates | -| [isRefresh] | boolean | optional flag to indicate that triggeredSend should be refreshed after deployment of assets | @@ -1238,7 +1236,7 @@ Automation MetadataType * [.retrieveForCache()](#Automation.retrieveForCache) ⇒ Promise.<TYPE.AutomationMapObj> * [.retrieveAsTemplate(templateDir, name, templateVariables)](#Automation.retrieveAsTemplate) ⇒ Promise.<TYPE.AutomationItemObj> * [.postRetrieveTasks(metadata)](#Automation.postRetrieveTasks) ⇒ TYPE.AutomationItem \| void - * [.deploy(metadata, targetBU, retrieveDir, [isRefresh])](#Automation.deploy) ⇒ Promise.<TYPE.AutomationMap> + * [.deploy(metadata, targetBU, retrieveDir)](#Automation.deploy) ⇒ Promise.<TYPE.AutomationMap> * [.create(metadata)](#Automation.create) ⇒ Promise * [.update(metadata, metadataBefore)](#Automation.update) ⇒ Promise * [.preDeployTasks(metadata)](#Automation.preDeployTasks) ⇒ Promise.<TYPE.AutomationItem> @@ -1310,7 +1308,7 @@ manages post retrieve steps -### Automation.deploy(metadata, targetBU, retrieveDir, [isRefresh]) ⇒ Promise.<TYPE.AutomationMap> +### Automation.deploy(metadata, targetBU, retrieveDir) ⇒ Promise.<TYPE.AutomationMap> Deploys automation - the saved file is the original one due to large differences required for deployment **Kind**: static method of [Automation](#Automation) @@ -1321,7 +1319,6 @@ Deploys automation - the saved file is the original one due to large differences | metadata | TYPE.AutomationMap | metadata mapped by their keyField | | targetBU | string | name/shorthand of target businessUnit for mapping | | retrieveDir | string | directory where metadata after deploy should be saved | -| [isRefresh] | boolean | optional flag - so far not used by automation | @@ -2335,7 +2332,7 @@ Event MetadataType * [.retrieveAsTemplate(templateDir, name, templateVariables)](#Event.retrieveAsTemplate) ⇒ Promise.<TYPE.MetadataTypeItemObj> * [.postRetrieveTasks(eventDef)](#Event.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem * [.deleteByKey(key)](#Event.deleteByKey) ⇒ Promise.<boolean> - * [.deploy(metadata, deployDir, retrieveDir, [isRefresh])](#Event.deploy) ⇒ Promise.<TYPE.MetadataTypeMap> + * [.deploy(metadata, deployDir, retrieveDir)](#Event.deploy) ⇒ Promise.<TYPE.MetadataTypeMap> * [.create(metadata)](#Event.create) ⇒ Promise * [.update(metadataEntry)](#Event.update) ⇒ Promise * [.preDeployTasks(metadata)](#Event.preDeployTasks) ⇒ TYPE.MetadataTypeItem @@ -2405,7 +2402,7 @@ Delete a metadata item from the specified business unit -### Event.deploy(metadata, deployDir, retrieveDir, [isRefresh]) ⇒ Promise.<TYPE.MetadataTypeMap> +### Event.deploy(metadata, deployDir, retrieveDir) ⇒ Promise.<TYPE.MetadataTypeMap> Deploys metadata - merely kept here to be able to print [logBeta](#Util.logBeta) once per deploy **Kind**: static method of [Event](#Event) @@ -2416,7 +2413,6 @@ Deploys metadata - merely kept here to be able to print [logBeta](#Util.logBeta) | metadata | TYPE.MetadataTypeMap | metadata mapped by their keyField | | deployDir | string | directory where deploy metadata are saved | | retrieveDir | string | directory where metadata after deploy should be saved | -| [isRefresh] | boolean | optional flag - so far not used by eventDefinition | @@ -2923,7 +2919,7 @@ definitionId: A unique UUID provided by Salesforce Marketing Cloud. Each version * [Journey](#Journey) ⇐ [MetadataType](#MetadataType) * [.retrieve(retrieveDir, [_], [__], [key])](#Journey.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.deleteByKey(key)](#Journey.deleteByKey) ⇒ Promise.<boolean> - * [.deploy(metadata, deployDir, retrieveDir, [isRefresh])](#Journey.deploy) ⇒ Promise.<TYPE.MetadataTypeMap> + * [.deploy(metadata, deployDir, retrieveDir)](#Journey.deploy) ⇒ Promise.<TYPE.MetadataTypeMap> * [.update(metadata)](#Journey.update) ⇒ Promise * [.create(metadata)](#Journey.create) ⇒ Promise * [.saveResults(results, retrieveDir, [overrideType], [templateVariables])](#Journey.saveResults) ⇒ Promise.<TYPE.MetadataTypeMap> @@ -2961,7 +2957,7 @@ Delete a metadata item from the specified business unit -### Journey.deploy(metadata, deployDir, retrieveDir, [isRefresh]) ⇒ Promise.<TYPE.MetadataTypeMap> +### Journey.deploy(metadata, deployDir, retrieveDir) ⇒ Promise.<TYPE.MetadataTypeMap> Deploys metadata - merely kept here to be able to print [logBeta](#Util.logBeta) once per deploy **Kind**: static method of [Journey](#Journey) @@ -2972,7 +2968,6 @@ Deploys metadata - merely kept here to be able to print [logBeta](#Util.logBeta) | metadata | TYPE.MetadataTypeMap | metadata mapped by their keyField | | deployDir | string | directory where deploy metadata are saved | | retrieveDir | string | directory where metadata after deploy should be saved | -| [isRefresh] | boolean | optional flag - so far not used by interaction | @@ -3155,8 +3150,8 @@ Provides default functionality that can be overwritten by child metadata type cl * [.buObject](#MetadataType.buObject) : TYPE.BuObject * [.getJsonFromFS(dir, [listBadKeys])](#MetadataType.getJsonFromFS) ⇒ TYPE.MetadataTypeMap * [.getFieldNamesToRetrieve([additionalFields], [isCaching])](#MetadataType.getFieldNamesToRetrieve) ⇒ Array.<string> - * [.deploy(metadata, deployDir, retrieveDir, [isRefresh])](#MetadataType.deploy) ⇒ Promise.<TYPE.MetadataTypeMap> - * [.postDeployTasks(upsertResults, originalMetadata, createdUpdated, [isRefresh])](#MetadataType.postDeployTasks) ⇒ void + * [.deploy(metadata, deployDir, retrieveDir)](#MetadataType.deploy) ⇒ Promise.<TYPE.MetadataTypeMap> + * [.postDeployTasks(upsertResults, originalMetadata, createdUpdated)](#MetadataType.postDeployTasks) ⇒ void * [.postCreateTasks(metadataEntry, apiResponse)](#MetadataType.postCreateTasks) ⇒ void * [.postUpdateTasks(metadataEntry, apiResponse)](#MetadataType.postUpdateTasks) ⇒ void * [.postDeployTasks_legacyApi(metadataEntry, apiResponse)](#MetadataType.postDeployTasks_legacyApi) ⇒ Promise.<void> @@ -3176,7 +3171,7 @@ Provides default functionality that can be overwritten by child metadata type cl * [.execute()](#MetadataType.execute) ⇒ void * [.hasChanged(cachedVersion, metadata, [fieldName])](#MetadataType.hasChanged) ⇒ boolean * [.hasChangedGeneric(cachedVersion, metadata, [fieldName], [silent])](#MetadataType.hasChangedGeneric) ⇒ boolean - * [.upsert(metadataMap, deployDir, [isRefresh])](#MetadataType.upsert) ⇒ Promise.<TYPE.MetadataTypeMap> + * [.upsert(metadataMap, deployDir)](#MetadataType.upsert) ⇒ Promise.<TYPE.MetadataTypeMap> * [.createOrUpdate(metadataMap, metadataKey, hasError, metadataToUpdate, metadataToCreate)](#MetadataType.createOrUpdate) ⇒ 'create' \| 'update' \| 'skip' * [.createREST(metadataEntry, uri)](#MetadataType.createREST) ⇒ Promise.<object> \| null * [.createSOAP(metadataEntry, [handleOutside])](#MetadataType.createSOAP) ⇒ Promise.<object> \| null @@ -3257,7 +3252,7 @@ Returns fieldnames of Metadata Type. 'this.definition.fields' variable only set -### MetadataType.deploy(metadata, deployDir, retrieveDir, [isRefresh]) ⇒ Promise.<TYPE.MetadataTypeMap> +### MetadataType.deploy(metadata, deployDir, retrieveDir) ⇒ Promise.<TYPE.MetadataTypeMap> Deploys metadata **Kind**: static method of [MetadataType](#MetadataType) @@ -3268,11 +3263,10 @@ Deploys metadata | metadata | TYPE.MetadataTypeMap | metadata mapped by their keyField | | deployDir | string | directory where deploy metadata are saved | | retrieveDir | string | directory where metadata after deploy should be saved | -| [isRefresh] | boolean | optional flag to indicate that triggeredSend should be refreshed after deployment of assets | -### MetadataType.postDeployTasks(upsertResults, originalMetadata, createdUpdated, [isRefresh]) ⇒ void +### MetadataType.postDeployTasks(upsertResults, originalMetadata, createdUpdated) ⇒ void Gets executed after deployment of metadata type **Kind**: static method of [MetadataType](#MetadataType) @@ -3282,7 +3276,6 @@ Gets executed after deployment of metadata type | upsertResults | TYPE.MetadataTypeMap | metadata mapped by their keyField as returned by update/create | | originalMetadata | TYPE.MetadataTypeMap | metadata to be updated (contains additioanl fields) | | createdUpdated | Object | counter representing successful creates/updates | -| [isRefresh] | boolean | optional flag to indicate that triggeredSend should be refreshed after deployment of assets | @@ -3524,7 +3517,7 @@ test if metadata was actually changed or not to potentially skip it during deplo -### MetadataType.upsert(metadataMap, deployDir, [isRefresh]) ⇒ Promise.<TYPE.MetadataTypeMap> +### MetadataType.upsert(metadataMap, deployDir) ⇒ Promise.<TYPE.MetadataTypeMap> MetadataType upsert, after retrieving from target and comparing to check if create or update operation is needed. **Kind**: static method of [MetadataType](#MetadataType) @@ -3534,7 +3527,6 @@ MetadataType upsert, after retrieving from target and comparing to check if crea | --- | --- | --- | | metadataMap | TYPE.MetadataTypeMap | metadata mapped by their keyField | | deployDir | string | directory where deploy metadata are saved | -| [isRefresh] | boolean | optional flag to indicate that triggeredSend should be refreshed after deployment of assets | @@ -5500,9 +5492,7 @@ MessageSendActivity MetadataType * [.create(metadata)](#TriggeredSend.create) ⇒ Promise * [.update(metadata)](#TriggeredSend.update) ⇒ Promise * [.deleteByKey(customerKey)](#TriggeredSend.deleteByKey) ⇒ Promise.<boolean> - * [.postRetrieveTasks(metadata)](#TriggeredSend.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem - * [.setFolderPath(metadata)](#TriggeredSend.setFolderPath) - * [.parseMetadata(metadata)](#TriggeredSend.parseMetadata) ⇒ TYPE.MetadataTypeItem \| void + * [.postRetrieveTasks(metadata)](#TriggeredSend.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem \| void * [.preDeployTasks(metadata)](#TriggeredSend.preDeployTasks) ⇒ TYPE.MetadataTypeItem * [.refresh([keyArr], [checkKey])](#TriggeredSend.refresh) ⇒ Promise.<void> * [.getKeysForValidTSDs(metadata)](#TriggeredSend.getKeysForValidTSDs) ⇒ Promise.<Array.<string>> @@ -5562,30 +5552,7 @@ Delete a metadata item from the specified business unit -### TriggeredSend.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem -manages post retrieve steps - -**Kind**: static method of [TriggeredSend](#TriggeredSend) -**Returns**: TYPE.MetadataTypeItem - Array with one metadata object and one query string - -| Param | Type | Description | -| --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single query | - - - -### TriggeredSend.setFolderPath(metadata) -generic script that retrieves the folder path from cache and updates the given metadata with it after retrieve - -**Kind**: static method of [TriggeredSend](#TriggeredSend) - -| Param | Type | Description | -| --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single script activity definition | - - - -### TriggeredSend.parseMetadata(metadata) ⇒ TYPE.MetadataTypeItem \| void +### TriggeredSend.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem \| void parses retrieved Metadata before saving **Kind**: static method of [TriggeredSend](#TriggeredSend) @@ -5593,7 +5560,7 @@ parses retrieved Metadata before saving | Param | Type | Description | | --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single query activity definition | +| metadata | TYPE.MetadataTypeItem | a single item | diff --git a/lib/metadataTypes/TriggeredSend.js b/lib/metadataTypes/TriggeredSend.js index 200ca0ee1..0e7d8e77d 100644 --- a/lib/metadataTypes/TriggeredSend.js +++ b/lib/metadataTypes/TriggeredSend.js @@ -94,48 +94,27 @@ class TriggeredSend extends MetadataType { 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 - * - * @param {TYPE.MetadataTypeItem} metadata a single script activity definition - */ - static setFolderPath(metadata) { - try { - metadata.r__folder_Path = cache.searchForField( - 'folder', - metadata[this.definition.folderIdField], - 'ID', - 'Path' - ); - delete metadata[this.definition.folderIdField]; - } catch (ex) { - Util.logger.error( - ` - skipping ${this.definition.type} '${metadata[this.definition.nameField]}' (${ - metadata[this.definition.keyField] - }): Could not find folder (${ex.message})` - ); - } - } /** * parses retrieved Metadata before saving * - * @param {TYPE.MetadataTypeItem} metadata a single query activity definition + * @param {TYPE.MetadataTypeItem} metadata a single item * @returns {TYPE.MetadataTypeItem | void} Array with one metadata object and one sql string */ static parseMetadata(metadata) { // remove IsPlatformObject, always has to be 'false' delete metadata.IsPlatformObject; + // folder - try { - this.setFolderPath(metadata); - } catch { + this.setFolderPath(metadata); + if (!metadata.r__folder_Path) { Util.logger.verbose( ` ☇ skipping ${this.definition.typeName} '${metadata.Name}'/'${metadata.CustomerKey}': Could not find folder.` ); // do not save this TSD because it would not be visible in the user interface return; } - // // email + + // email try { // classic const classicEmail = cache.searchForField('email', metadata.Email.ID, 'ID', 'Name'); @@ -244,7 +223,7 @@ class TriggeredSend extends MetadataType { * TSD-specific refresh method that finds active TSDs and refreshes them * * @param {string[]} [keyArr] metadata keys - * @param {boolean} [checkKey=true] whether to check if the key is valid + * @param {boolean} [checkKey] whether to check if the key is valid * @returns {Promise.} - */ static async refresh(keyArr, checkKey = true) { From 9196bfa5b829583e29b96acadcd0ac3ba1bb9ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Mon, 26 Jun 2023 16:06:20 +0200 Subject: [PATCH 023/208] #988: refactoring: merged postRetrieveTasks and parseMetadata --- lib/metadataTypes/TriggeredSend.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/lib/metadataTypes/TriggeredSend.js b/lib/metadataTypes/TriggeredSend.js index 0e7d8e77d..fd90191b7 100644 --- a/lib/metadataTypes/TriggeredSend.js +++ b/lib/metadataTypes/TriggeredSend.js @@ -85,22 +85,13 @@ class TriggeredSend extends MetadataType { return super.deleteByKeySOAP(customerKey); } - /** - * manages post retrieve steps - * - * @param {TYPE.MetadataTypeItem} metadata a single query - * @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 item * @returns {TYPE.MetadataTypeItem | void} Array with one metadata object and one sql string */ - static parseMetadata(metadata) { + static postRetrieveTasks(metadata) { // remove IsPlatformObject, always has to be 'false' delete metadata.IsPlatformObject; From 7ab2d81b34db22af004e208c7c5b87f8eab6f388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Mon, 26 Jun 2023 16:07:53 +0200 Subject: [PATCH 024/208] #988: ensure we re-cash types, ensuring no subtype was forgotten --- lib/metadataTypes/TriggeredSend.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/metadataTypes/TriggeredSend.js b/lib/metadataTypes/TriggeredSend.js index fd90191b7..1332a31cb 100644 --- a/lib/metadataTypes/TriggeredSend.js +++ b/lib/metadataTypes/TriggeredSend.js @@ -273,14 +273,17 @@ class TriggeredSend extends MetadataType { list: null, }; for (const [type, subTypeArr] of Object.entries(requiredCache)) { - if (!cache.getCache()?.[type]) { - Util.logger.info(` - Caching dependent Metadata: ${type}`); - Util.logSubtypes(subTypeArr); - cacheTypes[type].client = this.client; - cacheTypes[type].buObject = this.buObject; - cacheTypes[type].properties = this.properties; + Util.logger.info(` - Caching dependent Metadata: ${type}`); + Util.logSubtypes(subTypeArr); + cacheTypes[type].client = this.client; + cacheTypes[type].buObject = this.buObject; + cacheTypes[type].properties = this.properties; - const result = await cacheTypes[type].retrieveForCache(null, subTypeArr); + const result = await cacheTypes[type].retrieveForCache(null, subTypeArr); + if (cache.getCache()?.[type]) { + // re-run caching to merge with existing cache, assuming we might have missed subtypes + cache.mergeMetadata(type, result.metadata); + } else { cache.setMetadata(type, result.metadata); } } From 8dba9504562b959cd683c38757c70889ff976a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Mon, 26 Jun 2023 16:23:03 +0200 Subject: [PATCH 025/208] #988: skip caching assets if run via --refresh flag --- docs/dist/documentation.md | 9 +++++++-- lib/metadataTypes/Asset.js | 4 ++-- lib/metadataTypes/TriggeredSend.js | 6 +++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index f92ac4824..3e78b1ad0 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -5496,7 +5496,7 @@ MessageSendActivity MetadataType * [.preDeployTasks(metadata)](#TriggeredSend.preDeployTasks) ⇒ TYPE.MetadataTypeItem * [.refresh([keyArr], [checkKey])](#TriggeredSend.refresh) ⇒ Promise.<void> * [.getKeysForValidTSDs(metadata)](#TriggeredSend.getKeysForValidTSDs) ⇒ Promise.<Array.<string>> - * [.findRefreshableItems()](#TriggeredSend.findRefreshableItems) ⇒ Promise.<TYPE.MetadataTypeMapObj> + * [.findRefreshableItems([assetLoaded])](#TriggeredSend.findRefreshableItems) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [._refreshItem(key, checkKey)](#TriggeredSend._refreshItem) ⇒ Promise.<boolean> @@ -5601,11 +5601,16 @@ helper for [refresh](refresh) that extracts the keys from the TSD item map and e -### TriggeredSend.findRefreshableItems() ⇒ Promise.<TYPE.MetadataTypeMapObj> +### TriggeredSend.findRefreshableItems([assetLoaded]) ⇒ Promise.<TYPE.MetadataTypeMapObj> helper for [refresh](refresh) that finds active TSDs on the server and filters it by the same rules that [retrieve](retrieve) is using to avoid refreshing TSDs with broken dependencies **Kind**: static method of [TriggeredSend](#TriggeredSend) **Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of TSD item map + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| [assetLoaded] | boolean | false | if run after Asset.deploy via --refresh option this will skip caching assets | + ### TriggeredSend.\_refreshItem(key, checkKey) ⇒ Promise.<boolean> diff --git a/lib/metadataTypes/Asset.js b/lib/metadataTypes/Asset.js index 7c89071c1..2fd5c2c91 100644 --- a/lib/metadataTypes/Asset.js +++ b/lib/metadataTypes/Asset.js @@ -455,7 +455,7 @@ class Asset extends MetadataType { * @param {TYPE.AssetItem} metadata a single asset * @param {TYPE.AssetSubType} subType group of similar assets to put in a folder (ie. images) * @param {string} deployDir directory of deploy files - * @param {boolean} [pathOnly=false] used by getFilesToCommit which does not need the binary file to be actually read + * @param {boolean} [pathOnly] used by getFilesToCommit which does not need the binary file to be actually read * @returns {Promise.} if found will return the path of the binary file */ static async _readExtendedFileFromFS(metadata, subType, deployDir, pathOnly = false) { @@ -545,7 +545,7 @@ class Asset extends MetadataType { TriggeredSend.client = this.client; try { // find refreshable TSDs - const tsdObj = (await TriggeredSend.findRefreshableItems()).metadata; + const tsdObj = (await TriggeredSend.findRefreshableItems(true)).metadata; const tsdCountInitial = Object.keys(tsdObj).length; const emailCount = legacyIdArr.length; diff --git a/lib/metadataTypes/TriggeredSend.js b/lib/metadataTypes/TriggeredSend.js index 1332a31cb..71d8bd35a 100644 --- a/lib/metadataTypes/TriggeredSend.js +++ b/lib/metadataTypes/TriggeredSend.js @@ -252,9 +252,10 @@ class TriggeredSend extends MetadataType { /** * helper for {@link refresh} that finds active TSDs on the server and filters it by the same rules that {@link retrieve} is using to avoid refreshing TSDs with broken dependencies * + * @param {boolean} [assetLoaded] if run after Asset.deploy via --refresh option this will skip caching assets * @returns {Promise.} Promise of TSD item map */ - static async findRefreshableItems() { + static async findRefreshableItems(assetLoaded = false) { Util.logger.info('Finding refreshable items...'); // cache dependencies to test for broken links // skip deprecated classic emails here, assuming they cannot be updated and hence are not relevant for {@link refresh} @@ -273,6 +274,9 @@ class TriggeredSend extends MetadataType { list: null, }; for (const [type, subTypeArr] of Object.entries(requiredCache)) { + if (type === 'asset' && assetLoaded) { + continue; + } Util.logger.info(` - Caching dependent Metadata: ${type}`); Util.logSubtypes(subTypeArr); cacheTypes[type].client = this.client; From ab3685866ed7d977ba600b69ec8889e6840ce364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Mon, 26 Jun 2023 16:46:36 +0200 Subject: [PATCH 026/208] #991: group command-options in --help to make it easier to read --- lib/cli.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 931c78b19..4020dde2e 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -57,6 +57,10 @@ yargs type: 'string', describe: 'metadata key that shall be exclusively uploaded', }) + .group( + ['changeKeyField', 'changeKeyValue', 'fromRetrieve', 'refresh'], + 'Options for deploy:' + ) .option('changeKeyField', { type: 'string', describe: @@ -305,7 +309,7 @@ yargs aliases: ['et'], desc: 'explains metadata types that can be retrieved', builder: (yargs) => { - yargs.option('json', { + yargs.group(['json'], 'Options for explainTypes:').option('json', { type: 'boolean', describe: 'optionaly return info in json format', }); @@ -316,7 +320,7 @@ yargs }, }) .command({ - command: 'createDeltaPkg [range] [--filter ] [--commitHistory ]', + command: 'createDeltaPkg [range]', aliases: ['cdp'], desc: 'Copies commit-based file delta into deploy folder', builder: (yargs) => { @@ -325,6 +329,7 @@ yargs type: 'string', describe: 'Pull Request target branch or git commit range', }) + .group(['filter', 'commitHistory'], 'Options for createDeltaPkg:') .option('filter', { type: 'string', describe: From ef2341b1bd441c936a20666ba51b6de53ddb1f1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 20:57:47 +0000 Subject: [PATCH 027/208] Bump fast-xml-parser from 4.2.4 to 4.2.5 Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 4.2.4 to 4.2.5. - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v4.2.4...v4.2.5) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9ca5851b..b082430ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,7 +45,7 @@ "eslint-plugin-mocha": "10.1.0", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-unicorn": "47.0.0", - "fast-xml-parser": "4.2.4", + "fast-xml-parser": "4.2.5", "husky": "8.0.3", "jsdoc-to-markdown": "8.0.0", "lint-staged": "13.2.2", @@ -3637,9 +3637,9 @@ "dev": true }, "node_modules/fast-xml-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.4.tgz", - "integrity": "sha512-fbfMDvgBNIdDJLdLOwacjFAPYt67tr31H9ZhWSm45CDAxvd0I6WTlSOUo7K2P/K5sA5JgMKG64PI3DMcaFdWpQ==", + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", + "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", "dev": true, "funding": [ { @@ -12684,9 +12684,9 @@ "dev": true }, "fast-xml-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.4.tgz", - "integrity": "sha512-fbfMDvgBNIdDJLdLOwacjFAPYt67tr31H9ZhWSm45CDAxvd0I6WTlSOUo7K2P/K5sA5JgMKG64PI3DMcaFdWpQ==", + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", + "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", "dev": true, "requires": { "strnum": "^1.0.5" diff --git a/package.json b/package.json index e9975d472..13e0dff27 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "eslint-plugin-mocha": "10.1.0", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-unicorn": "47.0.0", - "fast-xml-parser": "4.2.4", + "fast-xml-parser": "4.2.5", "husky": "8.0.3", "jsdoc-to-markdown": "8.0.0", "lint-staged": "13.2.2", From 2d95f223a74c5d0979608d6750e5292e2131f4b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 12:27:20 +0000 Subject: [PATCH 028/208] Bump eslint from 8.42.0 to 8.43.0 Bumps [eslint](https://github.com/eslint/eslint) from 8.42.0 to 8.43.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.42.0...v8.43.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 30 +++++++++++++++--------------- package.json | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index b082430ee..a1da6d001 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "axios-mock-adapter": "1.21.3", "chai": "4.3.7", "chai-files": "1.4.0", - "eslint": "8.42.0", + "eslint": "8.43.0", "eslint-config-prettier": "8.7.0", "eslint-config-ssjs": "1.1.11", "eslint-plugin-jsdoc": "46.2.5", @@ -590,9 +590,9 @@ "dev": true }, "node_modules/@eslint/js": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", - "integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", + "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3138,15 +3138,15 @@ } }, "node_modules/eslint": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", - "integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", + "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.42.0", + "@eslint/js": "8.43.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -10396,9 +10396,9 @@ } }, "@eslint/js": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz", - "integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", + "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", "dev": true }, "@humanwhocodes/config-array": { @@ -12335,15 +12335,15 @@ "dev": true }, "eslint": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz", - "integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", + "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.42.0", + "@eslint/js": "8.43.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", diff --git a/package.json b/package.json index 13e0dff27..0222ea466 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "axios-mock-adapter": "1.21.3", "chai": "4.3.7", "chai-files": "1.4.0", - "eslint": "8.42.0", + "eslint": "8.43.0", "eslint-config-prettier": "8.7.0", "eslint-config-ssjs": "1.1.11", "eslint-plugin-jsdoc": "46.2.5", From cbd05a7d8c42e66de0a8f12cda586b3e3af155cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 12:29:55 +0000 Subject: [PATCH 029/208] Bump eslint-plugin-jsdoc from 46.2.5 to 46.3.0 Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 46.2.5 to 46.3.0. - [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases) - [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc) - [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v46.2.5...v46.3.0) --- updated-dependencies: - dependency-name: eslint-plugin-jsdoc dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index a1da6d001..962608652 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "eslint": "8.43.0", "eslint-config-prettier": "8.7.0", "eslint-config-ssjs": "1.1.11", - "eslint-plugin-jsdoc": "46.2.5", + "eslint-plugin-jsdoc": "46.3.0", "eslint-plugin-mocha": "10.1.0", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-unicorn": "47.0.0", @@ -3221,9 +3221,9 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "46.2.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.2.5.tgz", - "integrity": "sha512-Rmd0pb6S5fv9/lGbJMiVUZn56XvjKTGQoq9H5yfNjj6jcJHkTaq+Pqj2KHK/8EO01f8auFFy2kNL64cFisMEDw==", + "version": "46.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.3.0.tgz", + "integrity": "sha512-nfSvsR8YJRZyKrWwcXPSQyQC8jllfdEjcRhTXFr7RxfB5Wyl7AxrfjCUz72WwalkXMF4u+R6F/oDoW46ah69HQ==", "dev": true, "dependencies": { "@es-joy/jsdoccomment": "~0.39.4", @@ -12416,9 +12416,9 @@ "requires": {} }, "eslint-plugin-jsdoc": { - "version": "46.2.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.2.5.tgz", - "integrity": "sha512-Rmd0pb6S5fv9/lGbJMiVUZn56XvjKTGQoq9H5yfNjj6jcJHkTaq+Pqj2KHK/8EO01f8auFFy2kNL64cFisMEDw==", + "version": "46.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.3.0.tgz", + "integrity": "sha512-nfSvsR8YJRZyKrWwcXPSQyQC8jllfdEjcRhTXFr7RxfB5Wyl7AxrfjCUz72WwalkXMF4u+R6F/oDoW46ah69HQ==", "dev": true, "requires": { "@es-joy/jsdoccomment": "~0.39.4", diff --git a/package.json b/package.json index 0222ea466..f6ef92b95 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "eslint": "8.43.0", "eslint-config-prettier": "8.7.0", "eslint-config-ssjs": "1.1.11", - "eslint-plugin-jsdoc": "46.2.5", + "eslint-plugin-jsdoc": "46.3.0", "eslint-plugin-mocha": "10.1.0", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-unicorn": "47.0.0", From 0e44d419bda61fecde7d29f8ccead7b1c41d61d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 12:33:13 +0000 Subject: [PATCH 030/208] Bump semver from 7.5.0 to 7.5.3 Bumps [semver](https://github.com/npm/node-semver) from 7.5.0 to 7.5.3. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v7.5.0...v7.5.3) --- updated-dependencies: - dependency-name: semver dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 40 +++++++--------------------------------- package.json | 2 +- 2 files changed, 8 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index 962608652..ba50a7530 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "p-limit": "3.1.0", "prettier": "2.8.8", "prettier-plugin-sql": "0.14.0", - "semver": "7.5.0", + "semver": "7.5.3", "sfmc-sdk": "1.0.1", "simple-git": "3.18.0", "toposort": "2.0.2", @@ -3243,21 +3243,6 @@ "eslint": "^7.0.0 || ^8.0.0" } }, - "node_modules/eslint-plugin-jsdoc/node_modules/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-plugin-mocha": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.1.0.tgz", @@ -8666,9 +8651,9 @@ } }, "node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -12430,17 +12415,6 @@ "is-builtin-module": "^3.2.1", "semver": "^7.5.1", "spdx-expression-parse": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "eslint-plugin-mocha": { @@ -16386,9 +16360,9 @@ } }, "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "requires": { "lru-cache": "^6.0.0" } diff --git a/package.json b/package.json index f6ef92b95..95a5aea2c 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "p-limit": "3.1.0", "prettier": "2.8.8", "prettier-plugin-sql": "0.14.0", - "semver": "7.5.0", + "semver": "7.5.3", "sfmc-sdk": "1.0.1", "simple-git": "3.18.0", "toposort": "2.0.2", From 35627de65cd49819a8011ddadc942781b620b78a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Jun 2023 12:52:06 +0000 Subject: [PATCH 031/208] Bump axios-mock-adapter from 1.21.3 to 1.21.5 Bumps [axios-mock-adapter](https://github.com/ctimmerm/axios-mock-adapter) from 1.21.3 to 1.21.5. - [Release notes](https://github.com/ctimmerm/axios-mock-adapter/releases) - [Changelog](https://github.com/ctimmerm/axios-mock-adapter/blob/master/CHANGELOG.md) - [Commits](https://github.com/ctimmerm/axios-mock-adapter/compare/v1.21.3...v1.21.5) --- updated-dependencies: - dependency-name: axios-mock-adapter dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index ba50a7530..e7eb5b3d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,7 @@ }, "devDependencies": { "assert": "2.0.0", - "axios-mock-adapter": "1.21.3", + "axios-mock-adapter": "1.21.5", "chai": "4.3.7", "chai-files": "1.4.0", "eslint": "8.43.0", @@ -1449,9 +1449,9 @@ } }, "node_modules/axios-mock-adapter": { - "version": "1.21.3", - "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.21.3.tgz", - "integrity": "sha512-cdrQs/BqiJq4qn5EvaUUKDCaSor2j0KKW5tMtq5lqfTauxLRownBlzUNoLe+WKRoDrrXXXbtXTbmKpWFdL/NJw==", + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.21.5.tgz", + "integrity": "sha512-5NI1V/VK+8+JeTF8niqOowuysA4b8mGzdlMN/QnTnoXbYh4HZSNiopsDclN2g/m85+G++IrEtUdZaQ3GnaMsSA==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", @@ -11035,9 +11035,9 @@ } }, "axios-mock-adapter": { - "version": "1.21.3", - "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.21.3.tgz", - "integrity": "sha512-cdrQs/BqiJq4qn5EvaUUKDCaSor2j0KKW5tMtq5lqfTauxLRownBlzUNoLe+WKRoDrrXXXbtXTbmKpWFdL/NJw==", + "version": "1.21.5", + "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.21.5.tgz", + "integrity": "sha512-5NI1V/VK+8+JeTF8niqOowuysA4b8mGzdlMN/QnTnoXbYh4HZSNiopsDclN2g/m85+G++IrEtUdZaQ3GnaMsSA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.3", diff --git a/package.json b/package.json index 95a5aea2c..eeb992ebd 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ }, "devDependencies": { "assert": "2.0.0", - "axios-mock-adapter": "1.21.3", + "axios-mock-adapter": "1.21.5", "chai": "4.3.7", "chai-files": "1.4.0", "eslint": "8.43.0", From 07c813fbad8745aaa412486fe41d94d89a9e8177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 27 Jun 2023 16:54:20 +0200 Subject: [PATCH 032/208] #985: ensure trailing commas in key/type lists do not lead to unforeseen executions --- lib/cli.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 4020dde2e..4bd979400 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -471,9 +471,13 @@ function csvToArray(csv) { return !csv ? null : csv.includes(',') - ? csv.split(',').map((item) => - // allow whitespace in comma-separated lists - item.trim() - ) - : [csv.trim()]; + ? csv + .split(',') + .map((item) => + // allow whitespace in comma-separated lists + item.trim() + ) + // make sure trailing commas are ignored + .filter(Boolean) + : [csv.trim()].filter(Boolean); } From b9952bc45835dbcac73e5211dd0a358f80db2781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 27 Jun 2023 17:14:08 +0200 Subject: [PATCH 033/208] #1003: run lint:fix if npm install was required --- .husky/post-checkout | 1 + .husky/post-merge | 1 + 2 files changed, 2 insertions(+) diff --git a/.husky/post-checkout b/.husky/post-checkout index 2607e40f5..5bf2cfe67 100644 --- a/.husky/post-checkout +++ b/.husky/post-checkout @@ -32,6 +32,7 @@ if [[ ${PACKAGES[@]} ]]; then done echo "📦 Running npm install to update your dependencies..." npm install + npm run lint:fix else echo "📦 All packages up-to-date. No need to run npm install." fi diff --git a/.husky/post-merge b/.husky/post-merge index 06f668cd4..a5b4e597b 100644 --- a/.husky/post-merge +++ b/.husky/post-merge @@ -16,6 +16,7 @@ if [[ ${PACKAGES[@]} ]]; then done echo "📦 Running npm install to update your dependencies..." npm install + npm run lint:fix else echo "📦 All packages up-to-date. No need to run npm install." fi \ No newline at end of file From eb234090906a87138146a8b921fad987f34d9641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 27 Jun 2023 22:43:06 +0200 Subject: [PATCH 034/208] #0: eslint --fix --- docs/dist/documentation.md | 100 +++++++++++++++--------------- lib/Deployer.js | 2 +- lib/metadataTypes/Folder.js | 2 +- lib/metadataTypes/MetadataType.js | 10 +-- lib/metadataTypes/User.js | 2 +- lib/util/file.js | 4 +- lib/util/util.js | 6 +- 7 files changed, 63 insertions(+), 63 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 3e78b1ad0..c937ec619 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -447,11 +447,11 @@ Returns metadata of a business unit that is saved locally **Kind**: static method of [Deployer](#Deployer) **Returns**: TYPE.MultiMetadataTypeMap - Metadata of BU in local directory -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| deployDir | string | | root directory of metadata. | -| [typeArr] | Array.<string> | | limit deployment to given metadata type | -| [listBadKeys] | boolean | false | do not print errors, used for badKeys() | +| Param | Type | Description | +| --- | --- | --- | +| deployDir | string | root directory of metadata. | +| [typeArr] | Array.<string> | limit deployment to given metadata type | +| [listBadKeys] | boolean | do not print errors, used for badKeys() | @@ -2743,10 +2743,10 @@ Returns file contents mapped to their filename without '.json' ending **Kind**: static method of [Folder](#Folder) **Returns**: TYPE.MetadataTypeMap - fileName => fileContent map -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| dir | string | | directory that contains '.json' files to be read | -| [listBadKeys] | boolean | false | do not print errors, used for badKeys() | +| Param | Type | Description | +| --- | --- | --- | +| dir | string | directory that contains '.json' files to be read | +| [listBadKeys] | boolean | do not print errors, used for badKeys() | @@ -3232,10 +3232,10 @@ Returns file contents mapped to their filename without '.json' ending **Kind**: static method of [MetadataType](#MetadataType) **Returns**: TYPE.MetadataTypeMap - fileName => fileContent map -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| dir | string | | directory that contains '.json' files to be read | -| [listBadKeys] | boolean | false | do not print errors, used for badKeys() | +| Param | Type | Description | +| --- | --- | --- | +| dir | string | directory that contains '.json' files to be read | +| [listBadKeys] | boolean | do not print errors, used for badKeys() | @@ -3582,7 +3582,7 @@ Updates a single metadata entry via REST | --- | --- | --- | --- | | metadataEntry | TYPE.MetadataTypeItem | | a single metadata Entry | | uri | string | | rest endpoint for PATCH | -| [httpMethod] | 'patch' \| 'post' \| 'put' | 'patch' | defaults to 'patch'; some update requests require PUT instead of PATCH | +| [httpMethod] | 'patch' \| 'post' \| 'put' | patch | defaults to 'patch'; some update requests require PUT instead of PATCH | @@ -3761,10 +3761,10 @@ checks if the current metadata entry should be saved on retrieve or not **Kind**: static method of [MetadataType](#MetadataType) **Returns**: boolean - true: skip saving == filtered; false: continue with saving -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| metadataEntry | TYPE.MetadataTypeItem | | metadata entry | -| [include] | boolean | false | true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude | +| Param | Type | Description | +| --- | --- | --- | +| metadataEntry | TYPE.MetadataTypeItem | metadata entry | +| [include] | boolean | true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude | @@ -3774,10 +3774,10 @@ optionally filter by what folder something is in **Kind**: static method of [MetadataType](#MetadataType) **Returns**: boolean - true: filtered == do NOT save; false: not filtered == do save -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| metadataEntry | object | | metadata entry | -| [include] | boolean | false | true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude | +| Param | Type | Description | +| --- | --- | --- | +| metadataEntry | object | metadata entry | +| [include] | boolean | true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude | @@ -3987,11 +3987,11 @@ Returns metadata of a business unit that is saved locally **Kind**: static method of [MetadataType](#MetadataType) **Returns**: object - Metadata of BU in local directory -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| readDir | string | | root directory of metadata. | -| [listBadKeys] | boolean | false | do not print errors, used for badKeys() | -| [buMetadata] | object | | Metadata of BU in local directory | +| Param | Type | Description | +| --- | --- | --- | +| readDir | string | root directory of metadata. | +| [listBadKeys] | boolean | do not print errors, used for badKeys() | +| [buMetadata] | object | Metadata of BU in local directory | @@ -6025,9 +6025,9 @@ wrapper around our standard winston logging to console and logfile **Kind**: static method of [Util](#Util) **Returns**: object - initiated logger for console and file -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| [noLogFile] | boolean | false | optional flag to indicate if we should log to file; CLI logs are always on | +| Param | Type | Description | +| --- | --- | --- | +| [noLogFile] | boolean | optional flag to indicate if we should log to file; CLI logs are always on | @@ -6036,10 +6036,10 @@ initiate winston logger **Kind**: static method of [Util](#Util) -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| [restart] | boolean | false | if true, logger will be restarted; otherwise, an existing logger will be used | -| [noLogFile] | boolean | false | if false, logger will log to file; otherwise, only to console | +| Param | Type | Description | +| --- | --- | --- | +| [restart] | boolean | if true, logger will be restarted; otherwise, an existing logger will be used | +| [noLogFile] | boolean | if false, logger will log to file; otherwise, only to console | @@ -6773,12 +6773,12 @@ reads file from local file system. **Kind**: static method of [File](#File) **Returns**: Promise.<string> \| void - file contents; void on error -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| directory | string \| Array.<string> | | directory where the file is stored | -| filename | string | | name of the file without '.json' ending | -| filetype | string | | filetype suffix | -| [encoding] | string | "'utf8'" | read file with encoding (defaults to utf-8) | +| Param | Type | Description | +| --- | --- | --- | +| directory | string \| Array.<string> | directory where the file is stored | +| filename | string | name of the file without '.json' ending | +| filetype | string | filetype suffix | +| [encoding] | string | read file with encoding (defaults to utf-8) | @@ -6841,9 +6841,9 @@ Initalises Prettier formatting lib async. **Kind**: static method of [File](#File) **Returns**: Promise.<boolean> - success of config load -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| [filetype] | string | "'html'" | filetype ie. JSON or SSJS | +| Param | Type | Description | +| --- | --- | --- | +| [filetype] | string | filetype ie. JSON or SSJS | @@ -7915,9 +7915,9 @@ wrapper around our standard winston logging to console and logfile **Kind**: static method of [Util](#Util) **Returns**: object - initiated logger for console and file -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| [noLogFile] | boolean | false | optional flag to indicate if we should log to file; CLI logs are always on | +| Param | Type | Description | +| --- | --- | --- | +| [noLogFile] | boolean | optional flag to indicate if we should log to file; CLI logs are always on | @@ -7926,10 +7926,10 @@ initiate winston logger **Kind**: static method of [Util](#Util) -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| [restart] | boolean | false | if true, logger will be restarted; otherwise, an existing logger will be used | -| [noLogFile] | boolean | false | if false, logger will log to file; otherwise, only to console | +| Param | Type | Description | +| --- | --- | --- | +| [restart] | boolean | if true, logger will be restarted; otherwise, an existing logger will be used | +| [noLogFile] | boolean | if false, logger will log to file; otherwise, only to console | diff --git a/lib/Deployer.js b/lib/Deployer.js index 49485d2f8..28fd496e8 100644 --- a/lib/Deployer.js +++ b/lib/Deployer.js @@ -310,7 +310,7 @@ class Deployer { * * @param {string} deployDir root directory of metadata. * @param {string[]} [typeArr] limit deployment to given metadata type - * @param {boolean} [listBadKeys=false] do not print errors, used for badKeys() + * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @returns {TYPE.MultiMetadataTypeMap} Metadata of BU in local directory */ static readBUMetadata(deployDir, typeArr, listBadKeys) { diff --git a/lib/metadataTypes/Folder.js b/lib/metadataTypes/Folder.js index e1f691873..829800112 100644 --- a/lib/metadataTypes/Folder.js +++ b/lib/metadataTypes/Folder.js @@ -452,7 +452,7 @@ class Folder extends MetadataType { * Returns file contents mapped to their filename without '.json' ending * * @param {string} dir directory that contains '.json' files to be read - * @param {boolean} [listBadKeys=false] do not print errors, used for badKeys() + * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @returns {TYPE.MetadataTypeMap} fileName => fileContent map */ static getJsonFromFS(dir, listBadKeys) { diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index dd8f99c1e..584b7fa69 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -35,7 +35,7 @@ class MetadataType { * Returns file contents mapped to their filename without '.json' ending * * @param {string} dir directory that contains '.json' files to be read - * @param {boolean} [listBadKeys=false] do not print errors, used for badKeys() + * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @returns {TYPE.MetadataTypeMap} fileName => fileContent map */ static getJsonFromFS(dir, listBadKeys) { @@ -864,7 +864,7 @@ class MetadataType { * * @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry * @param {string} uri rest endpoint for PATCH - * @param {'patch'|'post'|'put'} [httpMethod='patch'] defaults to 'patch'; some update requests require PUT instead of PATCH + * @param {'patch'|'post'|'put'} [httpMethod] defaults to 'patch'; some update requests require PUT instead of PATCH * @returns {Promise. | null} Promise of API response or null in case of an error */ static async updateREST(metadataEntry, uri, httpMethod = 'patch') { @@ -1293,7 +1293,7 @@ class MetadataType { * * @static * @param {TYPE.MetadataTypeItem} metadataEntry metadata entry - * @param {boolean} [include=false] true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude + * @param {boolean} [include] true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude * @returns {boolean} true: skip saving == filtered; false: continue with saving * @memberof MetadataType */ @@ -1338,7 +1338,7 @@ class MetadataType { * * @static * @param {object} metadataEntry metadata entry - * @param {boolean} [include=false] true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude + * @param {boolean} [include] true: use definition.include / options.include; false=exclude: use definition.filter / options.exclude * @returns {boolean} true: filtered == do NOT save; false: not filtered == do save * @memberof MetadataType */ @@ -1954,7 +1954,7 @@ class MetadataType { * Returns metadata of a business unit that is saved locally * * @param {string} readDir root directory of metadata. - * @param {boolean} [listBadKeys=false] do not print errors, used for badKeys() + * @param {boolean} [listBadKeys] do not print errors, used for badKeys() * @param {object} [buMetadata] Metadata of BU in local directory * @returns {object} Metadata of BU in local directory */ diff --git a/lib/metadataTypes/User.js b/lib/metadataTypes/User.js index 59701f082..77c5e21c7 100644 --- a/lib/metadataTypes/User.js +++ b/lib/metadataTypes/User.js @@ -510,7 +510,7 @@ class User extends MetadataType { * @param {string} roleName role.Name * @param {number} userId user.AccountUserID * @param {boolean} assignmentOnly if true, only assignment configuration will be returned - * @param {boolean} [isRoleRemovale=false] if true, role will be removed from user; otherwise added + * @param {boolean} [isRoleRemovale] if true, role will be removed from user; otherwise added * @returns {object} format needed by API */ static _getRoleObjectForDeploy( diff --git a/lib/util/file.js b/lib/util/file.js index 89206f83e..d164a943c 100644 --- a/lib/util/file.js +++ b/lib/util/file.js @@ -381,7 +381,7 @@ const File = { * @param {string | string[]} directory directory where the file is stored * @param {string} filename name of the file without '.json' ending * @param {string} filetype filetype suffix - * @param {string} [encoding='utf8'] read file with encoding (defaults to utf-8) + * @param {string} [encoding] read file with encoding (defaults to utf-8) * @returns {Promise. | void} file contents; void on error */ readFilteredFilename: function (directory, filename, filetype, encoding) { @@ -514,7 +514,7 @@ const File = { /** * Initalises Prettier formatting lib async. * - * @param {string} [filetype='html'] filetype ie. JSON or SSJS + * @param {string} [filetype] filetype ie. JSON or SSJS * @returns {Promise.} success of config load */ async initPrettier(filetype = 'html') { diff --git a/lib/util/util.js b/lib/util/util.js index a5bfe7cf3..173e88cbd 100644 --- a/lib/util/util.js +++ b/lib/util/util.js @@ -229,7 +229,7 @@ const Util = { /** * wrapper around our standard winston logging to console and logfile * - * @param {boolean} [noLogFile=false] optional flag to indicate if we should log to file; CLI logs are always on + * @param {boolean} [noLogFile] optional flag to indicate if we should log to file; CLI logs are always on * @returns {object} initiated logger for console and file */ _createNewLoggerTransport: function (noLogFile = false) { @@ -296,8 +296,8 @@ const Util = { /** * initiate winston logger * - * @param {boolean} [restart=false] if true, logger will be restarted; otherwise, an existing logger will be used - * @param {boolean} [noLogFile=false] if false, logger will log to file; otherwise, only to console + * @param {boolean} [restart] if true, logger will be restarted; otherwise, an existing logger will be used + * @param {boolean} [noLogFile] if false, logger will log to file; otherwise, only to console * @returns {void} */ startLogger: function (restart = false, noLogFile = false) { From c8c40504cf2036bd4aff46161ed3d1c3b0534e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 27 Jun 2023 23:29:13 +0200 Subject: [PATCH 035/208] #987: add initial --like support to retrieve method --- docs/dist/documentation.md | 54 +++++++++++++++++++++++++++++++ lib/cli.js | 6 ++++ lib/index.js | 5 +-- lib/metadataTypes/MetadataType.js | 4 +++ lib/util/util.js | 44 +++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 2 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index c937ec619..264fee542 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -5880,6 +5880,8 @@ CLI entry for SFMC DevTools * [.getKeysString(keyArr, [isId])](#Util.getKeysString) ⇒ string * [.sleep(ms)](#Util.sleep) ⇒ Promise.<void> * [.getSsjs(code)](#Util.getSsjs) ⇒ string + * [.stringLike(testString, search)](#Util.stringLike) ⇒ boolean + * [.fieldsLike(metadata)](#Util.fieldsLike) ⇒ boolean @@ -6236,6 +6238,31 @@ the following is invalid: // 3 ``` + + +### Util.stringLike(testString, search) ⇒ boolean +allows us to filter just like with SQL's LIKE operator + +**Kind**: static method of [Util](#Util) +**Returns**: boolean - true if testString matches search + +| Param | Type | Description | +| --- | --- | --- | +| testString | string | field value to test | +| search | string | search string in SQL LIKE format | + + + +### Util.fieldsLike(metadata) ⇒ boolean +returns true if no LIKE filter is defined or if all filters match + +**Kind**: static method of [Util](#Util) +**Returns**: boolean - true if no LIKE filter is defined or if all filters match + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.MetadataTypeItem | a single metadata item | + ## MetadataTypeDefinitions @@ -7770,6 +7797,8 @@ Util that contains logger and simple util methods * [.getKeysString(keyArr, [isId])](#Util.getKeysString) ⇒ string * [.sleep(ms)](#Util.sleep) ⇒ Promise.<void> * [.getSsjs(code)](#Util.getSsjs) ⇒ string + * [.stringLike(testString, search)](#Util.stringLike) ⇒ boolean + * [.fieldsLike(metadata)](#Util.fieldsLike) ⇒ boolean @@ -8126,6 +8155,31 @@ the following is invalid: // 3 ``` + + +### Util.stringLike(testString, search) ⇒ boolean +allows us to filter just like with SQL's LIKE operator + +**Kind**: static method of [Util](#Util) +**Returns**: boolean - true if testString matches search + +| Param | Type | Description | +| --- | --- | --- | +| testString | string | field value to test | +| search | string | search string in SQL LIKE format | + + + +### Util.fieldsLike(metadata) ⇒ boolean +returns true if no LIKE filter is defined or if all filters match + +**Kind**: static method of [Util](#Util) +**Returns**: boolean - true if no LIKE filter is defined or if all filters match + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.MetadataTypeItem | a single metadata item | + ## csvToArray(csv) ⇒ Array.<string> diff --git a/lib/cli.js b/lib/cli.js index 4bd979400..81aac2d06 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -31,6 +31,12 @@ yargs .positional('KEY', { type: 'string', describe: 'metadata keys that shall be exclusively downloaded', + }) + .option('like', { + type: 'string', + group: 'Options for retrieve:', + describe: + 'filter metadata components (can include % as wildcard or _ for a single character, comma separated)', }); }, handler: (argv) => { diff --git a/lib/index.js b/lib/index.js index 3589f02b6..bf3ada5e1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -51,15 +51,16 @@ class Mcdev { static setOptions(argv) { const knownOptions = [ 'api', - 'commitHistory', 'changeKeyField', 'changeKeyValue', + 'commitHistory', 'filter', 'fromRetrieve', 'json', + 'like', + 'noLogFile', 'refresh', 'skipInteraction', - 'noLogFile', ]; for (const option of knownOptions) { if (argv[option] !== undefined) { diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 584b7fa69..97a776854 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -1570,6 +1570,10 @@ class MetadataType { } } + if (Util.OPTIONS.like && !Util.fieldsLike(results[originalKey])) { + Util.logger.debug(`Filtered ${originalKey} because of --like option`); + continue; + } // we dont store Id on local disk, but we need it for caching logic, // so its in retrieve but not in save. Here we put into the clone so that the original // object used for caching doesnt have the Id removed. diff --git a/lib/util/util.js b/lib/util/util.js index 173e88cbd..7f447b988 100644 --- a/lib/util/util.js +++ b/lib/util/util.js @@ -780,6 +780,50 @@ const Util = { // no script found return null; }, + /** + * allows us to filter just like with SQL's LIKE operator + * + * @param {string} testString field value to test + * @param {string} search search string in SQL LIKE format + * @returns {boolean} true if testString matches search + */ + stringLike(testString, search) { + if (typeof search !== 'string' || this === null) { + return false; + } + // Remove special chars + search = search.replaceAll( + new RegExp('([\\.\\\\\\+\\*\\?\\[\\^\\]\\$\\(\\)\\{\\}\\=\\!\\<\\>\\|\\:\\-])', 'g'), + '\\$1' + ); + // Replace % and _ with equivalent regex + search = search.replaceAll('%', '.*').replaceAll('_', '.'); + // Check matches + return new RegExp('^' + search + '$', 'gi').test(testString); + }, + /** + * returns true if no LIKE filter is defined or if all filters match + * + * @param {TYPE.MetadataTypeItem} metadata a single metadata item + * @returns {boolean} true if no LIKE filter is defined or if all filters match + */ + fieldsLike(metadata) { + const filters = Util.OPTIONS.like; + if (!filters) { + return true; + } + const fields = Object.keys(filters); + return fields.every((field) => { + const filter = filters[field]; + // TODO apply recursive logic for nested objects + if (typeof filter === 'string') { + return Util.stringLike(metadata[field], filter); + } else if (Array.isArray(filter)) { + return filter.some((f) => Util.stringLike(metadata[field], f)); + } + return false; + }); + }, }; Util.startLogger(false, true); From 9e2f013b53c4ce006b56a83faea04168696efe2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 27 Jun 2023 23:57:14 +0200 Subject: [PATCH 036/208] #987: handle complex field paths in objects and arrays for --like --- docs/dist/documentation.md | 10 ++++++---- lib/util/util.js | 20 +++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 264fee542..7bf37edbd 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -5881,7 +5881,7 @@ CLI entry for SFMC DevTools * [.sleep(ms)](#Util.sleep) ⇒ Promise.<void> * [.getSsjs(code)](#Util.getSsjs) ⇒ string * [.stringLike(testString, search)](#Util.stringLike) ⇒ boolean - * [.fieldsLike(metadata)](#Util.fieldsLike) ⇒ boolean + * [.fieldsLike(metadata, [filters])](#Util.fieldsLike) ⇒ boolean @@ -6253,7 +6253,7 @@ allows us to filter just like with SQL's LIKE operator -### Util.fieldsLike(metadata) ⇒ boolean +### Util.fieldsLike(metadata, [filters]) ⇒ boolean returns true if no LIKE filter is defined or if all filters match **Kind**: static method of [Util](#Util) @@ -6262,6 +6262,7 @@ returns true if no LIKE filter is defined or if all filters match | Param | Type | Description | | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single metadata item | +| [filters] | object | only used in recursive calls | @@ -7798,7 +7799,7 @@ Util that contains logger and simple util methods * [.sleep(ms)](#Util.sleep) ⇒ Promise.<void> * [.getSsjs(code)](#Util.getSsjs) ⇒ string * [.stringLike(testString, search)](#Util.stringLike) ⇒ boolean - * [.fieldsLike(metadata)](#Util.fieldsLike) ⇒ boolean + * [.fieldsLike(metadata, [filters])](#Util.fieldsLike) ⇒ boolean @@ -8170,7 +8171,7 @@ allows us to filter just like with SQL's LIKE operator -### Util.fieldsLike(metadata) ⇒ boolean +### Util.fieldsLike(metadata, [filters]) ⇒ boolean returns true if no LIKE filter is defined or if all filters match **Kind**: static method of [Util](#Util) @@ -8179,6 +8180,7 @@ returns true if no LIKE filter is defined or if all filters match | Param | Type | Description | | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single metadata item | +| [filters] | object | only used in recursive calls | diff --git a/lib/util/util.js b/lib/util/util.js index 7f447b988..9f5146113 100644 --- a/lib/util/util.js +++ b/lib/util/util.js @@ -805,21 +805,27 @@ const Util = { * returns true if no LIKE filter is defined or if all filters match * * @param {TYPE.MetadataTypeItem} metadata a single metadata item + * @param {object} [filters] only used in recursive calls * @returns {boolean} true if no LIKE filter is defined or if all filters match */ - fieldsLike(metadata) { - const filters = Util.OPTIONS.like; + fieldsLike(metadata, filters) { + filters ||= Util.OPTIONS.like; if (!filters) { return true; } const fields = Object.keys(filters); return fields.every((field) => { const filter = filters[field]; - // TODO apply recursive logic for nested objects - if (typeof filter === 'string') { - return Util.stringLike(metadata[field], filter); - } else if (Array.isArray(filter)) { - return filter.some((f) => Util.stringLike(metadata[field], f)); + if (Array.isArray(metadata[field])) { + return metadata[field].some((f) => Util.fieldsLike(f, filter)); + } else { + if (typeof filter === 'string') { + return Util.stringLike(metadata[field], filter); + } else if (Array.isArray(filter)) { + return filter.some((f) => Util.stringLike(metadata[field], f)); + } else if (typeof filter === 'object') { + return Util.fieldsLike(metadata[field], filter); + } } return false; }); From 09fad8c402afab9d3ff83aa1df7d6d9fb042c7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 27 Jun 2023 23:58:55 +0200 Subject: [PATCH 037/208] #987: refactoring --- lib/cli.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 81aac2d06..3dce5868f 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -63,26 +63,26 @@ yargs type: 'string', describe: 'metadata key that shall be exclusively uploaded', }) - .group( - ['changeKeyField', 'changeKeyValue', 'fromRetrieve', 'refresh'], - 'Options for deploy:' - ) .option('changeKeyField', { type: 'string', + group: 'Options for deploy:', describe: 'enables updating the key of the deployed metadata with the value in provided field (e.g. c__newKey). Can be used to sync name and key fields.', }) .option('changeKeyValue', { type: 'string', + group: 'Options for deploy:', describe: 'allows updating the key of the metadata to the provided value. Only available if a single type and key is deployed', }) .option('fromRetrieve', { type: 'boolean', + group: 'Options for deploy:', describe: 'optionally deploy from retrieve folder', }) .option('refresh', { type: 'boolean', + group: 'Options for deploy:', describe: 'optional for asset-message: runs refresh command for related triggeredSends after deploy', }); @@ -315,8 +315,9 @@ yargs aliases: ['et'], desc: 'explains metadata types that can be retrieved', builder: (yargs) => { - yargs.group(['json'], 'Options for explainTypes:').option('json', { + yargs.option('json', { type: 'boolean', + group: 'Options for explainTypes:', describe: 'optionaly return info in json format', }); }, @@ -335,14 +336,15 @@ yargs type: 'string', describe: 'Pull Request target branch or git commit range', }) - .group(['filter', 'commitHistory'], 'Options for createDeltaPkg:') .option('filter', { type: 'string', + group: 'Options for createDeltaPkg:', describe: 'Disable templating & instead filter by the specified BU path (comma separated), can include subtype, will be prefixed with "retrieve/"', }) .option('commitHistory', { type: 'number', + group: 'Options for createDeltaPkg:', describe: 'Number of commits to look back for changes (supersedes config)', }); }, From df7301c968aa6fdef8302eb85dc345417fa77bc3 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Wed, 28 Jun 2023 16:42:56 +0200 Subject: [PATCH 038/208] #38: retrieve, change key deploy and cache dependent DRAFT --- lib/index.js | 68 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/lib/index.js b/lib/index.js index 40ecae412..ca1307f71 100644 --- a/lib/index.js +++ b/lib/index.js @@ -921,6 +921,7 @@ class Mcdev { static async _fixKeysBU(cred, bu, type, keyArr) { const properties = await config.getProperties(); let counter_failed = 0; + const toDeploy = []; const buObject = await Cli.getCredentialObject( properties, cred === null ? null : cred + '/' + bu, @@ -940,15 +941,68 @@ class Mcdev { Util.logger.error(ex.message); return; } - Util.logger.info('First retrieve'); - await this._retrieveBU(cred, bu, type, keyArr); + Util.logger.info(`First retrieve ${type}`); + const retriever = new Retriever(properties, buObject); + const retrieved = await retriever.retrieve(type, keyArr, null, false); + Object.keys(retrieved).forEach((key) => { + //console.log(Object.values(retrieved[key][0])[0]); + //console.log(Object.values(retrieved[key][0])); + for (const item of Object.values(retrieved[key][0])) { + // console.log(item); + if (item != null) { + // console.log('name: ', item.name); + // console.log('key: ', item.key); + if (item.name != item.key) { + // console.log(item.key); + toDeploy.push(item.key); + // console.log('item.key', item.key); + Util.logger.info(`Updating key for query ${item.key}`); + } else { + Util.logger.info( + ` ☇ skipping query ${item.key} - key does not need to be updated` + ); + } + } else { + Util.logger.error(`${item.key} not found on server.`); + } + } + }); + + //console.log(Object.values(Object.values(retrieved)[0])); + // console.log(Object.values(retrieved)[0]); + // console.log(Array.isArray(Object.values(retrieved)[0])); + // console.log(Object.values(retrieved)); + // console.log(Object.values(retrieved)); + // let i = 0; + // for (const item of Object.keys(retrieved)) { + // console.log(Object.values(retrieved[key][0])[0]) + + // if (Object.values(item)[0] != null) { + // console.log('name: ', Object.values(item)[0].name); + // console.log('key: ', Object.values(item)[0].key); + // if (Object.values(item)[0].name != Object.values(item)[0].key) { + // console.log(Object.values(item)[0].key); + // // toDeploy.push(Object.values(item)[0].key); + // console.log('Object.values(item)[0].key', Object.values(item)[0].key); + // Util.logger.info(`Updating key for query ${Object.values(item)[0].key}`); + // } else { + // Util.logger.info( + // ` ☇ skipping query ${ + // Object.values(item)[0].key + // } - key does not need to be updated` + // ); + // } + // } else { + // Util.logger.error(`${Object.values(item)[0].key} not found on server.`); + // } + // } + + console.log('******************************************', toDeploy); Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; - const properties = await config.getProperties(); - if (!(await config.checkProperties(properties))) { - return null; - } properties.directories.deploy = properties.directories.retrieve; - return await Deployer._deployBU(cred, bu, properties, type, keyArr, true); + await Deployer._deployBU(cred, bu, properties, type, toDeploy, true); + console.log(MetadataTypeDefinitions[type].dependencies); + this._retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } From f5579b7a618ade426bf53d006ca7c417027c834d Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Wed, 28 Jun 2023 16:45:52 +0200 Subject: [PATCH 039/208] #38: retrieve, change key deploy and cache dependent DRAFT --- lib/index.js | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/lib/index.js b/lib/index.js index ca1307f71..9b1f435c1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -945,17 +945,10 @@ class Mcdev { const retriever = new Retriever(properties, buObject); const retrieved = await retriever.retrieve(type, keyArr, null, false); Object.keys(retrieved).forEach((key) => { - //console.log(Object.values(retrieved[key][0])[0]); - //console.log(Object.values(retrieved[key][0])); for (const item of Object.values(retrieved[key][0])) { - // console.log(item); if (item != null) { - // console.log('name: ', item.name); - // console.log('key: ', item.key); if (item.name != item.key) { - // console.log(item.key); toDeploy.push(item.key); - // console.log('item.key', item.key); Util.logger.info(`Updating key for query ${item.key}`); } else { Util.logger.info( @@ -967,41 +960,9 @@ class Mcdev { } } }); - - //console.log(Object.values(Object.values(retrieved)[0])); - // console.log(Object.values(retrieved)[0]); - // console.log(Array.isArray(Object.values(retrieved)[0])); - // console.log(Object.values(retrieved)); - // console.log(Object.values(retrieved)); - // let i = 0; - // for (const item of Object.keys(retrieved)) { - // console.log(Object.values(retrieved[key][0])[0]) - - // if (Object.values(item)[0] != null) { - // console.log('name: ', Object.values(item)[0].name); - // console.log('key: ', Object.values(item)[0].key); - // if (Object.values(item)[0].name != Object.values(item)[0].key) { - // console.log(Object.values(item)[0].key); - // // toDeploy.push(Object.values(item)[0].key); - // console.log('Object.values(item)[0].key', Object.values(item)[0].key); - // Util.logger.info(`Updating key for query ${Object.values(item)[0].key}`); - // } else { - // Util.logger.info( - // ` ☇ skipping query ${ - // Object.values(item)[0].key - // } - key does not need to be updated` - // ); - // } - // } else { - // Util.logger.error(`${Object.values(item)[0].key} not found on server.`); - // } - // } - - console.log('******************************************', toDeploy); Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; properties.directories.deploy = properties.directories.retrieve; await Deployer._deployBU(cred, bu, properties, type, toDeploy, true); - console.log(MetadataTypeDefinitions[type].dependencies); this._retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); From e8da1b2fe796679eb958058664b81784e904eb42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 28 Jun 2023 16:50:38 +0200 Subject: [PATCH 040/208] #987: add --like option support to execute command --- docs/dist/documentation.md | 30 +++++-- lib/cli.js | 15 +++- lib/index.js | 167 +++++++++++++++++++++++++++---------- lib/util/util.js | 4 + 4 files changed, 160 insertions(+), 56 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 7bf37edbd..103c133e4 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -495,8 +495,9 @@ main class * [.buildDefinition(businessUnit, selectedType, name, market)](#Mcdev.buildDefinition) ⇒ Promise.<void> * [.buildDefinitionBulk(listName, type, name)](#Mcdev.buildDefinitionBulk) ⇒ Promise.<void> * [.getFilesToCommit(businessUnit, selectedType, keyArr)](#Mcdev.getFilesToCommit) ⇒ Promise.<Array.<string>> - * [.execute(businessUnit, [selectedTypesArr], keys)](#Mcdev.execute) ⇒ Promise.<boolean> - * [._executeBU(cred, bu, [selectedTypesArr], keyArr)](#Mcdev._executeBU) ⇒ Promise.<boolean> + * [.execute(businessUnit, [selectedType], [keys])](#Mcdev.execute) ⇒ Promise.<boolean> + * [._executeBU(cred, bu, [type], keyArr)](#Mcdev._executeBU) ⇒ Promise.<boolean> + * [._getKeysWithLike(selectedType, buObject)](#Mcdev._getKeysWithLike) ⇒ Array.<string> @@ -751,7 +752,7 @@ Build a specific metadata file based on a template using a list of bu-market com -### Mcdev.execute(businessUnit, [selectedTypesArr], keys) ⇒ Promise.<boolean> +### Mcdev.execute(businessUnit, [selectedType], [keys]) ⇒ Promise.<boolean> Start an item (query) **Kind**: static method of [Mcdev](#Mcdev) @@ -760,13 +761,13 @@ Start an item (query) | Param | Type | Description | | --- | --- | --- | | businessUnit | string | name of BU | -| [selectedTypesArr] | Array.<TYPE.SupportedMetadataTypes> | limit to given metadata types | -| keys | Array.<string> | customerkey of the metadata | +| [selectedType] | TYPE.SupportedMetadataTypes | limit to given metadata types | +| [keys] | Array.<string> | customerkey of the metadata | -### Mcdev.\_executeBU(cred, bu, [selectedTypesArr], keyArr) ⇒ Promise.<boolean> -helper for [execute](execute) +### Mcdev.\_executeBU(cred, bu, [type], keyArr) ⇒ Promise.<boolean> +helper for [execute](#Mcdev.execute) **Kind**: static method of [Mcdev](#Mcdev) **Returns**: Promise.<boolean> - true if all items were executed, false otherwise @@ -775,9 +776,22 @@ helper for [execute](execute) | --- | --- | --- | | cred | string | name of Credential | | bu | string | name of BU | -| [selectedTypesArr] | Array.<TYPE.SupportedMetadataTypes> | limit execution to given metadata type | +| [type] | TYPE.SupportedMetadataTypes | limit execution to given metadata type | | keyArr | Array.<string> | customerkey of the metadata | + + +### Mcdev.\_getKeysWithLike(selectedType, buObject) ⇒ Array.<string> +helper for [_executeBU](#Mcdev._executeBU) + +**Kind**: static method of [Mcdev](#Mcdev) +**Returns**: Array.<string> - keyArr + +| Param | Type | Description | +| --- | --- | --- | +| selectedType | TYPE.SupportedMetadataTypes | limit execution to given metadata type | +| buObject | TYPE.BuObject | properties for auth | + ## Asset ⇐ [MetadataType](#MetadataType) diff --git a/lib/cli.js b/lib/cli.js index 3dce5868f..3d3f60ed4 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -36,7 +36,7 @@ yargs type: 'string', group: 'Options for retrieve:', describe: - 'filter metadata components (can include % as wildcard or _ for a single character, comma separated)', + 'filter metadata components (can include % as wildcard or _ for a single character)', }); }, handler: (argv) => { @@ -403,8 +403,8 @@ yargs }, }) .command({ - command: 'execute ', - aliases: ['exec'], + command: 'execute [KEY]', + aliases: ['exec', 'start'], desc: 'executes the entity (query/journey/automation etc.)', builder: (yargs) => { yargs @@ -419,11 +419,18 @@ yargs .positional('KEY', { type: 'string', describe: 'key(s) of the metadata component(s)', + }) + .option('like', { + type: 'string', + group: 'Options for execute:', + describe: + 'filter metadata components (can include % as wildcard or _ for a single character)', }); }, handler: (argv) => { Mcdev.setOptions(argv); - Mcdev.execute(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); + // ! do not allow multiple types to be passed in here via csvToArray + Mcdev.execute(argv.BU, argv.TYPE, csvToArray(argv.KEY)); }, }) .command({ diff --git a/lib/index.js b/lib/index.js index bf3ada5e1..be18b67b1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -236,7 +236,7 @@ class Mcdev { } } /** - * helper for {@link retrieve} + * helper for {@link Mcdev.retrieve} * * @private * @param {string} cred name of Credential @@ -705,11 +705,11 @@ class Mcdev { * Start an item (query) * * @param {string} businessUnit name of BU - * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit to given metadata types - * @param {string[]} keys customerkey of the metadata + * @param {TYPE.SupportedMetadataTypes} [selectedType] limit to given metadata types + * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.} true if all started successfully, false if not */ - static async execute(businessUnit, selectedTypesArr, keys) { + static async execute(businessUnit, selectedType, keys) { Util.startLogger(); Util.logger.info('mcdev:: Execute'); const properties = await config.getProperties(); @@ -719,15 +719,29 @@ class Mcdev { // return null here to avoid seeing 2 error messages for the same issue return null; } - if (Array.isArray(selectedTypesArr)) { - // types and keys can be provided but for each type all provided keys are applied as filter - for (const selectedType of Array.isArray(selectedTypesArr) - ? selectedTypesArr - : Object.keys(selectedTypesArr)) { - if (!Util._isValidType(selectedType)) { - return; - } - } + if (!Util._isValidType(selectedType)) { + return; + } + if (!Object.prototype.hasOwnProperty.call(MetadataTypeInfo[selectedType], 'execute')) { + Util.logger.error( + ` ☇ skipping ${selectedType}: execute is not supported yet for ${selectedType}` + ); + return; + } + if ( + (!Array.isArray(keys) || !keys.length) && + (!Util.OPTIONS.like || !Object.keys(Util.OPTIONS.like).length) + ) { + Util.logger.error('At least one key or a --like filter is required.'); + return; + } else if ( + Array.isArray(keys) && + keys.length && + Util.OPTIONS.like && + Object.keys(Util.OPTIONS.like).length + ) { + Util.logger.error('You can either specify keys OR a --like filter.'); + return; } if (businessUnit === '*') { Util.logger.info( @@ -738,7 +752,7 @@ class Mcdev { Util.logger.info(`\n :: Executing the entity on all BUs for ${cred}`); for (const bu in properties.credentials[cred].businessUnits) { - if (await this._executeBU(cred, bu, selectedTypesArr, keys)) { + if (await this._executeBU(cred, bu, selectedType, keys)) { counter_credBu++; } else { counter_failed++; @@ -778,7 +792,7 @@ class Mcdev { Util.logger.info(`\n :: Executing the entity on all BUs for ${cred}`); let counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { - if (await this._executeBU(cred, bu, selectedTypesArr, keys)) { + if (await this._executeBU(cred, bu, selectedType, keys)) { counter_credBu++; } else { counter_failed++; @@ -790,7 +804,7 @@ class Mcdev { ); } else { // execute the entity on one BU only - if (await this._executeBU(cred, bu, selectedTypesArr, keys)) { + if (await this._executeBU(cred, bu, selectedType, keys)) { counter_credBu++; } else { counter_failed++; @@ -804,15 +818,15 @@ class Mcdev { return counter_failed === 0 ? true : false; } /** - * helper for {@link execute} + * helper for {@link Mcdev.execute} * * @param {string} cred name of Credential * @param {string} bu name of BU - * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit execution to given metadata type + * @param {TYPE.SupportedMetadataTypes} [type] limit execution to given metadata type * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.} true if all items were executed, false otherwise */ - static async _executeBU(cred, bu, selectedTypesArr, keyArr) { + static async _executeBU(cred, bu, type, keyArr) { const properties = await config.getProperties(); let counter_failed = 0; const buObject = await Cli.getCredentialObject( @@ -821,38 +835,103 @@ class Mcdev { null, true ); - if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) { - throw new Error('No keys were provided'); + try { + if (!type) { + throw new Error('No type was provided'); + } + if (buObject !== null) { + cache.initCache(buObject); + cred = buObject.credential; + bu = buObject.businessUnit; + } + Util.logger.info(`\n :: Executing ${type} on ${cred}/${bu}\n`); + try { + MetadataTypeInfo[type].client = auth.getSDK(buObject); + } catch (ex) { + Util.logger.error(ex.message); + return; + } + if (Util.OPTIONS.like && Object.keys(Util.OPTIONS.like).length) { + keyArr = await this._getKeysWithLike(type, buObject); + } + if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) { + throw new Error('No keys were provided'); + } + + // result will be undefined (false) if execute is not supported for the type + if (!(await MetadataTypeInfo[type].execute(keyArr))) { + counter_failed++; + } + } catch (ex) { + Util.logger.errorStack(ex, 'mcdev.execute failed'); } - if (!selectedTypesArr || (Array.isArray(selectedTypesArr) && !selectedTypesArr.length)) { - throw new Error('No type was provided'); + + return counter_failed === 0 ? true : false; + } + + /** + * helper for {@link Mcdev._executeBU} + * + * @param {TYPE.SupportedMetadataTypes} selectedType limit execution to given metadata type + * @param {TYPE.BuObject} buObject properties for auth + * @returns {string[]} keyArr + */ + static async _getKeysWithLike(selectedType, buObject) { + const properties = await config.getProperties(); + + // cache depenencies + const deployOrder = Util.getMetadataHierachy([selectedType]); + for (const type in deployOrder) { + const subTypeArr = deployOrder[type]; + MetadataTypeInfo[type].client = auth.getSDK(buObject); + MetadataTypeInfo[type].properties = properties; + MetadataTypeInfo[type].buObject = buObject; + Util.logger.info(`Caching dependent Metadata: ${type}`); + Util.logSubtypes(subTypeArr); + const result = await MetadataTypeInfo[type].retrieveForCache(null, subTypeArr); + if (result) { + if (Array.isArray(result)) { + for (const result_i of result) { + if (result_i?.metadata && Object.keys(result_i.metadata).length) { + cache.mergeMetadata(type, result_i.metadata); + } + } + } else { + cache.setMetadata(type, result.metadata); + } + } } - if (buObject !== null) { - cache.initCache(buObject); - cred = buObject.credential; - bu = buObject.businessUnit; + + // find all keys in chosen type that match the like-filter + const keyArr = []; + const metadataMap = cache.getCache()[selectedType]; + if (!metadataMap) { + throw new Error(`Selected type ${selectedType} could not be cached`); } Util.logger.info( - `\n :: Executing ${selectedTypesArr.join(', ')} on ${cred}/${bu}\n` + Util.getGrayMsg(`Found ${Object.keys(metadataMap).length} ${selectedType}s`) ); - try { - // more than one type was provided, iterate types and execute items - for (const type of selectedTypesArr) { - try { - MetadataTypeInfo[type].client = auth.getSDK(buObject); - } catch (ex) { - Util.logger.error(ex.message); - return; - } - // result will be undefined (false) if execute is not supported for the type - if (!(await MetadataTypeInfo[type].execute(keyArr))) { - counter_failed++; - } + for (const originalKey in metadataMap) { + // hide postRetrieveOutput + Util.setLoggingLevel({ silent: true }); + metadataMap[originalKey] = MetadataTypeInfo[selectedType].postRetrieveTasks( + metadataMap[originalKey] + ); + // reactivate logging + Util.setLoggingLevel({}); + if (Util.fieldsLike(metadataMap[originalKey])) { + keyArr.push(originalKey); } - } catch (ex) { - Util.logger.errorStack(ex, 'mcdev.execute failed'); } - return counter_failed === 0 ? true : false; + Util.logger.info( + Util.getGrayMsg( + `Identified ${keyArr.length} ${selectedType}${ + keyArr.length === 1 ? '' : 's' + } that match${selectedType}${keyArr.length === 1 ? 'es' : ''} the like-filter` + ) + ); + + return keyArr; } } diff --git a/lib/util/util.js b/lib/util/util.js index 9f5146113..e552fe382 100644 --- a/lib/util/util.js +++ b/lib/util/util.js @@ -809,6 +809,10 @@ const Util = { * @returns {boolean} true if no LIKE filter is defined or if all filters match */ fieldsLike(metadata, filters) { + if (metadata.json && metadata.codeArr) { + // Compensate for CodeExtractItem format + metadata = metadata.json; + } filters ||= Util.OPTIONS.like; if (!filters) { return true; From dbc5bcd29f9408b175a07565b446dc061989f0d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 28 Jun 2023 17:09:07 +0200 Subject: [PATCH 041/208] #987: fix execute query test to work with new --like logic --- lib/index.js | 21 ++++++++------------- test/type.query.test.js | 26 ++++++++++++++++++++------ 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/lib/index.js b/lib/index.js index be18b67b1..26d19ed66 100644 --- a/lib/index.js +++ b/lib/index.js @@ -711,29 +711,29 @@ class Mcdev { */ static async execute(businessUnit, selectedType, keys) { Util.startLogger(); - Util.logger.info('mcdev:: Execute'); + Util.logger.info('mcdev:: Executing ' + selectedType); const properties = await config.getProperties(); let counter_credBu = 0; let counter_failed = 0; if (!(await config.checkProperties(properties))) { // return null here to avoid seeing 2 error messages for the same issue - return null; + return false; } if (!Util._isValidType(selectedType)) { - return; + return false; } if (!Object.prototype.hasOwnProperty.call(MetadataTypeInfo[selectedType], 'execute')) { Util.logger.error( ` ☇ skipping ${selectedType}: execute is not supported yet for ${selectedType}` ); - return; + return false; } if ( (!Array.isArray(keys) || !keys.length) && (!Util.OPTIONS.like || !Object.keys(Util.OPTIONS.like).length) ) { Util.logger.error('At least one key or a --like filter is required.'); - return; + return false; } else if ( Array.isArray(keys) && keys.length && @@ -741,7 +741,7 @@ class Mcdev { Object.keys(Util.OPTIONS.like).length ) { Util.logger.error('You can either specify keys OR a --like filter.'); - return; + return false; } if (businessUnit === '*') { Util.logger.info( @@ -782,7 +782,7 @@ class Mcdev { true ); if (buObject === null) { - return; + return false; } else { cred = buObject.credential; bu = buObject.businessUnit; @@ -845,12 +845,7 @@ class Mcdev { bu = buObject.businessUnit; } Util.logger.info(`\n :: Executing ${type} on ${cred}/${bu}\n`); - try { - MetadataTypeInfo[type].client = auth.getSDK(buObject); - } catch (ex) { - Util.logger.error(ex.message); - return; - } + MetadataTypeInfo[type].client = auth.getSDK(buObject); if (Util.OPTIONS.like && Object.keys(Util.OPTIONS.like).length) { keyArr = await this._getKeysWithLike(type, buObject); } diff --git a/test/type.query.test.js b/test/type.query.test.js index edaf72161..489e51898 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -279,15 +279,29 @@ describe('type: query', () => { }); }); describe('Execute ================', () => { - it('Should start executing a query', async () => { - const execute = await handler.execute( - 'testInstance/testBU', - ['query'], - ['testExisting_query'] - ); + it('Should start a query by key', async () => { + const execute = await handler.execute('testInstance/testBU', 'query', [ + 'testExisting_query', + ]); + assert.equal(process.exitCode, false, 'execute should not have thrown an error'); + assert.equal(execute, true, 'query was supposed to be executed'); + return; + }); + it('Should start a query selected via --like', async () => { + handler.setOptions({ like: { key: 'testExisting%' } }); + const execute = await handler.execute('testInstance/testBU', 'query'); assert.equal(process.exitCode, false, 'execute should not have thrown an error'); assert.equal(execute, true, 'query was supposed to be executed'); return; }); + it('Should not start executing a query because key and --like was specified', async () => { + handler.setOptions({ like: { key: 'testExisting%' } }); + const execute = await handler.execute('testInstance/testBU', 'query', [ + 'testExisting_query', + ]); + assert.equal(process.exitCode, true, 'execute should not have thrown an error'); + assert.equal(execute, false, 'query was not supposed to be executed'); + return; + }); }); }); From a91ca1214edc0b5d7d606a785a0959fec14aee52 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Wed, 28 Jun 2023 17:25:42 +0200 Subject: [PATCH 042/208] #38: check if type exists, check if key can be updated --- lib/index.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 9b1f435c1..f250aabc6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -871,11 +871,21 @@ class Mcdev { // return null here to avoid seeing 2 error messages for the same issue return null; } - //TODO: check if type exists + if (type) { + for (const selectedType of Array.isArray(type) ? type : Object.keys(type)) { + if (!Util._isValidType(selectedType)) { + return; + } + } + } if (Array.isArray(type) && type.length > 1) { Util.logger.error('fixKeys expects a single type to be deployed'); return null; } + if (type.definition.keyField === this.definition.idField) { + Util.logger.error(`Key cannot be updated for this type`); + return null; + } let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; // to allow all-BU via user selection we need to run this here already if ( From 9784c730a4fc21c290dc7f1a422b0ef33bf27b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 28 Jun 2023 17:26:01 +0200 Subject: [PATCH 043/208] #987: add retrieve --like tests --- test/type.query.test.js | 57 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/test/type.query.test.js b/test/type.query.test.js index 489e51898..0b04d878f 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -53,7 +53,7 @@ describe('type: query', () => { ); return; }); - it('Should retrieve one specific query', async () => { + it('Should retrieve one specific query by key', async () => { // WHEN await handler.retrieve('testInstance/testBU', ['query'], ['testExisting_query']); // THEN @@ -80,6 +80,61 @@ describe('type: query', () => { ); return; }); + it('Should retrieve one specific query via --like', async () => { + // WHEN + handler.setOptions({ like: { key: '%Existing_query' } }); + await handler.retrieve('testInstance/testBU', ['query']); + // THEN + assert.equal(process.exitCode, false, 'retrieve should not have thrown an error'); + // get results from cache + const result = cache.getCache(); + assert.equal( + result.query ? Object.keys(result.query).length : 0, + 2, + 'two queries in cache expected' + ); + assert.deepEqual( + await testUtils.getActualJson('testExisting_query', 'query'), + await testUtils.getExpectedJson('9999999', 'query', 'get'), + 'returned metadata was not equal expected' + ); + expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.equal( + file(testUtils.getExpectedFile('9999999', 'query', 'get', 'sql')) + ); + expect(file(testUtils.getActualFile('testExisting_query2', 'query', 'sql'))).to.not + .exist; + assert.equal( + testUtils.getAPIHistoryLength(), + 6, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + it('Should not retrieve any query via --like and key due to a mismatching filter', async () => { + // WHEN + handler.setOptions({ like: { key: 'NotExisting_query' } }); + await handler.retrieve('testInstance/testBU', ['query']); + // THEN + assert.equal(process.exitCode, false, 'retrieve should not have thrown an error'); + // get results from cache + const result = cache.getCache(); + assert.equal( + result.query ? Object.keys(result.query).length : 0, + 2, + 'two queries in cache expected' + ); + + expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.not + .exist; + expect(file(testUtils.getActualFile('testExisting_query2', 'query', 'sql'))).to.not + .exist; + assert.equal( + testUtils.getAPIHistoryLength(), + 6, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); }); describe('Deploy ================', () => { beforeEach(() => { From 93d441b00f740a2fc5669b72c1b4eb963891cc84 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Thu, 29 Jun 2023 09:49:22 +0200 Subject: [PATCH 044/208] #982: test method --- test/type.query.test.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/test/type.query.test.js b/test/type.query.test.js index 2a3895d1d..f914298f5 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -134,19 +134,10 @@ describe('type: query', () => { false, 'deploy with --execute should not have thrown an error' ); - // confirm created item - assert.deepEqual( - await testUtils.getActualJson('testNew_query', 'query'), - await testUtils.getExpectedJson('9999999', 'query', 'post'), - 'returned metadata was not equal expected for insert query' - ); - expect(file(testUtils.getActualFile('testNew_query', 'query', 'sql'))).to.equal( - file(testUtils.getExpectedFile('9999999', 'query', 'post', 'sql')) - ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 12, + 11, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; From d20f384dd9673eba9bbf3c9cea7861a3aeac7009 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Thu, 29 Jun 2023 09:51:39 +0200 Subject: [PATCH 045/208] #982: test method --- test/type.query.test.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/type.query.test.js b/test/type.query.test.js index f914298f5..2a3895d1d 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -134,10 +134,19 @@ describe('type: query', () => { false, 'deploy with --execute should not have thrown an error' ); + // confirm created item + assert.deepEqual( + await testUtils.getActualJson('testNew_query', 'query'), + await testUtils.getExpectedJson('9999999', 'query', 'post'), + 'returned metadata was not equal expected for insert query' + ); + expect(file(testUtils.getActualFile('testNew_query', 'query', 'sql'))).to.equal( + file(testUtils.getExpectedFile('9999999', 'query', 'post', 'sql')) + ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 11, + 12, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; From 50ed42cb6ca45e13c9d965ceaa9be25e3f18792a Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Thu, 29 Jun 2023 09:58:46 +0200 Subject: [PATCH 046/208] #982: await --- lib/metadataTypes/Query.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/metadataTypes/Query.js b/lib/metadataTypes/Query.js index 7578b0292..1eec6815b 100644 --- a/lib/metadataTypes/Query.js +++ b/lib/metadataTypes/Query.js @@ -459,7 +459,7 @@ class Query extends MetadataType { */ static async postDeployTasks(metadata) { if (Util.OPTIONS.execute) { - this.execute(Object.keys(metadata)); + await this.execute(Object.keys(metadata)); } } } From a7ea40e49d60cb7820e792f1aed5e38406508e91 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Thu, 29 Jun 2023 10:15:04 +0200 Subject: [PATCH 047/208] #982: test method --- test/type.query.test.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/type.query.test.js b/test/type.query.test.js index 2a3895d1d..7d9a10499 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -127,26 +127,26 @@ describe('type: query', () => { it('Should deploy and execute with --execute', async () => { handler.setOptions({ execute: true }); // WHEN - await handler.deploy('testInstance/testBU', ['query'], 'testNew_query'); + await handler.deploy('testInstance/testBU', ['query'], ['testExisting_query']); // THEN assert.equal( process.exitCode, false, 'deploy with --execute should not have thrown an error' ); - // confirm created item + // confirm updated item assert.deepEqual( - await testUtils.getActualJson('testNew_query', 'query'), - await testUtils.getExpectedJson('9999999', 'query', 'post'), + await testUtils.getActualJson('testExisting_query', 'query'), + await testUtils.getExpectedJson('9999999', 'query', 'patch'), 'returned metadata was not equal expected for insert query' ); - expect(file(testUtils.getActualFile('testNew_query', 'query', 'sql'))).to.equal( - file(testUtils.getExpectedFile('9999999', 'query', 'post', 'sql')) + expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.equal( + file(testUtils.getExpectedFile('9999999', 'query', 'patch', 'sql')) ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 12, + 9, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; From 594a8030d3d9968ea66f6b77e4cf6c8373a122e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 29 Jun 2023 11:36:26 +0200 Subject: [PATCH 048/208] #0: convert full xml filter to testing-response file name --- docs/dist/documentation.md | 12 ++++++++++++ test/resourceFactory.js | 17 ++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 8027e7538..7254c9912 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -4601,6 +4601,7 @@ Query MetadataType * [.checkForErrors(ex)](#Query.checkForErrors) ⇒ Array.<string> \| void * [.deleteByKey(customerKey)](#Query.deleteByKey) ⇒ boolean * [.postDeleteTasks(customerKey)](#Query.postDeleteTasks) ⇒ void + * [.postDeployTasks(metadata)](#Query.postDeployTasks) @@ -4799,6 +4800,17 @@ clean up after deleting a metadata item | --- | --- | --- | | customerKey | string | Identifier of metadata item | + + +### Query.postDeployTasks(metadata) +Gets executed after deployment of metadata type + +**Kind**: static method of [Query](#Query) + +| Param | Description | +| --- | --- | +| metadata | metadata mapped by their keyField | + ## Role ⇐ [MetadataType](#MetadataType) diff --git a/test/resourceFactory.js b/test/resourceFactory.js index 5cdd55508..e9176ab6a 100644 --- a/test/resourceFactory.js +++ b/test/resourceFactory.js @@ -54,11 +54,22 @@ exports.loadSOAPRecords = async (mcdevAction, type, mid, filter) => { }); }; exports.filterToPath = (filter) => { - if (filter && filter.Property && filter.SimpleOperator && filter.Value) { - return `-${filter.Property}${filter.SimpleOperator.replace('equals', '=')}${filter.Value}`; + if (filter) { + return '-' + this._filterToPath(filter); } return ''; }; +exports._filterToPath = (filter) => { + if (filter.Property && filter.SimpleOperator && filter.Value) { + return `${filter.Property}${filter.SimpleOperator.replace('equals', '=')}${filter.Value}`; + } else if (filter.LeftOperand && filter.LogicalOperator && filter.RightOperand) { + return ( + this._filterToPath(filter.LeftOperand) + + filter.LogicalOperator + + this._filterToPath(filter.RightOperand) + ); + } +}; /** * based on request, respond with different soap data * @@ -197,7 +208,7 @@ exports.handleRESTRequest = async (config) => { return [ 404, - fs.readFile(path.join('test', 'resources', 'rest404-response.json'), { + await fs.readFile(path.join('test', 'resources', 'rest404-response.json'), { encoding: 'utf8', }), ]; From 498225b516c53279c2fb9b7c6b5305af72fd86f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 29 Jun 2023 11:40:40 +0200 Subject: [PATCH 049/208] #0: enforce jsdoc includes parameter types --- .eslintrc.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.json b/.eslintrc.json index 355ff1839..3636f6eb4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -84,6 +84,7 @@ } } ], + "jsdoc/require-param-type": "error", "jsdoc/tag-lines": ["warn", "any", { "startLines": 1 }], "spaced-comment": ["warn", "always", { "block": { "exceptions": ["*"], "balanced": true } }] }, From f404dca73bf82223ed40fabd2247cbb08f85c283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 29 Jun 2023 11:46:19 +0200 Subject: [PATCH 050/208] #982: renamed query SOAP response to be more specific --- ...e-CustomerKey=testExisting_queryANDStatus=Active-response.xml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/resources/9999999/queryDefinition/{retrieve-response.xml => retrieve-CustomerKey=testExisting_queryANDStatus=Active-response.xml} (100%) diff --git a/test/resources/9999999/queryDefinition/retrieve-response.xml b/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_queryANDStatus=Active-response.xml similarity index 100% rename from test/resources/9999999/queryDefinition/retrieve-response.xml rename to test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_queryANDStatus=Active-response.xml From 7b7876def916e263627e6b206ab365d75222d949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 29 Jun 2023 12:03:05 +0200 Subject: [PATCH 051/208] #982: fix for one breaking execution stopping all following executions --- docs/dist/documentation.md | 10 +++++----- lib/metadataTypes/Query.js | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index c6a0ba924..44cddb11c 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -4593,7 +4593,7 @@ Query MetadataType * [.checkForErrors(ex)](#Query.checkForErrors) ⇒ Array.<string> \| void * [.deleteByKey(customerKey)](#Query.deleteByKey) ⇒ boolean * [.postDeleteTasks(customerKey)](#Query.postDeleteTasks) ⇒ void - * [.postDeployTasks(metadata)](#Query.postDeployTasks) + * [.postDeployTasks(upsertResults)](#Query.postDeployTasks) @@ -4794,14 +4794,14 @@ clean up after deleting a metadata item -### Query.postDeployTasks(metadata) +### Query.postDeployTasks(upsertResults) Gets executed after deployment of metadata type **Kind**: static method of [Query](#Query) -| Param | Description | -| --- | --- | -| metadata | metadata mapped by their keyField | +| Param | Type | Description | +| --- | --- | --- | +| upsertResults | TYPE.MetadataTypeMap | metadata mapped by their keyField as returned by update/create | diff --git a/lib/metadataTypes/Query.js b/lib/metadataTypes/Query.js index 1eec6815b..b3b315258 100644 --- a/lib/metadataTypes/Query.js +++ b/lib/metadataTypes/Query.js @@ -65,7 +65,7 @@ class Query extends MetadataType { objectId = await this._getObjectIdForSingleRetrieve(key); if (!objectId) { Util.logger.info(`Skipping ${key} - did not find an item with such key`); - break; + continue; } } results.push( @@ -455,11 +455,11 @@ class Query extends MetadataType { /** * Gets executed after deployment of metadata type * - * @param metadata metadata mapped by their keyField + * @param {TYPE.MetadataTypeMap} upsertResults metadata mapped by their keyField as returned by update/create */ - static async postDeployTasks(metadata) { + static async postDeployTasks(upsertResults) { if (Util.OPTIONS.execute) { - await this.execute(Object.keys(metadata)); + await this.execute(Object.keys(upsertResults)); } } } From 7487397e4d3e7cfddf6f12255746e751c1a18889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 29 Jun 2023 12:09:58 +0200 Subject: [PATCH 052/208] #982: improve log output --- lib/index.js | 14 ++++---------- lib/metadataTypes/MetadataType.js | 2 +- lib/metadataTypes/Query.js | 1 + 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/lib/index.js b/lib/index.js index 5ee214b46..968be4e7d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -730,12 +730,10 @@ class Mcdev { } } if (businessUnit === '*') { - Util.logger.info( - '\n :: Executing the entity on all BUs for all credentials' - ); + Util.logger.info(':: Executing the entity on all BUs for all credentials'); let counter_credTotal = 0; for (const cred in properties.credentials) { - Util.logger.info(`\n :: Executing the entity on all BUs for ${cred}`); + Util.logger.info(`:: Executing the entity on all BUs for ${cred}`); for (const bu in properties.credentials[cred].businessUnits) { if (await this._executeBU(cred, bu, selectedTypesArr, keys)) { @@ -746,13 +744,9 @@ class Mcdev { Util.startLogger(true); } counter_credTotal += counter_credBu; - Util.logger.info( - `\n :: Executed the entity on ${counter_credBu} BUs for ${cred}\n` - ); + Util.logger.info(`:: Executed the entity on ${counter_credBu} BUs for ${cred}\n`); } - Util.logger.info( - `\n :: Executed the entity on ${counter_credTotal} BUs in total\n` - ); + Util.logger.info(`:: Executed the entity on ${counter_credTotal} BUs in total\n`); } else { let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; // to allow all-BU via user selection we need to run this here already diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 584b7fa69..a5e55bcfa 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -1079,7 +1079,7 @@ class MetadataType { try { const response = await this.client.rest.post(uri, {}); // payload is empty for this request if (response === 'OK') { - Util.logger.info(`Executed ${this.definition.type}: ${key}`); + Util.logger.info(` - executed ${this.definition.type}: ${key}`); } else { throw new Error(response); } diff --git a/lib/metadataTypes/Query.js b/lib/metadataTypes/Query.js index b3b315258..f33d9a9d4 100644 --- a/lib/metadataTypes/Query.js +++ b/lib/metadataTypes/Query.js @@ -459,6 +459,7 @@ class Query extends MetadataType { */ static async postDeployTasks(upsertResults) { if (Util.OPTIONS.execute) { + Util.logger.info(`Executing: ${this.definition.type}`); await this.execute(Object.keys(upsertResults)); } } From bfac576a689c4bae4e1bada3cc64d1b437615840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 29 Jun 2023 12:12:29 +0200 Subject: [PATCH 053/208] #982: fixed execut test for newly created query --- .../actions/start/post-response.txt | 1 + ...testNew_queryANDStatus=Active-response.xml | 30 +++++++++++++++++++ test/type.query.test.js | 4 +-- 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dae/actions/start/post-response.txt create mode 100644 test/resources/9999999/queryDefinition/retrieve-CustomerKey=testNew_queryANDStatus=Active-response.xml diff --git a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dae/actions/start/post-response.txt b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dae/actions/start/post-response.txt new file mode 100644 index 000000000..a0aba9318 --- /dev/null +++ b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dae/actions/start/post-response.txt @@ -0,0 +1 @@ +OK \ No newline at end of file diff --git a/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testNew_queryANDStatus=Active-response.xml b/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testNew_queryANDStatus=Active-response.xml new file mode 100644 index 000000000..ad6aad842 --- /dev/null +++ b/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testNew_queryANDStatus=Active-response.xml @@ -0,0 +1,30 @@ + + + + RetrieveResponse + urn:uuid:7ef0345e-b559-4fc4-8986-47e54e1a8a58 + urn:uuid:b2e814a6-517c-4882-9bbb-238bfce951ce + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-04-11T16:33:48Z + 2023-04-11T16:38:48Z + + + + + + OK + e8eb2988-2f43-4243-a6b0-6ab6b841a6ab + + + 549f0568-607c-4940-afef-437965094dae + + + + \ No newline at end of file diff --git a/test/type.query.test.js b/test/type.query.test.js index 7d9a10499..e174cfdd1 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -127,7 +127,7 @@ describe('type: query', () => { it('Should deploy and execute with --execute', async () => { handler.setOptions({ execute: true }); // WHEN - await handler.deploy('testInstance/testBU', ['query'], ['testExisting_query']); + await handler.deploy('testInstance/testBU', ['query']); // THEN assert.equal( process.exitCode, @@ -146,7 +146,7 @@ describe('type: query', () => { // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 9, + 12, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; From fc53c6dd7d4ec725b43d54d017920badfbf461c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 29 Jun 2023 12:19:11 +0200 Subject: [PATCH 054/208] #982: ensure --execute is grouped in help-dialogue --- lib/cli.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index b768c2d77..d60988992 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -39,7 +39,7 @@ yargs }, }) .command({ - command: 'deploy [BU] [TYPE] [KEY] [--fromRetrieve] [--refresh] [--execute]', + command: 'deploy [BU] [TYPE] [KEY] [--fromRetrieve] [--refresh]', aliases: ['d'], desc: 'deploys local metadata to a business unit', builder: (yargs) => { @@ -58,7 +58,7 @@ yargs describe: 'metadata key that shall be exclusively uploaded', }) .group( - ['changeKeyField', 'changeKeyValue', 'fromRetrieve', 'refresh'], + ['changeKeyField', 'changeKeyValue', 'fromRetrieve', 'refresh', 'execute'], 'Options for deploy:' ) .option('changeKeyField', { From da912a975ff410bad2358d8281e0969f32d86598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 29 Jun 2023 14:34:41 +0200 Subject: [PATCH 055/208] #987: fix test to only find ONE query --- test/type.query.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/type.query.test.js b/test/type.query.test.js index 0de1e0780..b82df7cc4 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -370,7 +370,7 @@ describe('type: query', () => { return; }); it('Should start a query selected via --like', async () => { - handler.setOptions({ like: { key: 'testExisting%' } }); + handler.setOptions({ like: { key: 'testExist%query' } }); const execute = await handler.execute('testInstance/testBU', 'query'); assert.equal(process.exitCode, false, 'execute should not have thrown an error'); assert.equal(execute, true, 'query was supposed to be executed'); From 1d3cf0f42be1c8cc7323b0ae525e2743f24f5059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 29 Jun 2023 14:38:25 +0200 Subject: [PATCH 056/208] #987: rename method to describe better what it does --- docs/dist/documentation.md | 6 +++--- lib/index.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 2e8bd94f4..82eedc210 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -497,7 +497,7 @@ main class * [.getFilesToCommit(businessUnit, selectedType, keyArr)](#Mcdev.getFilesToCommit) ⇒ Promise.<Array.<string>> * [.execute(businessUnit, [selectedType], [keys])](#Mcdev.execute) ⇒ Promise.<boolean> * [._executeBU(cred, bu, [type], keyArr)](#Mcdev._executeBU) ⇒ Promise.<boolean> - * [._getKeysWithLike(selectedType, buObject)](#Mcdev._getKeysWithLike) ⇒ Array.<string> + * [._retrieveKeysWithLike(selectedType, buObject)](#Mcdev._retrieveKeysWithLike) ⇒ Array.<string> @@ -779,9 +779,9 @@ helper for [execute](#Mcdev.execute) | [type] | TYPE.SupportedMetadataTypes | limit execution to given metadata type | | keyArr | Array.<string> | customerkey of the metadata | - + -### Mcdev.\_getKeysWithLike(selectedType, buObject) ⇒ Array.<string> +### Mcdev.\_retrieveKeysWithLike(selectedType, buObject) ⇒ Array.<string> helper for [_executeBU](#Mcdev._executeBU) **Kind**: static method of [Mcdev](#Mcdev) diff --git a/lib/index.js b/lib/index.js index d381ca7c4..5928a854e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -842,7 +842,7 @@ class Mcdev { Util.logger.info(`\n :: Executing ${type} on ${cred}/${bu}\n`); MetadataTypeInfo[type].client = auth.getSDK(buObject); if (Util.OPTIONS.like && Object.keys(Util.OPTIONS.like).length) { - keyArr = await this._getKeysWithLike(type, buObject); + keyArr = await this._retrieveKeysWithLike(type, buObject); } if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) { throw new Error('No keys were provided'); @@ -866,7 +866,7 @@ class Mcdev { * @param {TYPE.BuObject} buObject properties for auth * @returns {string[]} keyArr */ - static async _getKeysWithLike(selectedType, buObject) { + static async _retrieveKeysWithLike(selectedType, buObject) { const properties = await config.getProperties(); // cache depenencies From 1ddad4ea3ab7a36e80c96d0a7d84b5397a8f89d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 10:42:02 +0200 Subject: [PATCH 057/208] #1008: ensure deploy returns deployed items, not complete cache --- lib/util/cache.js | 13 +++++++++---- test/type.user.test.js | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/util/cache.js b/lib/util/cache.js index bcea3a35d..b95931e3e 100644 --- a/lib/util/cache.js +++ b/lib/util/cache.js @@ -72,10 +72,15 @@ module.exports = { * @returns {void} */ mergeMetadata: (type, metadataMap, overrideMID) => { - dataStore[overrideMID || currentMID][type] = Object.assign( - metadataMap, - dataStore[currentMID][type] - ); + // ensure cache exists for type + dataStore[currentMID][type] ||= {}; + // if overrideMID is provided, create a copy of current MID cache + if (overrideMID) { + // ! needs to be verified if this is actually needed. When discovering an issue with this method actually overriting metadataMap, this copy-logic was present and i did not want to break things + dataStore[overrideMID][type] = Object.assign({}, dataStore[currentMID][type]); + } + // merge metadataMap into existing cache + Object.assign(dataStore[overrideMID || currentMID][type] || {}, metadataMap); }, /** * standardized method for getting data from cache. diff --git a/test/type.user.test.js b/test/type.user.test.js index cb56fe090..810164a60 100644 --- a/test/type.user.test.js +++ b/test/type.user.test.js @@ -83,7 +83,7 @@ describe('type: user', () => { }); it('Should create & upsert a user', async () => { // WHEN - const expectedCache = ['testNew_user', 'testExisting_user']; + const expectedCache = ['testExisting_user', 'testNew_user']; await handler.deploy('testInstance/_ParentBU_', ['user'], expectedCache); // THEN assert.equal(process.exitCode, false, 'deploy should not have thrown an error'); From 69e2f27728932db956e7502407e8691c986b8240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 11:08:05 +0200 Subject: [PATCH 058/208] #1010: improve filter-stringify logic to handle Value=false/undefined --- test/resourceFactory.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/resourceFactory.js b/test/resourceFactory.js index e9176ab6a..a8100c963 100644 --- a/test/resourceFactory.js +++ b/test/resourceFactory.js @@ -60,14 +60,18 @@ exports.filterToPath = (filter) => { return ''; }; exports._filterToPath = (filter) => { - if (filter.Property && filter.SimpleOperator && filter.Value) { - return `${filter.Property}${filter.SimpleOperator.replace('equals', '=')}${filter.Value}`; + if (filter.Property && filter.SimpleOperator) { + return `${filter.Property}${filter.SimpleOperator.replace('equals', '=')}${ + filter.Value === undefined ? '' : filter.Value + }`; } else if (filter.LeftOperand && filter.LogicalOperator && filter.RightOperand) { return ( this._filterToPath(filter.LeftOperand) + filter.LogicalOperator + this._filterToPath(filter.RightOperand) ); + } else { + throw new Error('unknown filter type'); } }; /** From 4b619e336335ea7652b59087da418f3577e29e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 11:12:30 +0200 Subject: [PATCH 059/208] #1010: allow pending mocha tests --- .eslintrc.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 3636f6eb4..e95ead59b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,8 +1,7 @@ { "env": { "es6": true, - "node": true, - "mocha": true + "node": true }, "extends": [ "eslint:recommended", @@ -67,7 +66,6 @@ "unicorn/prefer-set-has": "off", "unicorn/prefer-spread": "off", "unicorn/prefer-string-replace-all": "error", - "unicorn/unicorn/no-lonely-if": "off", "arrow-body-style": ["error", "as-needed"], "curly": "error", "no-console": "error", @@ -104,7 +102,8 @@ "extends": ["plugin:mocha/recommended"], "plugins": ["mocha"], "rules": { - "mocha/no-mocha-arrows": "off" + "mocha/no-mocha-arrows": "off", + "mocha/no-pending-tests": "off" } } ] From 7a187412829e128491b1f6ad08afd09aec464c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 11:36:25 +0200 Subject: [PATCH 060/208] #1010: make automation test more specific --- ...ect=falseANDDescriptionnotEqualsSFSendDefinition-response.xml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/resources/9999999/emailSendDefinition/{retrieve-response.xml => retrieve-IsPlatformObject=falseANDDescriptionnotEqualsSFSendDefinition-response.xml} (100%) diff --git a/test/resources/9999999/emailSendDefinition/retrieve-response.xml b/test/resources/9999999/emailSendDefinition/retrieve-IsPlatformObject=falseANDDescriptionnotEqualsSFSendDefinition-response.xml similarity index 100% rename from test/resources/9999999/emailSendDefinition/retrieve-response.xml rename to test/resources/9999999/emailSendDefinition/retrieve-IsPlatformObject=falseANDDescriptionnotEqualsSFSendDefinition-response.xml From 3b07393bedb15a507c1187c4c597b3b551fe6df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 11:47:35 +0200 Subject: [PATCH 061/208] #1010: make dataExtension tests more specific --- ...me=testExisting_dataExtension-response.xml | 52 ++++++++++ ...ey=testExisting_dataExtension-response.xml | 98 ++++++++++++++++++ ...ey=testExisting_dataExtension-response.xml | 99 +++++++++++++++++++ 3 files changed, 249 insertions(+) create mode 100644 test/resources/9999999/dataExtension/retrieve-Name=testExisting_dataExtension-response.xml create mode 100644 test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtension-response.xml create mode 100644 test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionORDataExtension.CustomerKey=testExisting_dataExtension-response.xml diff --git a/test/resources/9999999/dataExtension/retrieve-Name=testExisting_dataExtension-response.xml b/test/resources/9999999/dataExtension/retrieve-Name=testExisting_dataExtension-response.xml new file mode 100644 index 000000000..e7cf0d2ef --- /dev/null +++ b/test/resources/9999999/dataExtension/retrieve-Name=testExisting_dataExtension-response.xml @@ -0,0 +1,52 @@ + + + + RetrieveResponse + urn:uuid:c198cc12-c34c-4d1d-90b0-5b785a342efc + urn:uuid:a0506b59-1847-4405-8231-6a15e26bbcc9 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2022-04-21T19:21:50Z + 2022-04-21T19:26:50Z + + + + + + OK + d175de6e-c8e4-4f5d-9c1d-ad64426ff4b7 + + + 2022-04-21T06:56:27.927 + 2022-04-21T06:56:27.927 + 21711373-72c1-ec11-b83b-48df37d1deb7 + testExisting_dataExtension + testExisting_dataExtension + bla bla + true + true + + + + ContactKey + + + _SubscriberKey + + 6 + 5 + true + false + false + + 2 + + + + \ No newline at end of file diff --git a/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtension-response.xml b/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtension-response.xml new file mode 100644 index 000000000..3ffc1b3eb --- /dev/null +++ b/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testExisting_dataExtension-response.xml @@ -0,0 +1,98 @@ + + + + RetrieveResponse + urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d + urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2022-04-21T19:21:52Z + 2022-04-21T19:26:52Z + + + + + + OK + cfe51e71-6a2b-4cb4-aecd-3777076d63bc + + + 8018397d-880d-4f88-940e-3b4eca098a0c + [testExisting_dataExtension].[ContactKey] + ContactKey + 0 + + 50 + true + 3 + true + Text + + + + testExisting_dataExtension + + + + + bea0e308-5d45-4181-a673-da9972a7c674 + [testExisting_dataExtension].[LastName] + LastName + 0 + + 50 + false + 1 + false + Text + + + + testExisting_dataExtension + + + + + 2557b461-a699-4744-950d-e80a19afc2dc + [testExisting_dataExtension].[EmailAddress] + EmailAddress + 0 + + 254 + true + 2 + false + EmailAddress + + + + testExisting_dataExtension + + + + + 42760528-a8c5-44dd-8c1d-ff34e5daee54 + [testExisting_dataExtension].[FirstName] + FirstName + 0 + + 50 + false + 0 + false + Text + + + + testExisting_dataExtension + + + + + \ No newline at end of file diff --git a/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionORDataExtension.CustomerKey=testExisting_dataExtension-response.xml b/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionORDataExtension.CustomerKey=testExisting_dataExtension-response.xml new file mode 100644 index 000000000..8018e9949 --- /dev/null +++ b/test/resources/9999999/dataExtensionField/retrieve-DataExtension.CustomerKey=testNew_dataExtensionORDataExtension.CustomerKey=testExisting_dataExtension-response.xml @@ -0,0 +1,99 @@ + + + + + RetrieveResponse + urn:uuid:6d2f81c8-80ab-44d5-8664-206753e7ac8d + urn:uuid:a7354389-079e-4844-93b5-af6b7bf1d535 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2022-04-21T19:21:52Z + 2022-04-21T19:26:52Z + + + + + + OK + cfe51e71-6a2b-4cb4-aecd-3777076d63bc + + + 8018397d-880d-4f88-940e-3b4eca098a0c + [testExisting_dataExtension].[ContactKey] + ContactKey + 0 + + 50 + true + 3 + true + Text + + + + testExisting_dataExtension + + + + + bea0e308-5d45-4181-a673-da9972a7c674 + [testExisting_dataExtension].[LastName] + LastName + 0 + + 50 + false + 1 + false + Text + + + + testExisting_dataExtension + + + + + 2557b461-a699-4744-950d-e80a19afc2dc + [testExisting_dataExtension].[EmailAddress] + EmailAddress + 0 + + 254 + true + 2 + false + EmailAddress + + + + testExisting_dataExtension + + + + + 42760528-a8c5-44dd-8c1d-ff34e5daee54 + [testExisting_dataExtension].[FirstName] + FirstName + 0 + + 50 + false + 0 + false + Text + + + + testExisting_dataExtension + + + + + \ No newline at end of file From 1ffa647425f38f072721db73c5aaf49654dfb323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 11:50:03 +0200 Subject: [PATCH 062/208] #1010: make journey tests more specific --- ...edSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/resources/9999999/triggeredSendDefinition/{retrieve-response.xml => retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml} (100%) diff --git a/test/resources/9999999/triggeredSendDefinition/retrieve-response.xml b/test/resources/9999999/triggeredSendDefinition/retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml similarity index 100% rename from test/resources/9999999/triggeredSendDefinition/retrieve-response.xml rename to test/resources/9999999/triggeredSendDefinition/retrieve-TriggeredSendStatusINNew,Active,Inactive,Moved,Canceled-response.xml From 52448e5eb7b8af71b4e009d2c21d416202ae5b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 11:56:14 +0200 Subject: [PATCH 063/208] #1010: make transactionalEmail tests more specific --- .../{retrieve-response.xml => retrieve-ID=1111111-response.xml} | 0 ...merKey=All SubscribersORListName=All Subscribers-response.xml} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test/resources/1111111/businessUnit/{retrieve-response.xml => retrieve-ID=1111111-response.xml} (100%) rename test/resources/1111111/list/{retrieve-response.xml => retrieve-CustomerKey=All SubscribersORListName=All Subscribers-response.xml} (100%) diff --git a/test/resources/1111111/businessUnit/retrieve-response.xml b/test/resources/1111111/businessUnit/retrieve-ID=1111111-response.xml similarity index 100% rename from test/resources/1111111/businessUnit/retrieve-response.xml rename to test/resources/1111111/businessUnit/retrieve-ID=1111111-response.xml diff --git a/test/resources/1111111/list/retrieve-response.xml b/test/resources/1111111/list/retrieve-CustomerKey=All SubscribersORListName=All Subscribers-response.xml similarity index 100% rename from test/resources/1111111/list/retrieve-response.xml rename to test/resources/1111111/list/retrieve-CustomerKey=All SubscribersORListName=All Subscribers-response.xml From 822864fe4b5a5515c7133d9b5d14c64f573c3c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 13:33:34 +0200 Subject: [PATCH 064/208] #1010: make user tests more specific --- ...estExisting_userANDEmaillike@-response.xml | 27 +++ ...ActiveFlag=falseANDEmaillike@-response.xml | 156 ++++++++++++++++++ ...stExisting_userANDEmaillike@-response.xml} | 0 ...erANDMustChangePassword=false-response.xml | 27 +++ ...-ActiveFlag=trueANDEmaillike@-response.xml | 156 ++++++++++++++++++ ...erANDMustChangePassword=false-response.xml | 27 +++ ...tUser.AccountUserID=700301950-response.xml | 60 +++++++ ...tUserIDIN700301950,700301951-response.xml} | 0 ... => retrieve-IsPrivate=false-response.xml} | 0 .../1111111/user/retrieve-expected.md | 3 +- test/type.user.test.js | 26 ++- 11 files changed, 472 insertions(+), 10 deletions(-) create mode 100644 test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDCustomerKey=testExisting_userANDEmaillike@-response.xml create mode 100644 test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDEmaillike@-response.xml rename test/resources/1111111/accountUser/{retrieve-response.xml => retrieve-ActiveFlag=trueANDCustomerKey=testExisting_userANDEmaillike@-response.xml} (100%) create mode 100644 test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml create mode 100644 test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmaillike@-response.xml create mode 100644 test/resources/1111111/accountUser/retrieve-CustomerKey=testExisting_userANDActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml create mode 100644 test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserID=700301950-response.xml rename test/resources/1111111/accountUserAccount/{retrieve-response.xml => retrieve-AccountUser.AccountUserIDIN700301950,700301951-response.xml} (100%) rename test/resources/1111111/role/{retrieve-response.xml => retrieve-IsPrivate=false-response.xml} (100%) diff --git a/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDCustomerKey=testExisting_userANDEmaillike@-response.xml b/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDCustomerKey=testExisting_userANDEmaillike@-response.xml new file mode 100644 index 000000000..af1dec2e2 --- /dev/null +++ b/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDCustomerKey=testExisting_userANDEmaillike@-response.xml @@ -0,0 +1,27 @@ + + + + RetrieveResponse + urn:uuid:1babdae0-9282-4bba-b69f-2f1843deaf11 + urn:uuid:39d1c021-b3df-49f9-a8f7-bb444172d2d3 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-03-11T13:53:00Z + 2023-03-11T13:58:00Z + + + + + + OK + 5347bf1d-e801-486a-b4a9-c2d46a8909b6 + + + + \ No newline at end of file diff --git a/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDEmaillike@-response.xml b/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDEmaillike@-response.xml new file mode 100644 index 000000000..22ee9fd1e --- /dev/null +++ b/test/resources/1111111/accountUser/retrieve-ActiveFlag=falseANDEmaillike@-response.xml @@ -0,0 +1,156 @@ + + + + RetrieveResponse + urn:uuid:1babdae0-9282-4bba-b69f-2f1843deaf11 + urn:uuid:39d1c021-b3df-49f9-a8f7-bb444172d2d3 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-03-11T13:53:00Z + 2023-03-11T13:58:00Z + + + + + + OK + 5347bf1d-e801-486a-b4a9-c2d46a8909b6 + + + 1111111 + 123456 + + + 2019-09-06T01:59:07.097 + 2022-06-21T01:43:02.64 + 700301951 + + testExisting_user_inactive + 700301951 + user_test-inactive@accenture.asgr + user test-inactive + user_test-inactive@accenture.com + false + false + + + 2 + + + + + 0 + + + + 3 + + + + + 0 + + 0 + 2023-02-23T10:14:11.443 + false + user_test-inactive@accenture.com + false + 1111111 + + + 1111111 + + None + + + + + + en-GB + + + + 5 + + (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna * + + + + + 1111111 + -1000 + -1000 + 1111111 + + + 2016-07-22T17:52:36.93 + 2016-07-22T17:52:36.93 + f1cfb80f-3550-e611-96fe-38eaa7142c61 + SYS_DEF_ADMIN + Administrator + Administrator + false + true + + + + 1111111 + -1000 + -1000 + 1111111 + + + 2016-07-22T17:52:36.93 + 2016-07-22T17:52:36.93 + f4cfb80f-3550-e611-96fe-38eaa7142c61 + SYS_DEF_CONTENT + Content Creator + Content Creator + false + true + + + + 1111111 + -1000 + -1000 + 1111111 + + + 2019-09-06T07:59:07.8 + 2019-09-06T07:59:07.8 + bd251431-7cd0-e911-a2d3-1402ec936979 + Individual role for 700301951 + Individual role for 700301951 + Individual role for 700301951 + true + false + + + + 0 + 0 + 0 + 0 + + + 2012-02-21T02:09:19.983 + 2013-12-23T16:48:50.533 + 63a50610-315c-e111-beee-8e001800001f + SYS_DEF_IMHADMIN + Marketing Cloud Administrator + Assign Marketing Cloud roles to users and manage Mobile, Social and Sites Channels, Hub Apps and Marketing Cloud Tools + false + true + + + + + + \ No newline at end of file diff --git a/test/resources/1111111/accountUser/retrieve-response.xml b/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDCustomerKey=testExisting_userANDEmaillike@-response.xml similarity index 100% rename from test/resources/1111111/accountUser/retrieve-response.xml rename to test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDCustomerKey=testExisting_userANDEmaillike@-response.xml diff --git a/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml b/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml new file mode 100644 index 000000000..af1dec2e2 --- /dev/null +++ b/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml @@ -0,0 +1,27 @@ + + + + RetrieveResponse + urn:uuid:1babdae0-9282-4bba-b69f-2f1843deaf11 + urn:uuid:39d1c021-b3df-49f9-a8f7-bb444172d2d3 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-03-11T13:53:00Z + 2023-03-11T13:58:00Z + + + + + + OK + 5347bf1d-e801-486a-b4a9-c2d46a8909b6 + + + + \ No newline at end of file diff --git a/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmaillike@-response.xml b/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmaillike@-response.xml new file mode 100644 index 000000000..e16046c89 --- /dev/null +++ b/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmaillike@-response.xml @@ -0,0 +1,156 @@ + + + + RetrieveResponse + urn:uuid:1babdae0-9282-4bba-b69f-2f1843deaf11 + urn:uuid:39d1c021-b3df-49f9-a8f7-bb444172d2d3 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-03-11T13:53:00Z + 2023-03-11T13:58:00Z + + + + + + OK + 5347bf1d-e801-486a-b4a9-c2d46a8909b6 + + + 1111111 + 123456 + + + 2019-09-06T01:59:07.097 + 2022-06-21T01:43:02.64 + 700301950 + + testExisting_user + 700301950 + user_test@accenture.asgr + user test + user_test@accenture.com + false + true + + + 2 + + + + + 0 + + + + 3 + + + + + 0 + + 0 + 2023-02-23T10:14:11.443 + false + user_test@accenture.com + false + 1111111 + + + 1111111 + + None + + + + + + en-GB + + + + 5 + + (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna * + + + + + 1111111 + -1000 + -1000 + 1111111 + + + 2016-07-22T17:52:36.93 + 2016-07-22T17:52:36.93 + f1cfb80f-3550-e611-96fe-38eaa7142c61 + SYS_DEF_ADMIN + Administrator + Administrator + false + true + + + + 1111111 + -1000 + -1000 + 1111111 + + + 2016-07-22T17:52:36.93 + 2016-07-22T17:52:36.93 + f4cfb80f-3550-e611-96fe-38eaa7142c61 + SYS_DEF_CONTENT + Content Creator + Content Creator + false + true + + + + 1111111 + -1000 + -1000 + 1111111 + + + 2019-09-06T07:59:07.8 + 2019-09-06T07:59:07.8 + bd251431-7cd0-e911-a2d3-1402ec936979 + Individual role for 700301950 + Individual role for 700301950 + Individual role for 700301950 + true + false + + + + 0 + 0 + 0 + 0 + + + 2012-02-21T02:09:19.983 + 2013-12-23T16:48:50.533 + 63a50610-315c-e111-beee-8e001800001f + SYS_DEF_IMHADMIN + Marketing Cloud Administrator + Assign Marketing Cloud roles to users and manage Mobile, Social and Sites Channels, Hub Apps and Marketing Cloud Tools + false + true + + + + + + \ No newline at end of file diff --git a/test/resources/1111111/accountUser/retrieve-CustomerKey=testExisting_userANDActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml b/test/resources/1111111/accountUser/retrieve-CustomerKey=testExisting_userANDActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml new file mode 100644 index 000000000..af1dec2e2 --- /dev/null +++ b/test/resources/1111111/accountUser/retrieve-CustomerKey=testExisting_userANDActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml @@ -0,0 +1,27 @@ + + + + RetrieveResponse + urn:uuid:1babdae0-9282-4bba-b69f-2f1843deaf11 + urn:uuid:39d1c021-b3df-49f9-a8f7-bb444172d2d3 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-03-11T13:53:00Z + 2023-03-11T13:58:00Z + + + + + + OK + 5347bf1d-e801-486a-b4a9-c2d46a8909b6 + + + + \ No newline at end of file diff --git a/test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserID=700301950-response.xml b/test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserID=700301950-response.xml new file mode 100644 index 000000000..29e5e4173 --- /dev/null +++ b/test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserID=700301950-response.xml @@ -0,0 +1,60 @@ + + + + RetrieveResponse + urn:uuid:b9fbc10c-2775-48d0-b9bb-fddf1ed90616 + urn:uuid:11d44cfe-e1d7-4fc2-b6ad-a2c806573859 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-03-11T13:52:52Z + 2023-03-11T13:57:52Z + + + + + + OK + f4057c93-40e3-47d6-a953-06839e221d40 + + + + + + + 700301950 + 0 + + + + 1111111 + + None + + + + + + + + + + 700301950 + 0 + + + + 9999999 + + None + + + + + + \ No newline at end of file diff --git a/test/resources/1111111/accountUserAccount/retrieve-response.xml b/test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserIDIN700301950,700301951-response.xml similarity index 100% rename from test/resources/1111111/accountUserAccount/retrieve-response.xml rename to test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserIDIN700301950,700301951-response.xml diff --git a/test/resources/1111111/role/retrieve-response.xml b/test/resources/1111111/role/retrieve-IsPrivate=false-response.xml similarity index 100% rename from test/resources/1111111/role/retrieve-response.xml rename to test/resources/1111111/role/retrieve-IsPrivate=false-response.xml diff --git a/test/resources/1111111/user/retrieve-expected.md b/test/resources/1111111/user/retrieve-expected.md index 50eb1b2ec..a9e5a5756 100644 --- a/test/resources/1111111/user/retrieve-expected.md +++ b/test/resources/1111111/user/retrieve-expected.md @@ -7,10 +7,11 @@ | user test | 96 days | ✓ | - | - | - | _ParentBU_ (1111111) | _ParentBU_ (1111111),
testBU (9999999) | Administrator,
Content Creator,
Marketing Cloud Administrator | user_test@accenture.asgr | 700301950 | testExisting_user | user_test@accenture.com | user_test@accenture.com | GMT+01:00 | en-GB | 2022-06-21 01:43:02.64 | 123456 | 2019-09-06 01:59:07.097 | -## Inactivated Users (0) +## Inactivated Users (1) | Name | Last successful Login | Active | Access Locked out | API User | Must change PW | Default BU | BU Access | Roles | Login | ID | Key | E-Mail | Notification E-Mail | Timezone | SFMC Locale | Modified Date | Modified By | Created Date | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| user test-inactive | 96 days | - | - | - | - | _ParentBU_ (1111111) | _ParentBU_ (1111111) | Administrator,
Content Creator,
Marketing Cloud Administrator | user_test-inactive@accenture.asgr | 700301951 | testExisting_user_inactive | user_test-inactive@accenture.com | user_test-inactive@accenture.com | GMT+01:00 | en-GB | 2022-06-21 01:43:02.64 | 123456 | 2019-09-06 01:59:07.097 | ## Installed Packages (0) diff --git a/test/type.user.test.js b/test/type.user.test.js index 810164a60..4a6686312 100644 --- a/test/type.user.test.js +++ b/test/type.user.test.js @@ -26,8 +26,8 @@ describe('type: user', () => { const result = cache.getCache(); assert.equal( result.user ? Object.keys(result.user).length : 0, - 1, - 'only one user expected' + 2, + 'only two users expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_user', 'user', '_ParentBU_'), @@ -42,7 +42,7 @@ describe('type: user', () => { { encoding: 'utf8' } ); const regexFindDaysSinceLogin = - /\| (\d*) (seconds|minutes|days|weeks|months|years){1} \|/gm; + /\| (\d*) (seconds|minutes|days|weeks|months|years){1} \|/g; // fetch expected time since last login const expectedDaysSinceLogin = expectedFile.match(regexFindDaysSinceLogin); // load actual file and replace days since last login with expected value @@ -50,7 +50,7 @@ describe('type: user', () => { await File.readFile(`./docs/user/testInstance.users.md`, { encoding: 'utf8', }) - ).replaceAll(regexFindDaysSinceLogin, expectedDaysSinceLogin); + ).replaceAll(regexFindDaysSinceLogin, [expectedDaysSinceLogin[0]]); expect(actualFile).to.equal(expectedFile); assert.equal( @@ -83,7 +83,11 @@ describe('type: user', () => { }); it('Should create & upsert a user', async () => { // WHEN - const expectedCache = ['testExisting_user', 'testNew_user']; + const expectedCache = [ + 'testExisting_user', + 'testExisting_user_inactive', + 'testNew_user', + ]; await handler.deploy('testInstance/_ParentBU_', ['user'], expectedCache); // THEN assert.equal(process.exitCode, false, 'deploy should not have thrown an error'); @@ -92,8 +96,8 @@ describe('type: user', () => { const result = cache.getCache(); assert.equal( result.user ? Object.keys(result.user).length : 0, - 2, - 'two users expected' + 3, + 'three users expected' ); // confirm if result.user only includes values from expectedCache assert.deepEqual( @@ -126,14 +130,18 @@ describe('type: user', () => { }); it('Should not deploy user with Marketing Cloud role', async () => { // WHEN - const expectedCache = ['testExisting_user']; + const expectedCache = ['testExisting_user', 'testExisting_user_inactive']; await handler.deploy('testInstance/_ParentBU_', ['user'], ['testBlocked_user']); // THEN assert.equal(process.exitCode, 1, 'Deployment should have thrown an error'); // get results from cache const result = cache.getCache(); - assert.equal(result.user ? Object.keys(result.user).length : 0, 1, '1 user expected'); + assert.equal( + result.user ? Object.keys(result.user).length : 0, + 2, + 'two users expected' + ); // confirm if result.user only includes values from expectedCache assert.deepEqual( Object.keys(result.user), From 22de4fa892676ec06d2190baebf8645569270592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 13:44:34 +0200 Subject: [PATCH 065/208] #1010: added installed package to test for type user --- ...erANDMustChangePassword=false-response.xml | 62 ++++++++++++++++++- ...N700301950,700301951,7471228-response.xml} | 0 .../1111111/user/retrieve-expected.md | 3 +- test/type.user.test.js | 19 +++--- 4 files changed, 75 insertions(+), 9 deletions(-) rename test/resources/1111111/accountUserAccount/{retrieve-AccountUser.AccountUserIDIN700301950,700301951-response.xml => retrieve-AccountUser.AccountUserIDIN700301950,700301951,7471228-response.xml} (100%) diff --git a/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml b/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml index af1dec2e2..5ac4001a5 100644 --- a/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml +++ b/test/resources/1111111/accountUser/retrieve-ActiveFlag=trueANDEmailisNullORNamelikeapp userANDMustChangePassword=false-response.xml @@ -21,7 +21,67 @@ OK 5347bf1d-e801-486a-b4a9-c2d46a8909b6 - + + + 1111111 + 0 + + + 2016-07-22T11:52:37.42 + 2023-05-27T07:05:55.113 + 7471228 + + 45372cbb-06e0-438e-88d8-008981f7a18b + 7471228 + 20f2d94a-9a7d-4580-9fb6-c36a1ce32fb9 + igopredictiveemail app user + + false + true + 0 + + true + + false + 1111111 + + + + en-GB + + + + 5 + + (GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna + + + + 1111111 + + None + + + + + + 1111111 + 0 + 0 + 1111111 + + + 2016-07-22T17:52:37.88 + 2016-07-22T17:52:37.88 + 44d0b80f-3550-e611-96fe-38eaa7142c61 + Individual role for 7471228 + Individual role for 7471228 + Individual role for 7471228 + true + false + + + \ No newline at end of file diff --git a/test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserIDIN700301950,700301951-response.xml b/test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserIDIN700301950,700301951,7471228-response.xml similarity index 100% rename from test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserIDIN700301950,700301951-response.xml rename to test/resources/1111111/accountUserAccount/retrieve-AccountUser.AccountUserIDIN700301950,700301951,7471228-response.xml diff --git a/test/resources/1111111/user/retrieve-expected.md b/test/resources/1111111/user/retrieve-expected.md index a9e5a5756..acc1becbd 100644 --- a/test/resources/1111111/user/retrieve-expected.md +++ b/test/resources/1111111/user/retrieve-expected.md @@ -14,7 +14,8 @@ | user test-inactive | 96 days | - | - | - | - | _ParentBU_ (1111111) | _ParentBU_ (1111111) | Administrator,
Content Creator,
Marketing Cloud Administrator | user_test-inactive@accenture.asgr | 700301951 | testExisting_user_inactive | user_test-inactive@accenture.com | user_test-inactive@accenture.com | GMT+01:00 | en-GB | 2022-06-21 01:43:02.64 | 123456 | 2019-09-06 01:59:07.097 | -## Installed Packages (0) +## Installed Packages (1) | Name | Last successful Login | Active | Access Locked out | API User | Must change PW | Default BU | BU Access | Roles | Login | ID | Key | E-Mail | Notification E-Mail | Timezone | SFMC Locale | Modified Date | Modified By | Created Date | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| igopredictiveemail app user | never | ✓ | - | ✓ | - | _ParentBU_ (1111111) | _ParentBU_ (1111111) | | 20f2d94a-9a7d-4580-9fb6-c36a1ce32fb9 | 7471228 | 45372cbb-06e0-438e-88d8-008981f7a18b | | | GMT+01:00 | en-GB | 2023-05-27 07:05:55.113 | n/a | 2016-07-22 11:52:37.42 | diff --git a/test/type.user.test.js b/test/type.user.test.js index 4a6686312..18fc252ba 100644 --- a/test/type.user.test.js +++ b/test/type.user.test.js @@ -26,8 +26,8 @@ describe('type: user', () => { const result = cache.getCache(); assert.equal( result.user ? Object.keys(result.user).length : 0, - 2, - 'only two users expected' + 3, + 'only three users expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_user', 'user', '_ParentBU_'), @@ -86,6 +86,7 @@ describe('type: user', () => { const expectedCache = [ 'testExisting_user', 'testExisting_user_inactive', + '45372cbb-06e0-438e-88d8-008981f7a18b', 'testNew_user', ]; await handler.deploy('testInstance/_ParentBU_', ['user'], expectedCache); @@ -96,8 +97,8 @@ describe('type: user', () => { const result = cache.getCache(); assert.equal( result.user ? Object.keys(result.user).length : 0, - 3, - 'three users expected' + 4, + 'four users expected' ); // confirm if result.user only includes values from expectedCache assert.deepEqual( @@ -130,7 +131,11 @@ describe('type: user', () => { }); it('Should not deploy user with Marketing Cloud role', async () => { // WHEN - const expectedCache = ['testExisting_user', 'testExisting_user_inactive']; + const expectedCache = [ + 'testExisting_user', + 'testExisting_user_inactive', + '45372cbb-06e0-438e-88d8-008981f7a18b', + ]; await handler.deploy('testInstance/_ParentBU_', ['user'], ['testBlocked_user']); // THEN assert.equal(process.exitCode, 1, 'Deployment should have thrown an error'); @@ -139,8 +144,8 @@ describe('type: user', () => { const result = cache.getCache(); assert.equal( result.user ? Object.keys(result.user).length : 0, - 2, - 'two users expected' + 3, + 'three users expected' ); // confirm if result.user only includes values from expectedCache assert.deepEqual( From 1cccdd85ec2e2733d4cf0c00d5fb2e394b6a27f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 14:04:18 +0200 Subject: [PATCH 066/208] #1012: fix potential security issue regarding passwords in log files --- lib/metadataTypes/User.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/metadataTypes/User.js b/lib/metadataTypes/User.js index 77c5e21c7..28e942215 100644 --- a/lib/metadataTypes/User.js +++ b/lib/metadataTypes/User.js @@ -404,8 +404,11 @@ class User extends MetadataType { if (!metadata.Password) { metadata.Password = this._generatePassword(); Util.logger.info( - ` - Password for ${metadata.UserID} was not given. Generated password: ${metadata.Password}` + ` - Password for ${metadata.UserID} was not given. Generated password:` ); + // use console.log here to print the generated password to bypass the logfile + // eslint-disable-next-line no-console + console.log(metadata.Password); } } From f3ef481a544fc778d87556d4f628cb9217941f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 15:41:12 +0200 Subject: [PATCH 067/208] #870: first attempt for scheduling automations via execute - still bad api response --- docs/dist/documentation.md | 46 +++++++++- lib/index.js | 3 + lib/metadataTypes/Automation.js | 148 ++++++++++++++++++++++++-------- 3 files changed, 157 insertions(+), 40 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 82eedc210..98c0bca4c 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -186,11 +186,17 @@ Provides default functionality that can be overwritten by child metadata type cl
csvToArray(csv)Array.<string>

helper to convert CSVs into an array. if only one value was given, it's also returned as an array

+
Automation.(metadata)boolean
+

helper for postRetrieveTasks and execute

+
+
Automation.(metadata)
+

helper for preDeployTasks and execute

+
Automation.(metadataMap, key)Promise.<void>

helper for postDeployTasks

Automation.(metadataMap, originalMetadataMap, key)
-

helper for postDeployTasks

+

helper for postDeployTasks

getUserName(userList, item, fieldname)string
@@ -1250,6 +1256,7 @@ Automation MetadataType * [.retrieveForCache()](#Automation.retrieveForCache) ⇒ Promise.<TYPE.AutomationMapObj> * [.retrieveAsTemplate(templateDir, name, templateVariables)](#Automation.retrieveAsTemplate) ⇒ Promise.<TYPE.AutomationItemObj> * [.postRetrieveTasks(metadata)](#Automation.postRetrieveTasks) ⇒ TYPE.AutomationItem \| void + * [.execute(keyArr)](#Automation.execute) ⇒ Promise.<boolean> * [.deploy(metadata, targetBU, retrieveDir)](#Automation.deploy) ⇒ Promise.<TYPE.AutomationMap> * [.create(metadata)](#Automation.create) ⇒ Promise * [.update(metadata, metadataBefore)](#Automation.update) ⇒ Promise @@ -1320,6 +1327,18 @@ manages post retrieve steps | --- | --- | --- | | metadata | TYPE.AutomationItem | a single automation | + + +### Automation.execute(keyArr) ⇒ Promise.<boolean> +a function to start query execution via API + +**Kind**: static method of [Automation](#Automation) +**Returns**: Promise.<boolean> - Returns true if all items were executed successfully, otherwise false + +| Param | Type | Description | +| --- | --- | --- | +| keyArr | Array.<string> | customerkey of the metadata | + ### Automation.deploy(metadata, targetBU, retrieveDir) ⇒ Promise.<TYPE.AutomationMap> @@ -8222,6 +8241,29 @@ helper to convert CSVs into an array. if only one value was given, it's also ret +## Automation.(metadata) ⇒ boolean +helper for [postRetrieveTasks](#Automation.postRetrieveTasks) and [execute](#Automation.execute) + +**Kind**: global function +**Returns**: boolean - true if the automation schedule is valid + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.AutomationItem | a single automation | + + + +## Automation.(metadata) +helper for [preDeployTasks](#Automation.preDeployTasks) and [execute](#Automation.execute) + +**Kind**: global function + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.AutomationItem | metadata mapped by their keyField | + + + ## Automation.(metadataMap, key) ⇒ Promise.<void> helper for [postDeployTasks](#Automation.postDeployTasks) @@ -8236,7 +8278,7 @@ helper for [postDeployTasks](#Automation.postDeployTasks) ## Automation.(metadataMap, originalMetadataMap, key) -helper for [postDeployTasks](postDeployTasks) +helper for [postDeployTasks](#Automation.postDeployTasks) **Kind**: global function diff --git a/lib/index.js b/lib/index.js index 5928a854e..68a0ffd39 100644 --- a/lib/index.js +++ b/lib/index.js @@ -843,6 +843,9 @@ class Mcdev { MetadataTypeInfo[type].client = auth.getSDK(buObject); if (Util.OPTIONS.like && Object.keys(Util.OPTIONS.like).length) { keyArr = await this._retrieveKeysWithLike(type, buObject); + } else { + MetadataTypeInfo[type].properties = properties; + MetadataTypeInfo[type].buObject = buObject; } if (!keyArr || (Array.isArray(keyArr) && !keyArr.length)) { throw new Error('No keys were provided'); diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index b2aaefa01..af30f0a4e 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -318,6 +318,40 @@ class Automation extends MetadataType { throw new Error(JSON.stringify(results)); } } + /** + * helper for {@link Automation.postRetrieveTasks} and {@link Automation.execute} + * + * @param {TYPE.AutomationItem} metadata a single automation + * @returns {boolean} true if the automation schedule is valid + */ + static #isValidSchedule(metadata) { + if (metadata.type === 'scheduled' && metadata.schedule?.startDate) { + try { + if (this.definition.timeZoneMapping[metadata.schedule.timezoneName]) { + // if we found the id in our list, remove the redundant data + delete metadata.schedule.timezoneId; + } + } catch { + Util.logger.debug( + `- Schedule name '${metadata.schedule.timezoneName}' not found in definition.timeZoneMapping` + ); + } + try { + // type 'Running' is temporary status only, overwrite with Scheduled for storage. + if (metadata.type === 'scheduled' && metadata.status === 'Running') { + metadata.status = 'Scheduled'; + } + } catch { + Util.logger.error( + ` - ${this.definition.type} ${metadata.name} does not have a valid schedule setting.` + ); + return false; + } + return true; + } else { + return false; + } + } /** * manages post retrieve steps * @@ -332,25 +366,7 @@ class Automation extends MetadataType { if (metadata.type === 'scheduled' && metadata.schedule?.startDate) { // Starting Source == 'Schedule' - try { - if (this.definition.timeZoneMapping[metadata.schedule.timezoneName]) { - // if we found the id in our list, remove the redundant data - delete metadata.schedule.timezoneId; - } - } catch { - Util.logger.debug( - `- Schedule name '${metadata.schedule.timezoneName}' not found in definition.timeZoneMapping` - ); - } - try { - // type 'Running' is temporary status only, overwrite with Scheduled for storage. - if (metadata.type === 'scheduled' && metadata.status === 'Running') { - metadata.status = 'Scheduled'; - } - } catch { - Util.logger.error( - `- ${this.definition.type} ${metadata.name} does not have a valid schedule setting.` - ); + if (!this.#isValidSchedule(metadata)) { return; } } else if (metadata.type === 'triggered' && metadata.fileTrigger) { @@ -445,6 +461,51 @@ class Automation extends MetadataType { return null; } } + /** + * a function to start query execution via API + * + * @param {string[]} keyArr customerkey of the metadata + * @returns {Promise.} Returns true if all items were executed successfully, otherwise false + */ + static async execute(keyArr) { + const metadataMap = {}; + for (const key of keyArr) { + if (key) { + const results = await this.retrieve(undefined, undefined, undefined, key); + if (Object.keys(results.metadata).length) { + for (const key of Object.keys(results.metadata)) { + if (this.#isValidSchedule(results.metadata[key])) { + metadataMap[key] = results.metadata[key]; + } else { + Util.logger.error( + ` - skipping ${this.definition.type} ${results.metadata[key].name}: no valid schedule settings found.` + ); + } + } + } + } + } + + Util.logger.info( + `Starting automations according to schedule: ${Object.keys(metadataMap).length}` + ); + for (const key of Object.keys(metadataMap)) { + if (metadataMap[key].status === 'Scheduled') { + Util.logger.info( + ` - skipping ${this.definition.type} ${metadataMap[key].name}: already scheduled.` + ); + } else { + this.#preDeploySchedule(metadataMap[key]); + metadataMap[key].status = 'Scheduled'; + this.#scheduleAutomation(metadataMap, metadataMap, key); + } + } + // console.log('metadataMap', metadataMap); + + // const successCounter = (await Promise.all(results)).filter((r) => r === 'OK').length; + // Util.logger.info(`Executed ${successCounter} of ${keyArr.length} items`); + // return successCounter === keyArr.length; + } /** * Deploys automation - the saved file is the original one due to large differences required for deployment @@ -492,6 +553,33 @@ class Automation extends MetadataType { return super.updateREST(metadata, uri); } + /** + * helper for {@link Automation.preDeployTasks} and {@link Automation.execute} + * + * @param {TYPE.AutomationItem} metadata metadata mapped by their keyField + */ + static #preDeploySchedule(metadata) { + delete metadata.schedule.rangeTypeId; + delete metadata.schedule.pattern; + delete metadata.schedule.scheduledTime; + delete metadata.schedule.scheduledStatus; + if (this.definition.timeZoneMapping[metadata.schedule.timezoneName]) { + metadata.schedule.timezoneId = + this.definition.timeZoneMapping[metadata.schedule.timezoneName]; + } else { + Util.logger.error( + `Could not find timezone ${metadata.schedule.timezoneName} in definition.timeZoneMapping` + ); + } + + // the upsert API needs this to be named scheduleTypeId; the retrieve API returns it as typeId + metadata.schedule.scheduleTypeId = metadata.schedule.typeId; + delete metadata.schedule.typeId; + + // prep startSource + metadata.startSource = { schedule: metadata.schedule, typeId: 1 }; + } + /** * Gets executed before deploying metadata * @@ -515,25 +603,9 @@ class Automation extends MetadataType { if (metadata.type === 'scheduled' && metadata?.schedule?.startDate) { // Starting Source == 'Schedule' - delete metadata.schedule.rangeTypeId; - delete metadata.schedule.pattern; - delete metadata.schedule.scheduledTime; - delete metadata.schedule.scheduledStatus; - if (this.definition.timeZoneMapping[metadata.schedule.timezoneName]) { - metadata.schedule.timezoneId = - this.definition.timeZoneMapping[metadata.schedule.timezoneName]; - } else { - Util.logger.error( - `Could not find timezone ${metadata.schedule.timezoneName} in definition.timeZoneMapping` - ); - } + this.#preDeploySchedule(metadata); delete metadata.schedule.timezoneName; - // the upsert API needs this to be named scheduleTypeId; the retrieve API returns it as typeId - metadata.schedule.scheduleTypeId = metadata.schedule.typeId; - delete metadata.schedule.typeId; - - // prep startSource - metadata.startSource = { schedule: metadata.schedule, typeId: 1 }; + delete metadata.startSource.schedule.timezoneName; } else if (metadata.type === 'triggered' && metadata.fileTrigger) { // Starting Source == 'File Drop' @@ -705,7 +777,7 @@ class Automation extends MetadataType { } /** - * helper for {@link postDeployTasks} + * helper for {@link Automation.postDeployTasks} * * @param {TYPE.AutomationMap} metadataMap metadata mapped by their keyField * @param {TYPE.AutomationMap} originalMetadataMap metadata to be updated (contains additioanl fields) From 925a92d7cdf6b790ea45a9b73f03478c59d2efc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 30 Jun 2023 16:07:13 +0200 Subject: [PATCH 068/208] #0: prepping to remove schedule.typeId from retrieve --- .../definitions/Automation.definition.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/metadataTypes/definitions/Automation.definition.js b/lib/metadataTypes/definitions/Automation.definition.js index c7ab19a19..62808f0aa 100644 --- a/lib/metadataTypes/definitions/Automation.definition.js +++ b/lib/metadataTypes/definitions/Automation.definition.js @@ -48,6 +48,13 @@ module.exports = { lastmodNameField: 'lastSavedByName', restPagination: true, maxKeyLength: 200, // confirmed max length + scheduleTypeMapping: { + MINUTELY: 1, + HOURLY: 2, + DAILY: 3, + WEEKLY: 4, + MONTHLY: 5, + }, statusMapping: { AwaitingTrigger: 7, Building: 1, @@ -486,8 +493,8 @@ module.exports = { 'schedule.typeId': { isCreateable: true, isUpdateable: true, - retrieving: true, - template: true, + retrieving: false, + template: false, }, status: { isCreateable: true, From efb5c3dbfb74e8baa7f4bb015204f73817eafcf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 4 Jul 2023 10:37:01 +0200 Subject: [PATCH 069/208] #1018: add command "pause automation" --- docs/dist/documentation.md | 76 +++++++++++++++++++++++---- lib/cli.js | 33 +++++++++++- lib/index.js | 86 ++++++++++++++++++++----------- lib/metadataTypes/Automation.js | 85 ++++++++++++++++++++++++++++-- lib/metadataTypes/MetadataType.js | 13 ++++- 5 files changed, 246 insertions(+), 47 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 98c0bca4c..1b3d39169 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -189,13 +189,19 @@ Provides default functionality that can be overwritten by child metadata type cl
Automation.(metadata)boolean

helper for postRetrieveTasks and execute

+
Automation.(metadataMap, key)Promise.<object>
+

helper for execute

+
+
Automation.(metadata)Promise.<object>
+

helper for pause

+
Automation.(metadata)

helper for preDeployTasks and execute

Automation.(metadataMap, key)Promise.<void>

helper for postDeployTasks

-
Automation.(metadataMap, originalMetadataMap, key)
+
Automation.(metadataMap, originalMetadataMap, key)Promise.<object>

helper for postDeployTasks

getUserName(userList, item, fieldname)string
@@ -501,8 +507,8 @@ main class * [.buildDefinition(businessUnit, selectedType, name, market)](#Mcdev.buildDefinition) ⇒ Promise.<void> * [.buildDefinitionBulk(listName, type, name)](#Mcdev.buildDefinitionBulk) ⇒ Promise.<void> * [.getFilesToCommit(businessUnit, selectedType, keyArr)](#Mcdev.getFilesToCommit) ⇒ Promise.<Array.<string>> - * [.execute(businessUnit, [selectedType], [keys])](#Mcdev.execute) ⇒ Promise.<boolean> - * [._executeBU(cred, bu, [type], keyArr)](#Mcdev._executeBU) ⇒ Promise.<boolean> + * [.runMethod(methodName, businessUnit, [selectedType], [keys])](#Mcdev.runMethod) ⇒ Promise.<boolean> + * [._runOnBU(methodName, cred, bu, [type], keyArr)](#Mcdev._runOnBU) ⇒ Promise.<boolean> * [._retrieveKeysWithLike(selectedType, buObject)](#Mcdev._retrieveKeysWithLike) ⇒ Array.<string> @@ -756,9 +762,9 @@ Build a specific metadata file based on a template using a list of bu-market com | selectedType | string | supported metadata type | | keyArr | Array.<string> | customerkey of the metadata | - + -### Mcdev.execute(businessUnit, [selectedType], [keys]) ⇒ Promise.<boolean> +### Mcdev.runMethod(methodName, businessUnit, [selectedType], [keys]) ⇒ Promise.<boolean> Start an item (query) **Kind**: static method of [Mcdev](#Mcdev) @@ -766,20 +772,22 @@ Start an item (query) | Param | Type | Description | | --- | --- | --- | +| methodName | 'execute' \| 'pause' | what to run | | businessUnit | string | name of BU | | [selectedType] | TYPE.SupportedMetadataTypes | limit to given metadata types | | [keys] | Array.<string> | customerkey of the metadata | - + -### Mcdev.\_executeBU(cred, bu, [type], keyArr) ⇒ Promise.<boolean> -helper for [execute](#Mcdev.execute) +### Mcdev.\_runOnBU(methodName, cred, bu, [type], keyArr) ⇒ Promise.<boolean> +helper for [runMethod](#Mcdev.runMethod) **Kind**: static method of [Mcdev](#Mcdev) **Returns**: Promise.<boolean> - true if all items were executed, false otherwise | Param | Type | Description | | --- | --- | --- | +| methodName | 'execute' \| 'pause' | what to run | | cred | string | name of Credential | | bu | string | name of BU | | [type] | TYPE.SupportedMetadataTypes | limit execution to given metadata type | @@ -788,7 +796,7 @@ helper for [execute](#Mcdev.execute) ### Mcdev.\_retrieveKeysWithLike(selectedType, buObject) ⇒ Array.<string> -helper for [_executeBU](#Mcdev._executeBU) +helper for [_runOnBU](#Mcdev._runOnBU) **Kind**: static method of [Mcdev](#Mcdev) **Returns**: Array.<string> - keyArr @@ -1257,6 +1265,7 @@ Automation MetadataType * [.retrieveAsTemplate(templateDir, name, templateVariables)](#Automation.retrieveAsTemplate) ⇒ Promise.<TYPE.AutomationItemObj> * [.postRetrieveTasks(metadata)](#Automation.postRetrieveTasks) ⇒ TYPE.AutomationItem \| void * [.execute(keyArr)](#Automation.execute) ⇒ Promise.<boolean> + * [.pause(keyArr)](#Automation.pause) ⇒ Promise.<boolean> * [.deploy(metadata, targetBU, retrieveDir)](#Automation.deploy) ⇒ Promise.<TYPE.AutomationMap> * [.create(metadata)](#Automation.create) ⇒ Promise * [.update(metadata, metadataBefore)](#Automation.update) ⇒ Promise @@ -1339,6 +1348,18 @@ a function to start query execution via API | --- | --- | --- | | keyArr | Array.<string> | customerkey of the metadata | + + +### Automation.pause(keyArr) ⇒ Promise.<boolean> +a function to start query execution via API + +**Kind**: static method of [Automation](#Automation) +**Returns**: Promise.<boolean> - Returns true if all items were executed successfully, otherwise false + +| Param | Type | Description | +| --- | --- | --- | +| keyArr | Array.<string> | customerkey of the metadata | + ### Automation.deploy(metadata, targetBU, retrieveDir) ⇒ Promise.<TYPE.AutomationMap> @@ -3202,6 +3223,7 @@ Provides default functionality that can be overwritten by child metadata type cl * [.update(metadata, [metadataBefore])](#MetadataType.update) ⇒ void * [.refresh()](#MetadataType.refresh) ⇒ void * [.execute()](#MetadataType.execute) ⇒ void + * [.pause()](#MetadataType.pause) ⇒ void * [.hasChanged(cachedVersion, metadata, [fieldName])](#MetadataType.hasChanged) ⇒ boolean * [.hasChangedGeneric(cachedVersion, metadata, [fieldName], [silent])](#MetadataType.hasChangedGeneric) ⇒ boolean * [.upsert(metadataMap, deployDir)](#MetadataType.upsert) ⇒ Promise.<TYPE.MetadataTypeMap> @@ -3518,6 +3540,12 @@ Abstract refresh method that needs to be implemented in child metadata type ### MetadataType.execute() ⇒ void Abstract execute method that needs to be implemented in child metadata type +**Kind**: static method of [MetadataType](#MetadataType) + + +### MetadataType.pause() ⇒ void +Abstract pause method that needs to be implemented in child metadata type + **Kind**: static method of [MetadataType](#MetadataType) @@ -3645,7 +3673,7 @@ Updates a single metadata entry via fuel-soap (generic lib not wrapper) ### MetadataType.getSOAPErrorMsg(ex) ⇒ string -helper for [_handleSOAPErrors](_handleSOAPErrors) +helper for [_handleSOAPErrors](#MetadataType._handleSOAPErrors) **Kind**: static method of [MetadataType](#MetadataType) **Returns**: string - error message @@ -8253,6 +8281,31 @@ helper for [postRetrieveTasks](#Automation.postRetrieveTasks) and [execute](#Aut +## Automation.(metadataMap, key) ⇒ Promise.<object> +helper for [execute](#Automation.execute) + +**Kind**: global function +**Returns**: Promise.<object> - Returns the result of the API call + +| Param | Type | Description | +| --- | --- | --- | +| metadataMap | TYPE.AutomationMap | map of metadata | +| key | string | key of the metadata | + + + +## Automation.(metadata) ⇒ Promise.<object> +helper for [pause](#Automation.pause) + +**Kind**: global function +**Returns**: Promise.<object> - schedule reponse + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.AutomationItem | automation metadata | + + + ## Automation.(metadata) helper for [preDeployTasks](#Automation.preDeployTasks) and [execute](#Automation.execute) @@ -8277,10 +8330,11 @@ helper for [postDeployTasks](#Automation.postDeployTasks) -## Automation.(metadataMap, originalMetadataMap, key) +## Automation.(metadataMap, originalMetadataMap, key) ⇒ Promise.<object> helper for [postDeployTasks](#Automation.postDeployTasks) **Kind**: global function +**Returns**: Promise.<object> - - | Param | Type | Description | | --- | --- | --- | diff --git a/lib/cli.js b/lib/cli.js index 7a7e5ea89..ddec010e8 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -435,7 +435,38 @@ yargs handler: (argv) => { Mcdev.setOptions(argv); // ! do not allow multiple types to be passed in here via csvToArray - Mcdev.execute(argv.BU, argv.TYPE, csvToArray(argv.KEY)); + Mcdev.runMethod('execute', argv.BU, argv.TYPE, csvToArray(argv.KEY)); + }, + }) + .command({ + command: 'pause [KEY]', + aliases: ['p', 'stop'], + desc: 'pauses the entity (automation etc.)', + builder: (yargs) => { + yargs + .positional('BU', { + type: 'string', + describe: 'the business unit where to start an item', + }) + .positional('TYPE', { + type: 'string', + describe: 'metadata type', + }) + .positional('KEY', { + type: 'string', + describe: 'key(s) of the metadata component(s)', + }) + .option('like', { + type: 'string', + group: 'Options for pause:', + describe: + 'filter metadata components (can include % as wildcard or _ for a single character)', + }); + }, + handler: (argv) => { + Mcdev.setOptions(argv); + // ! do not allow multiple types to be passed in here via csvToArray + Mcdev.runMethod('pause', argv.BU, argv.TYPE, csvToArray(argv.KEY)); }, }) .command({ diff --git a/lib/index.js b/lib/index.js index 68a0ffd39..245992499 100644 --- a/lib/index.js +++ b/lib/index.js @@ -175,10 +175,10 @@ class Mcdev { } if (businessUnit === '*') { - Util.logger.info('\n :: Retrieving all BUs for all credentials'); + Util.logger.info(':: Retrieving all BUs for all credentials'); let counter_credTotal = 0; for (const cred in properties.credentials) { - Util.logger.info(`\n :: Retrieving all BUs for ${cred}`); + Util.logger.info(`:: Retrieving all BUs for ${cred}`); let counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { await this._retrieveBU(cred, bu, selectedTypesArr, keys); @@ -186,9 +186,9 @@ class Mcdev { Util.startLogger(true); } counter_credTotal += counter_credBu; - Util.logger.info(`\n :: ${counter_credBu} BUs for ${cred}\n`); + Util.logger.info(`:: ${counter_credBu} BUs for ${cred}\n`); } - Util.logger.info(`\n :: ${counter_credTotal} BUs in total\n`); + Util.logger.info(`:: ${counter_credTotal} BUs in total\n`); } else { let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; // to allow all-BU via user selection we need to run this here already @@ -212,14 +212,14 @@ class Mcdev { } if (bu === '*' && properties.credentials && properties.credentials[cred]) { - Util.logger.info(`\n :: Retrieving all BUs for ${cred}`); + Util.logger.info(`:: Retrieving all BUs for ${cred}`); let counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { await this._retrieveBU(cred, bu, selectedTypesArr, keys); counter_credBu++; Util.startLogger(true); } - Util.logger.info(`\n :: ${counter_credBu} BUs for ${cred}\n`); + Util.logger.info(`:: ${counter_credBu} BUs for ${cred}\n`); } else { // retrieve a single BU; return const retrieveChangelog = await this._retrieveBU( @@ -272,7 +272,7 @@ class Mcdev { triggeredSend: 'triggeredSendDefinition', user: 'accountUser', }; - Util.logger.info(`\n :: Retrieving ${cred}/${bu}\n`); + Util.logger.info(`:: Retrieving ${cred}/${bu}\n`); const retrieveTypesArr = []; if (selectedTypesArr) { for (const selectedType of Array.isArray(selectedTypesArr) @@ -705,14 +705,31 @@ class Mcdev { /** * Start an item (query) * + * @param {'execute'|'pause'} methodName what to run * @param {string} businessUnit name of BU * @param {TYPE.SupportedMetadataTypes} [selectedType] limit to given metadata types * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.} true if all started successfully, false if not */ - static async execute(businessUnit, selectedType, keys) { + static async runMethod(methodName, businessUnit, selectedType, keys) { Util.startLogger(); - Util.logger.info('mcdev:: Executing ' + selectedType); + let lang_past; + let lang_present; + switch (methodName) { + case 'execute': { + lang_past = 'executed'; + lang_present = 'executing'; + break; + } + case 'pause': { + lang_past = 'paused'; + lang_present = 'pausing'; + + break; + } + } + + Util.logger.info(`mcdev:: ${methodName} ${selectedType}`); const properties = await config.getProperties(); let counter_credBu = 0; let counter_failed = 0; @@ -723,9 +740,9 @@ class Mcdev { if (!Util._isValidType(selectedType)) { return false; } - if (!Object.prototype.hasOwnProperty.call(MetadataTypeInfo[selectedType], 'execute')) { + if (!Object.prototype.hasOwnProperty.call(MetadataTypeInfo[selectedType], methodName)) { Util.logger.error( - ` ☇ skipping ${selectedType}: execute is not supported yet for ${selectedType}` + ` ☇ skipping ${selectedType}: ${methodName} is not supported yet for ${selectedType}` ); return false; } @@ -745,13 +762,15 @@ class Mcdev { return false; } if (businessUnit === '*') { - Util.logger.info(':: Executing the entity on all BUs for all credentials'); + Util.logger.info( + `:: ${lang_present} the ${selectedType} on all BUs for all credentials` + ); let counter_credTotal = 0; for (const cred in properties.credentials) { - Util.logger.info(`:: Executing the entity on all BUs for ${cred}`); + Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`); for (const bu in properties.credentials[cred].businessUnits) { - if (await this._executeBU(cred, bu, selectedType, keys)) { + if (await this._runOnBU(methodName, cred, bu, selectedType, keys)) { counter_credBu++; } else { counter_failed++; @@ -759,9 +778,13 @@ class Mcdev { Util.startLogger(true); } counter_credTotal += counter_credBu; - Util.logger.info(`:: Executed the entity on ${counter_credBu} BUs for ${cred}\n`); + Util.logger.info( + `:: ${lang_past} ${selectedType} on ${counter_credBu} BUs for ${cred}` + ); } - Util.logger.info(`:: Executed the entity on ${counter_credTotal} BUs in total\n`); + Util.logger.info( + `:: ${lang_past} ${selectedType} on ${counter_credTotal} BUs in total\n` + ); } else { let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; // to allow all-BU via user selection we need to run this here already @@ -784,10 +807,10 @@ class Mcdev { } } if (bu === '*' && properties.credentials && properties.credentials[cred]) { - Util.logger.info(`\n :: Executing the entity on all BUs for ${cred}`); + Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`); let counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { - if (await this._executeBU(cred, bu, selectedType, keys)) { + if (await this._runOnBU(methodName, cred, bu, selectedType, keys)) { counter_credBu++; } else { counter_failed++; @@ -795,33 +818,34 @@ class Mcdev { Util.startLogger(true); } Util.logger.info( - `\n :: Executed the entity on ${counter_credBu} BUs for ${cred}\n` + `:: ${lang_past} ${selectedType} on ${counter_credBu} BUs for ${cred}` ); } else { - // execute the entity on one BU only - if (await this._executeBU(cred, bu, selectedType, keys)) { + // execute runMethod for the entity on one BU only + if (await this._runOnBU(methodName, cred, bu, selectedType, keys)) { counter_credBu++; } else { counter_failed++; } - Util.logger.info(`\n :: Done\n`); + Util.logger.info(`:: Done`); } } - if (counter_credBu !== 0) { - Util.logger.info(`\n :: Executed query on ${counter_credBu} BUs\n`); + if (counter_credBu > 1) { + Util.logger.info(`:: ${lang_past} ${selectedType} on ${counter_credBu} BUs`); } return counter_failed === 0 ? true : false; } /** - * helper for {@link Mcdev.execute} + * helper for {@link Mcdev.runMethod} * + * @param {'execute'|'pause'} methodName what to run * @param {string} cred name of Credential * @param {string} bu name of BU * @param {TYPE.SupportedMetadataTypes} [type] limit execution to given metadata type * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.} true if all items were executed, false otherwise */ - static async _executeBU(cred, bu, type, keyArr) { + static async _runOnBU(methodName, cred, bu, type, keyArr) { const properties = await config.getProperties(); let counter_failed = 0; const buObject = await Cli.getCredentialObject( @@ -839,7 +863,7 @@ class Mcdev { cred = buObject.credential; bu = buObject.businessUnit; } - Util.logger.info(`\n :: Executing ${type} on ${cred}/${bu}\n`); + Util.logger.info(`:: ${methodName} ${type} on ${cred}/${bu}`); MetadataTypeInfo[type].client = auth.getSDK(buObject); if (Util.OPTIONS.like && Object.keys(Util.OPTIONS.like).length) { keyArr = await this._retrieveKeysWithLike(type, buObject); @@ -851,19 +875,19 @@ class Mcdev { throw new Error('No keys were provided'); } - // result will be undefined (false) if execute is not supported for the type - if (!(await MetadataTypeInfo[type].execute(keyArr))) { + // result will be undefined (false) if methodName is not supported for the type + if (!(await MetadataTypeInfo[type][methodName](keyArr))) { counter_failed++; } } catch (ex) { - Util.logger.errorStack(ex, 'mcdev.execute failed'); + Util.logger.errorStack(ex, 'mcdev.' + methodName + ' failed'); } return counter_failed === 0 ? true : false; } /** - * helper for {@link Mcdev._executeBU} + * helper for {@link Mcdev._runOnBU} * * @param {TYPE.SupportedMetadataTypes} selectedType limit execution to given metadata type * @param {TYPE.BuObject} buObject properties for auth diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index af30f0a4e..2f34409f5 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -501,10 +501,89 @@ class Automation extends MetadataType { } } // console.log('metadataMap', metadataMap); + } + /** + * a function to start query execution via API + * + * @param {string[]} keyArr customerkey of the metadata + * @returns {Promise.} Returns true if all items were executed successfully, otherwise false + */ + static async pause(keyArr) { + const metadataMap = {}; + for (const key of keyArr) { + if (key) { + const results = await this.retrieve(undefined, undefined, undefined, key); + if (Object.keys(results.metadata).length) { + for (const key of Object.keys(results.metadata)) { + if (this.#isValidSchedule(results.metadata[key])) { + metadataMap[key] = results.metadata[key]; + } else { + Util.logger.error( + ` - skipping ${this.definition.type} ${results.metadata[key].name}: no valid schedule settings found.` + ); + } + } + } + } + } + + Util.logger.info(`Pausing automations: ${Object.keys(metadataMap).length}`); + const promiseResults = []; + for (const key of Object.keys(metadataMap)) { + if (metadataMap[key].status === 'Scheduled') { + promiseResults.push(this.#pauseItem(metadataMap[key])); + } else if (metadataMap[key].status === 'PausedSchedule') { + Util.logger.info( + ` - skipping ${this.definition.type} ${metadataMap[key].name}: already paused.` + ); + } else { + Util.logger.error( + ` - skipping ${this.definition.type} ${ + metadataMap[key].name + }: currently ${metadataMap[ + key + ].status.toLowerCase()}. Please try again in a few minutes.` + ); + } + } + const successCounter = (await Promise.all(promiseResults)) + .filter(Boolean) + .filter((r) => r.OverallStatus === 'OK').length; + + Util.logger.info(`Paused ${successCounter} of ${keyArr.length} items`); + return successCounter === keyArr.length; + } - // const successCounter = (await Promise.all(results)).filter((r) => r === 'OK').length; - // Util.logger.info(`Executed ${successCounter} of ${keyArr.length} items`); - // return successCounter === keyArr.length; + /** + * helper for {@link Automation.pause} + * + * @param {TYPE.AutomationItem} metadata automation metadata + * @returns {Promise.} schedule reponse + */ + static async #pauseItem(metadata) { + const schedule = {}; + try { + const response = await this.client.soap.schedule( + 'Automation', + schedule, + { + Interaction: { + ObjectID: metadata[this.definition.idField], + }, + }, + 'pause', + {} + ); + Util.logger.info( + ` - paused ${this.definition.type}: ${metadata[this.definition.keyField]} / ${ + metadata[this.definition.nameField] + }` + ); + return response; + } catch (ex) { + this._handleSOAPErrors(ex, 'pausing', metadata, false); + return null; + } } /** diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 09533b907..983b50c8a 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -463,6 +463,17 @@ class MetadataType { ); return; } + /** + * Abstract pause method that needs to be implemented in child metadata type + * + * @returns {void} + */ + static pause() { + Util.logger.error( + ` ☇ skipping ${this.definition.type}: pause is not supported yet for ${this.definition.type}` + ); + return; + } /** * test if metadata was actually changed or not to potentially skip it during deployment @@ -980,7 +991,7 @@ class MetadataType { } } /** - * helper for {@link _handleSOAPErrors} + * helper for {@link MetadataType._handleSOAPErrors} * * @param {Error} ex error that occured * @returns {string} error message From de57e547492eebb54e8513b91bb02f73251d54ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 4 Jul 2023 11:20:09 +0200 Subject: [PATCH 070/208] #870: execute in parallel & ensure errors are handled gracefully --- lib/metadataTypes/Automation.js | 52 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index 2f34409f5..b55eb1785 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -336,17 +336,6 @@ class Automation extends MetadataType { `- Schedule name '${metadata.schedule.timezoneName}' not found in definition.timeZoneMapping` ); } - try { - // type 'Running' is temporary status only, overwrite with Scheduled for storage. - if (metadata.type === 'scheduled' && metadata.status === 'Running') { - metadata.status = 'Scheduled'; - } - } catch { - Util.logger.error( - ` - ${this.definition.type} ${metadata.name} does not have a valid schedule setting.` - ); - return false; - } return true; } else { return false; @@ -369,6 +358,10 @@ class Automation extends MetadataType { if (!this.#isValidSchedule(metadata)) { return; } + // type 'Running' is temporary status only, overwrite with Scheduled for storage. + if (metadata.type === 'scheduled' && metadata.status === 'Running') { + metadata.status = 'Scheduled'; + } } else if (metadata.type === 'triggered' && metadata.fileTrigger) { // Starting Source == 'File Drop' // Do nothing for now @@ -489,18 +482,35 @@ class Automation extends MetadataType { Util.logger.info( `Starting automations according to schedule: ${Object.keys(metadataMap).length}` ); + const promiseResults = []; + for (const key of Object.keys(metadataMap)) { if (metadataMap[key].status === 'Scheduled') { Util.logger.info( ` - skipping ${this.definition.type} ${metadataMap[key].name}: already scheduled.` ); } else { - this.#preDeploySchedule(metadataMap[key]); - metadataMap[key].status = 'Scheduled'; - this.#scheduleAutomation(metadataMap, metadataMap, key); + promiseResults.push(this.#executeItem(metadataMap, key)); } } - // console.log('metadataMap', metadataMap); + const results = await Promise.all(promiseResults); + const successCounter = results + .filter(Boolean) + .filter((r) => r.OverallStatus === 'OK').length; + Util.logger.info(`Executed ${successCounter} of ${keyArr.length} items`); + return successCounter === keyArr.length; + } + /** + * helper for {@link Automation.execute} + * + * @param {TYPE.AutomationMap} metadataMap map of metadata + * @param {string} key key of the metadata + * @returns {Promise.} Returns the result of the API call + */ + static async #executeItem(metadataMap, key) { + this.#preDeploySchedule(metadataMap[key]); + metadataMap[key].status = 'Scheduled'; + return this.#scheduleAutomation(metadataMap, metadataMap, key); } /** * a function to start query execution via API @@ -861,8 +871,10 @@ class Automation extends MetadataType { * @param {TYPE.AutomationMap} metadataMap metadata mapped by their keyField * @param {TYPE.AutomationMap} originalMetadataMap metadata to be updated (contains additioanl fields) * @param {string} key current customer key + * @returns {Promise.} - */ static async #scheduleAutomation(metadataMap, originalMetadataMap, key) { + let response = null; if (originalMetadataMap[key]?.type === 'scheduled') { // Starting Source == 'Schedule': Try starting the automation if (originalMetadataMap[key].status === 'Scheduled') { @@ -884,7 +896,7 @@ class Automation extends MetadataType { const schedule_timezoneString = schedule._timezoneString; delete schedule._timezoneString; // start the automation - await this.client.soap.schedule( + response = await this.client.soap.schedule( 'Automation', schedule, { @@ -909,8 +921,11 @@ class Automation extends MetadataType { } ${schedule_timezoneString}` ); } catch (ex) { - Util.logger.error( - `- Could not start scheduled automation '${originalMetadataMap[key].name}': ${ex.message}` + this._handleSOAPErrors( + ex, + 'starting scheduled', + originalMetadataMap, + false ); } } @@ -931,6 +946,7 @@ class Automation extends MetadataType { metadataMap[key].schedule.typeId = metadataMap[key].schedule.scheduleTypeId; delete metadataMap[key].schedule.scheduleTypeId; } + return response; } /** From b7931133c61832e8cb2683522e945746b3ee6ccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 4 Jul 2023 13:51:32 +0200 Subject: [PATCH 071/208] #870: --- docs/dist/documentation.md | 22 +++++++++---------- .../definitions/Automation.definition.js | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 1b3d39169..e5a2555d0 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -3335,7 +3335,7 @@ Gets executed after deployment of metadata type ### MetadataType.postCreateTasks(metadataEntry, apiResponse) ⇒ void -helper for [createREST](createREST) +helper for [createREST](#MetadataType.createREST) **Kind**: static method of [MetadataType](#MetadataType) @@ -3347,7 +3347,7 @@ helper for [createREST](createREST) ### MetadataType.postUpdateTasks(metadataEntry, apiResponse) ⇒ void -helper for [updateREST](updateREST) +helper for [updateREST](#MetadataType.updateREST) **Kind**: static method of [MetadataType](#MetadataType) @@ -3359,7 +3359,7 @@ helper for [updateREST](updateREST) ### MetadataType.postDeployTasks\_legacyApi(metadataEntry, apiResponse) ⇒ Promise.<void> -helper for [createREST](createREST) when legacy API endpoints as these do not return the created item but only their new id +helper for [createREST](#MetadataType.createREST) when legacy API endpoints as these do not return the created item but only their new id **Kind**: static method of [MetadataType](#MetadataType) **Returns**: Promise.<void> - - @@ -3728,7 +3728,7 @@ Used to execute a query/automation etc. ### MetadataType.runDocumentOnRetrieve([singleRetrieve], metadataMap) ⇒ Promise.<void> -helper for [retrieveREST](retrieveREST) and [retrieveSOAP](retrieveSOAP) +helper for [retrieveREST](#MetadataType.retrieveREST) and [retrieveSOAP](#MetadataType.retrieveSOAP) **Kind**: static method of [MetadataType](#MetadataType) **Returns**: Promise.<void> - - @@ -3858,7 +3858,7 @@ Helper for writing Metadata to disk, used for Retrieve and deploy ### MetadataType.applyTemplateValues(code, templateVariables) ⇒ string -helper for [buildDefinitionForNested](buildDefinitionForNested) +helper for [buildDefinitionForNested](#MetadataType.buildDefinitionForNested) searches extracted file for template variable names and applies the market values **Kind**: static method of [MetadataType](#MetadataType) @@ -3872,7 +3872,7 @@ searches extracted file for template variable names and applies the market value ### MetadataType.applyTemplateNames(code, templateVariables) ⇒ string -helper for [buildTemplateForNested](buildTemplateForNested) +helper for [buildTemplateForNested](#MetadataType.buildTemplateForNested) searches extracted file for template variable values and applies the market variable names **Kind**: static method of [MetadataType](#MetadataType) @@ -3886,7 +3886,7 @@ searches extracted file for template variable values and applies the market vari ### MetadataType.buildDefinitionForNested(templateDir, targetDir, metadata, variables, templateName) ⇒ Promise.<Array.<Array.<string>>> -helper for [buildDefinition](buildDefinition) +helper for [buildDefinition](#MetadataType.buildDefinition) handles extracted code if any are found for complex types (e.g script, asset, query) **Kind**: static method of [MetadataType](#MetadataType) @@ -3903,7 +3903,7 @@ handles extracted code if any are found for complex types (e.g script, asset, qu ### MetadataType.buildTemplateForNested(templateDir, targetDir, metadata, templateVariables, templateName) ⇒ Promise.<Array.<Array.<string>>> -helper for [buildTemplate](buildTemplate) +helper for [buildTemplate](#MetadataType.buildTemplate) handles extracted code if any are found for complex types **Kind**: static method of [MetadataType](#MetadataType) @@ -5663,7 +5663,7 @@ TSD-specific refresh method that finds active TSDs and refreshes them ### TriggeredSend.getKeysForValidTSDs(metadata) ⇒ Promise.<Array.<string>> -helper for [refresh](refresh) that extracts the keys from the TSD item map and eli +helper for [refresh](#TriggeredSend.refresh) that extracts the keys from the TSD item map and eli **Kind**: static method of [TriggeredSend](#TriggeredSend) **Returns**: Promise.<Array.<string>> - keyArr @@ -5675,7 +5675,7 @@ helper for [refresh](refresh) that extracts the keys from the TSD item map and e ### TriggeredSend.findRefreshableItems([assetLoaded]) ⇒ Promise.<TYPE.MetadataTypeMapObj> -helper for [refresh](refresh) that finds active TSDs on the server and filters it by the same rules that [retrieve](retrieve) is using to avoid refreshing TSDs with broken dependencies +helper for [refresh](#TriggeredSend.refresh) that finds active TSDs on the server and filters it by the same rules that [retrieve](#TriggeredSend.retrieve) is using to avoid refreshing TSDs with broken dependencies **Kind**: static method of [TriggeredSend](#TriggeredSend) **Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of TSD item map @@ -5687,7 +5687,7 @@ helper for [refresh](refresh) that finds active TSDs on the server and filters i ### TriggeredSend.\_refreshItem(key, checkKey) ⇒ Promise.<boolean> -helper for [refresh](refresh) that pauses, publishes and starts a triggered send +helper for [refresh](#TriggeredSend.refresh) that pauses, publishes and starts a triggered send **Kind**: static method of [TriggeredSend](#TriggeredSend) **Returns**: Promise.<boolean> - true if refresh was successful diff --git a/lib/metadataTypes/definitions/Automation.definition.js b/lib/metadataTypes/definitions/Automation.definition.js index 62808f0aa..719ec6005 100644 --- a/lib/metadataTypes/definitions/Automation.definition.js +++ b/lib/metadataTypes/definitions/Automation.definition.js @@ -491,8 +491,8 @@ module.exports = { template: true, }, 'schedule.typeId': { - isCreateable: true, - isUpdateable: true, + isCreateable: false, + isUpdateable: false, retrieving: false, template: false, }, From 2ae89544ea5efe6539d9544dfc71a018d4b79e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 4 Jul 2023 14:06:50 +0200 Subject: [PATCH 072/208] #870: ensure minimum frequency (5 minutes) --- docs/dist/documentation.md | 52 ++++++++++++++++----------------- lib/metadataTypes/Automation.js | 15 ++++++++-- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index e5a2555d0..d988436b2 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -437,7 +437,7 @@ Deploys all metadata located in the 'deploy' directory to the specified business ### Deployer.\_deployBU(cred, bu, properties, [typeArr], [keyArr], [fromRetrieve]) ⇒ Promise.<TYPE.MultiMetadataTypeMap> -helper for [deploy](deploy) +helper for [deploy](#Deployer.deploy) **Kind**: static method of [Deployer](#Deployer) **Returns**: Promise.<TYPE.MultiMetadataTypeMap> - ensure that BUs are worked on sequentially @@ -958,7 +958,7 @@ This method retrieves these and saves them alongside the metadata json ### Asset.\_readExtendedFileFromFS(metadata, subType, deployDir, [pathOnly]) ⇒ Promise.<string> -helper for [preDeployTasks](preDeployTasks) +helper for [preDeployTasks](#Asset.preDeployTasks) Some metadata types store their actual content as a separate file, e.g. images This method reads these from the local FS stores them in the metadata object allowing to deploy it @@ -1104,7 +1104,7 @@ Asset-specific script that retrieves the folder ID from cache and updates the gi ### Asset.\_mergeCode(metadata, deployDir, subType, [templateName], [fileListOnly]) ⇒ Promise.<Array.<TYPE.CodeExtract>> -helper for [preDeployTasks](preDeployTasks) that loads extracted code content back into JSON +helper for [preDeployTasks](#Asset.preDeployTasks) that loads extracted code content back into JSON **Kind**: static method of [Asset](#Asset) **Returns**: Promise.<Array.<TYPE.CodeExtract>> - fileList for templating (disregarded during deployment) @@ -1120,7 +1120,7 @@ helper for [preDeployTasks](preDeployTasks) that loads extracted code content ba ### Asset.\_mergeCode\_slots(prefix, metadataSlots, readDirArr, subtypeExtension, subDirArr, fileList, customerKey, [templateName], [fileListOnly]) ⇒ Promise.<void> -helper for [preDeployTasks](preDeployTasks) that loads extracted code content back into JSON +helper for [preDeployTasks](#Asset.preDeployTasks) that loads extracted code content back into JSON **Kind**: static method of [Asset](#Asset) **Returns**: Promise.<void> - - @@ -1140,7 +1140,7 @@ helper for [preDeployTasks](preDeployTasks) that loads extracted code content ba ### Asset.\_extractCode(metadata) ⇒ TYPE.CodeExtractItem -helper for [postRetrieveTasks](postRetrieveTasks) that finds code content in JSON and extracts it +helper for [postRetrieveTasks](#Asset.postRetrieveTasks) that finds code content in JSON and extracts it to allow saving that separately and formatted **Kind**: static method of [Asset](#Asset) @@ -3065,7 +3065,7 @@ Helper for writing Metadata to disk, used for Retrieve and deploy ### Journey.\_postRetrieveTasksBulk(metadataMap) -helper for Journey's [saveResults](saveResults). Gets executed after retreive of metadata type and +helper for Journey's [saveResults](#Journey.saveResults). Gets executed after retreive of metadata type and **Kind**: static method of [Journey](#Journey) @@ -4243,7 +4243,7 @@ manages post retrieve steps ### MobileKeyword.prepExtractedCode(metadataScript) ⇒ Object -helper for [parseMetadata](parseMetadata) and [_buildForNested](_buildForNested) +helper for [postRetrieveTasks](#MobileKeyword.postRetrieveTasks) and [_buildForNested](#MobileKeyword._buildForNested) **Kind**: static method of [MobileKeyword](#MobileKeyword) **Returns**: Object - returns found extension and file content @@ -4293,7 +4293,7 @@ scripts are saved as 1 json and 1 ssjs file. both files need to be run through t ### MobileKeyword.\_buildForNested(templateDir, targetDir, metadata, templateVariables, templateName, mode) ⇒ Promise.<Array.<Array.<string>>> -helper for [buildTemplateForNested](buildTemplateForNested) / [buildDefinitionForNested](buildDefinitionForNested) +helper for [buildTemplateForNested](#MobileKeyword.buildTemplateForNested) / [buildDefinitionForNested](#MobileKeyword.buildDefinitionForNested) handles extracted code if any are found for complex types **Kind**: static method of [MobileKeyword](#MobileKeyword) @@ -4324,7 +4324,7 @@ prepares an event definition for deployment ### MobileKeyword.postCreateTasks(metadataEntry, apiResponse) ⇒ void -helper for [createREST](createREST) +helper for [createREST](#MetadataType.createREST) **Kind**: static method of [MobileKeyword](#MobileKeyword) @@ -4336,7 +4336,7 @@ helper for [createREST](createREST) ### MobileKeyword.postUpdateTasks(metadataEntry, apiResponse) ⇒ void -helper for [updateREST](updateREST) +helper for [updateREST](#MetadataType.updateREST) **Kind**: static method of [MobileKeyword](#MobileKeyword) @@ -4348,7 +4348,7 @@ helper for [updateREST](updateREST) ### MobileKeyword.\_mergeCode(metadata, deployDir, [templateName]) ⇒ Promise.<string> -helper for [preDeployTasks](preDeployTasks) that loads extracted code content back into JSON +helper for [preDeployTasks](#MobileKeyword.preDeployTasks) that loads extracted code content back into JSON **Kind**: static method of [MobileKeyword](#MobileKeyword) **Returns**: Promise.<string> - content for metadata.script @@ -4476,7 +4476,7 @@ Creates a single item ### MobileMessage.\_mergeCode(metadata, deployDir, [templateName]) ⇒ Promise.<string> -helper for [preDeployTasks](preDeployTasks) that loads extracted code content back into JSON +helper for [preDeployTasks](#MobileMessage.preDeployTasks) that loads extracted code content back into JSON **Kind**: static method of [MobileMessage](#MobileMessage) **Returns**: Promise.<string> - code @@ -4490,7 +4490,7 @@ helper for [preDeployTasks](preDeployTasks) that loads extracted code content ba ### MobileMessage.prepExtractedCode(code) ⇒ Object -helper for [parseMetadata](parseMetadata) and [_buildForNested](_buildForNested) +helper for [postRetrieveTasks](#MobileMessage.postRetrieveTasks) and [_buildForNested](#MobileMessage._buildForNested) **Kind**: static method of [MobileMessage](#MobileMessage) **Returns**: Object - returns found extension and file content @@ -4540,7 +4540,7 @@ prepares an event definition for deployment ### MobileMessage.postCreateTasks(metadataEntry, apiResponse) ⇒ void -helper for [createREST](createREST) +helper for [createREST](#MetadataType.createREST) **Kind**: static method of [MobileMessage](#MobileMessage) @@ -4552,7 +4552,7 @@ helper for [createREST](createREST) ### MobileMessage.postUpdateTasks(metadataEntry, apiResponse) ⇒ void -helper for [updateREST](updateREST) +helper for [updateREST](#MetadataType.updateREST) **Kind**: static method of [MobileMessage](#MobileMessage) @@ -4602,7 +4602,7 @@ scripts are saved as 1 json and 1 ssjs file. both files need to be run through t ### MobileMessage.\_buildForNested(templateDir, targetDir, metadata, templateVariables, templateName, mode) ⇒ Promise.<Array.<Array.<string>>> -helper for [buildTemplateForNested](buildTemplateForNested) / [buildDefinitionForNested](buildDefinitionForNested) +helper for [buildTemplateForNested](#MobileMessage.buildTemplateForNested) / [buildDefinitionForNested](#MobileMessage.buildDefinitionForNested) handles extracted code if any are found for complex types **Kind**: static method of [MobileMessage](#MobileMessage) @@ -4756,7 +4756,7 @@ prepares a Query for deployment ### Query.applyTemplateValues(code, templateVariables) ⇒ string -helper for [buildDefinitionForNested](buildDefinitionForNested) +helper for [buildDefinitionForNested](#Query.buildDefinitionForNested) searches extracted SQL file for template variables and applies the market values **Kind**: static method of [Query](#Query) @@ -5057,7 +5057,7 @@ Creates a single Script ### Script.\_mergeCode(metadata, deployDir, [templateName]) ⇒ Promise.<string> -helper for [preDeployTasks](preDeployTasks) that loads extracted code content back into JSON +helper for [preDeployTasks](#Script.preDeployTasks) that loads extracted code content back into JSON **Kind**: static method of [Script](#Script) **Returns**: Promise.<string> - content for metadata.script @@ -5122,7 +5122,7 @@ scripts are saved as 1 json and 1 ssjs file. both files need to be run through t ### Script.\_buildForNested(templateDir, targetDir, metadata, templateVariables, templateName, mode) ⇒ Promise.<Array.<Array.<string>>> -helper for [buildTemplateForNested](buildTemplateForNested) / [buildDefinitionForNested](buildDefinitionForNested) +helper for [buildTemplateForNested](#Script.buildTemplateForNested) / [buildDefinitionForNested](#Script.buildDefinitionForNested) handles extracted code if any are found for complex types **Kind**: static method of [Script](#Script) @@ -5152,7 +5152,7 @@ Splits the script metadata into two parts and parses in a standard manner ### Script.prepExtractedCode(metadataScript, metadataName) ⇒ Object -helper for [parseMetadata](parseMetadata) and [_buildForNested](_buildForNested) +helper for [parseMetadata](#Script.parseMetadata) and [_buildForNested](#Script._buildForNested) **Kind**: static method of [Script](#Script) **Returns**: Object - returns found extension and file content @@ -5436,7 +5436,7 @@ prepares for deployment ### TransactionalSMS.\_mergeCode(metadata, deployDir, [templateName]) ⇒ Promise.<string> -helper for [preDeployTasks](preDeployTasks) that loads extracted code content back into JSON +helper for [preDeployTasks](#TransactionalSMS.preDeployTasks) that loads extracted code content back into JSON **Kind**: static method of [TransactionalSMS](#TransactionalSMS) **Returns**: Promise.<string> - content for metadata.script @@ -5462,7 +5462,7 @@ manages post retrieve steps ### TransactionalSMS.prepExtractedCode(metadataScript) ⇒ Object -helper for [parseMetadata](parseMetadata) and [_buildForNested](_buildForNested) +helper for [postRetrieveTasks](#TransactionalSMS.postRetrieveTasks) and [_buildForNested](#TransactionalSMS._buildForNested) **Kind**: static method of [TransactionalSMS](#TransactionalSMS) **Returns**: Object - returns found extension and file content @@ -5474,7 +5474,7 @@ helper for [parseMetadata](parseMetadata) and [_buildForNested](_buildForNested) ### TransactionalSMS.buildDefinitionForNested(templateDir, targetDir, metadata, templateVariables, templateName) ⇒ Promise.<Array.<Array.<string>>> -helper for [buildDefinition](#MetadataType.buildDefinition) +helper for [TransactionalMessage.buildDefinition](TransactionalMessage.buildDefinition) handles extracted code if any are found for complex types **Kind**: static method of [TransactionalSMS](#TransactionalSMS) @@ -5491,7 +5491,7 @@ handles extracted code if any are found for complex types ### TransactionalSMS.buildTemplateForNested(templateDir, targetDir, metadata, templateVariables, templateName) ⇒ Promise.<Array.<Array.<string>>> -helper for [buildTemplate](#MetadataType.buildTemplate) +helper for [TransactionalMessage.buildTemplate](TransactionalMessage.buildTemplate) handles extracted code if any are found for complex types **Kind**: static method of [TransactionalSMS](#TransactionalSMS) @@ -5512,7 +5512,7 @@ scripts are saved as 1 json and 1 ssjs file. both files need to be run through t ### TransactionalSMS.\_buildForNested(templateDir, targetDir, metadata, templateVariables, templateName, mode) ⇒ Promise.<Array.<Array.<string>>> -helper for [buildTemplateForNested](buildTemplateForNested) / [buildDefinitionForNested](buildDefinitionForNested) +helper for [buildTemplateForNested](#TransactionalSMS.buildTemplateForNested) / [buildDefinitionForNested](#TransactionalSMS.buildDefinitionForNested) handles extracted code if any are found for complex types **Kind**: static method of [TransactionalSMS](#TransactionalSMS) @@ -5907,7 +5907,7 @@ Retrieve metadata of specified types into local file system and Retriever.metada ### retriever.\_getTypeDependencies(metadataTypes) ⇒ Array.<TYPE.SupportedMetadataTypes> -helper for [retrieve](retrieve) to get all dependencies of the given types +helper for [Retriever.retrieve](Retriever.retrieve) to get all dependencies of the given types **Kind**: instance method of [Retriever](#Retriever) **Returns**: Array.<TYPE.SupportedMetadataTypes> - unique list dependent metadata types diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index b55eb1785..d2e59ed23 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -693,6 +693,9 @@ class Automation extends MetadataType { // Starting Source == 'Schedule' this.#preDeploySchedule(metadata); + // * run _buildSchedule here but only to check if things look ok - do not use the returned schedule object for deploy + this._buildSchedule(metadata.schedule); + delete metadata.schedule.timezoneName; delete metadata.startSource.schedule.timezoneName; } else if (metadata.type === 'triggered' && metadata.fileTrigger) { @@ -1033,6 +1036,9 @@ class Automation extends MetadataType { const a = obj.split('='); recurHelper[a[0]] = a[1]; } + if (recurHelper.INTERVAL) { + recurHelper.INTERVAL = Number.parseInt(recurHelper.INTERVAL); + } // the ical schedule is all in caps but soap objects require Title Case. const keyStem = recurHelper.FREQ.charAt(0) + recurHelper.FREQ.slice(1, -2).toLowerCase(); @@ -1061,13 +1067,18 @@ class Automation extends MetadataType { 'Scheduling automatically not supported for Weekly, Monthly and Yearly, please configure manually.' ); } + if (recurHelper.FREQ === 'MINUTELY' && recurHelper.INTERVAL && recurHelper.INTERVAL < 5) { + throw new Error( + 'The smallest interval you can configure is 5 minutes. Please adjust your schedule.' + ); + } if (this.definition.timeZoneMapping[scheduleObject.timezoneName]) { scheduleObject.timezoneId = this.definition.timeZoneMapping[scheduleObject.timezoneName]; } else { - Util.logger.error( - `- Could not find timezone ${scheduleObject.timezoneName} in definition.timeZoneMapping` + throw new Error( + `Could not find timezone ${scheduleObject.timezoneName} in definition.timeZoneMapping` ); } schedule.TimeZone.ID = scheduleObject.timezoneId; From 76a0d7131823e1a320a37bd248018c615e62ebce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 4 Jul 2023 14:09:30 +0200 Subject: [PATCH 073/208] #0: jsdoc fixes --- lib/Deployer.js | 2 +- lib/Retriever.js | 2 +- lib/metadataTypes/Asset.js | 12 ++++++------ lib/metadataTypes/DataExtension.js | 4 ++-- lib/metadataTypes/Journey.js | 6 +++--- lib/metadataTypes/MetadataType.js | 18 +++++++++--------- lib/metadataTypes/MobileKeyword.js | 16 ++++++++-------- lib/metadataTypes/MobileMessage.js | 10 +++++----- lib/metadataTypes/Query.js | 4 ++-- lib/metadataTypes/Script.js | 6 +++--- lib/metadataTypes/TransactionalSMS.js | 10 +++++----- lib/metadataTypes/TriggeredSend.js | 6 +++--- lib/metadataTypes/User.js | 4 ++-- 13 files changed, 50 insertions(+), 50 deletions(-) diff --git a/lib/Deployer.js b/lib/Deployer.js index 28fd496e8..8df75ff6d 100644 --- a/lib/Deployer.js +++ b/lib/Deployer.js @@ -180,7 +180,7 @@ class Deployer { return buMultiMetadataTypeMap; } /** - * helper for {@link deploy} + * helper for {@link Deployer.deploy} * * @param {string} cred name of Credential * @param {string} bu name of BU diff --git a/lib/Retriever.js b/lib/Retriever.js index 86ecf781e..f32acd2e3 100644 --- a/lib/Retriever.js +++ b/lib/Retriever.js @@ -189,7 +189,7 @@ class Retriever { } /** - * helper for {@link retrieve} to get all dependencies of the given types + * helper for {@link Retriever.retrieve} to get all dependencies of the given types * * @param {TYPE.SupportedMetadataTypes[]} metadataTypes list of metadata types to retrieve; can include subtypes! * @returns {TYPE.SupportedMetadataTypes[]} unique list dependent metadata types diff --git a/lib/metadataTypes/Asset.js b/lib/metadataTypes/Asset.js index 2fd5c2c91..c44e337c3 100644 --- a/lib/metadataTypes/Asset.js +++ b/lib/metadataTypes/Asset.js @@ -86,7 +86,7 @@ class Asset extends MetadataType { return { metadata: Object.values(metadata)[0], type: this.definition.type }; } /** - * helper for {@link retrieve} + {@link retrieveAsTemplate} + * helper for {@link Asset.retrieve} + {@link Asset.retrieveAsTemplate} * * @private * @returns {TYPE.AssetSubType[]} subtype array @@ -448,7 +448,7 @@ class Asset extends MetadataType { ); } /** - * helper for {@link preDeployTasks} + * helper for {@link Asset.preDeployTasks} * Some metadata types store their actual content as a separate file, e.g. images * This method reads these from the local FS stores them in the metadata object allowing to deploy it * @@ -520,7 +520,7 @@ class Asset extends MetadataType { } /** - * helper for {@link postDeployTasks}. triggers a refresh of active triggerredSendDefinitions associated with the updated asset-message items. Gets executed if refresh option has been set. + * helper for {@link Asset.postDeployTasks}. triggers a refresh of active triggerredSendDefinitions associated with the updated asset-message items. Gets executed if refresh option has been set. * * @private * @param {TYPE.MetadataTypeMap} metadata metadata mapped by their keyField @@ -866,7 +866,7 @@ class Asset extends MetadataType { } /** - * helper for {@link preDeployTasks} that loads extracted code content back into JSON + * helper for {@link Asset.preDeployTasks} that loads extracted code content back into JSON * * @param {TYPE.AssetItem} metadata a single asset definition * @param {string} deployDir directory of deploy files @@ -1150,7 +1150,7 @@ class Asset extends MetadataType { return fileList; } /** - * helper for {@link preDeployTasks} that loads extracted code content back into JSON + * helper for {@link Asset.preDeployTasks} that loads extracted code content back into JSON * * @param {string} prefix usually the customerkey * @param {object} metadataSlots metadata.views.html.slots or deeper slots.<>.blocks.<>.slots @@ -1230,7 +1230,7 @@ class Asset extends MetadataType { } } /** - * helper for {@link postRetrieveTasks} that finds code content in JSON and extracts it + * helper for {@link Asset.postRetrieveTasks} that finds code content in JSON and extracts it * to allow saving that separately and formatted * * @param {TYPE.AssetItem} metadata a single asset definition diff --git a/lib/metadataTypes/DataExtension.js b/lib/metadataTypes/DataExtension.js index 43e9dcfc8..7210095a6 100644 --- a/lib/metadataTypes/DataExtension.js +++ b/lib/metadataTypes/DataExtension.js @@ -203,7 +203,7 @@ class DataExtension extends MetadataType { } } /** - * helper for {@link upsert} + * helper for {@link DataExtension.upsert} * * @private * @param {object} res - @@ -607,7 +607,7 @@ class DataExtension extends MetadataType { metadata[customerKey].Fields = fieldArr; } /** - * helper for {@link super.updateREST} and {@link super.updateSOAP} that removes old files after the key was changed + * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} that removes old files after the key was changed * * @private * @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry diff --git a/lib/metadataTypes/Journey.js b/lib/metadataTypes/Journey.js index 87e03e2b5..1719dfe47 100644 --- a/lib/metadataTypes/Journey.js +++ b/lib/metadataTypes/Journey.js @@ -264,7 +264,7 @@ class Journey extends MetadataType { } /** - * helper for Journey's {@link saveResults}. Gets executed after retreive of metadata type and + * helper for Journey's {@link Journey.saveResults}. Gets executed after retreive of metadata type and * * @param {TYPE.MetadataTypeMap} metadataMap key=customer key, value=metadata */ @@ -477,7 +477,7 @@ class Journey extends MetadataType { return metadata; } /** - * helper for {@link postRetrieveTasks} + * helper for {@link Journey.postRetrieveTasks} * * @private * @param {TYPE.MetadataTypeItem} metadata a single item @@ -799,7 +799,7 @@ class Journey extends MetadataType { } /** - * helper for {@link preDeployTasks} + * helper for {@link Journey.preDeployTasks} * * @private * @param {TYPE.MetadataTypeItem} metadata a single item diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 983b50c8a..d18f75848 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -135,7 +135,7 @@ class MetadataType { static postDeployTasks(upsertResults, originalMetadata, createdUpdated) {} /** - * helper for {@link createREST} + * helper for {@link MetadataType.createREST} * * @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call @@ -144,7 +144,7 @@ class MetadataType { static postCreateTasks(metadataEntry, apiResponse) {} /** - * helper for {@link updateREST} + * helper for {@link MetadataType.updateREST} * * @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call @@ -153,7 +153,7 @@ class MetadataType { static postUpdateTasks(metadataEntry, apiResponse) {} /** - * helper for {@link createREST} when legacy API endpoints as these do not return the created item but only their new id + * helper for {@link MetadataType.createREST} when legacy API endpoints as these do not return the created item but only their new id * * @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call @@ -910,7 +910,7 @@ class MetadataType { } /** - * helper for {@link updateREST} and {@link updateSOAP} that removes old files after the key was changed + * helper for {@link MetadataType.updateREST} and {@link MetadataType.updateSOAP} that removes old files after the key was changed * * @private * @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry @@ -1101,7 +1101,7 @@ class MetadataType { } /** - * helper for {@link retrieveREST} and {@link retrieveSOAP} + * helper for {@link MetadataType.retrieveREST} and {@link MetadataType.retrieveSOAP} * * @param {string|number} [singleRetrieve] key of single item to filter by * @param {TYPE.MetadataTypeMap} metadataMap saved metadata @@ -1631,7 +1631,7 @@ class MetadataType { return savedResults; } /** - * helper for {@link buildDefinitionForNested} + * helper for {@link MetadataType.buildDefinitionForNested} * searches extracted file for template variable names and applies the market values * * @param {string} code code from extracted code @@ -1643,7 +1643,7 @@ class MetadataType { return Mustache.render(code, templateVariables, {}, ['{{{', '}}}']); } /** - * helper for {@link buildTemplateForNested} + * helper for {@link MetadataType.buildTemplateForNested} * searches extracted file for template variable values and applies the market variable names * * @param {string} code code from extracted code @@ -1655,7 +1655,7 @@ class MetadataType { return Util.replaceByObject(code, templateVariables); } /** - * helper for {@link buildDefinition} + * helper for {@link MetadataType.buildDefinition} * handles extracted code if any are found for complex types (e.g script, asset, query) * * @param {string} templateDir Directory where metadata templates are stored @@ -1676,7 +1676,7 @@ class MetadataType { return null; } /** - * helper for {@link buildTemplate} + * helper for {@link MetadataType.buildTemplate} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored diff --git a/lib/metadataTypes/MobileKeyword.js b/lib/metadataTypes/MobileKeyword.js index 02ade31c3..12b796bc0 100644 --- a/lib/metadataTypes/MobileKeyword.js +++ b/lib/metadataTypes/MobileKeyword.js @@ -96,7 +96,7 @@ class MobileKeyword extends MetadataType { } /** - * helper for {@link parseResponseBody} that creates a custom key field for this type based on mobileCode and keyword + * helper for {@link MobileKeyword.parseResponseBody} that creates a custom key field for this type based on mobileCode and keyword * * @private * @param {TYPE.MetadataType} metadata single item @@ -106,7 +106,7 @@ class MobileKeyword extends MetadataType { } /** - * helper for {@link preDeployTasks} and {@link createOrUpdate} to ensure we have code & keyword properly set + * helper for {@link MobileKeyword.preDeployTasks} and {@link MobileKeyword.createOrUpdate} to ensure we have code & keyword properly set * * @private * @param {TYPE.MetadataType} metadata single item @@ -192,7 +192,7 @@ class MobileKeyword extends MetadataType { } /** - * helper for {@link retrieve} and {@link retrieveAsTemplate} + * helper for {@link MobileKeyword.retrieve} and {@link MobileKeyword.retrieveAsTemplate} * * @private * @param {string} key customer key of single item to retrieve / name of the metadata file @@ -281,7 +281,7 @@ class MobileKeyword extends MetadataType { } } /** - * helper for {@link parseMetadata} and {@link _buildForNested} + * helper for {@link MobileKeyword.postRetrieveTasks} and {@link MobileKeyword._buildForNested} * * @param {string} metadataScript the code of the file * @returns {{fileExt:string,code:string}} returns found extension and file content @@ -349,7 +349,7 @@ class MobileKeyword extends MetadataType { } /** - * helper for {@link buildTemplateForNested} / {@link buildDefinitionForNested} + * helper for {@link MobileKeyword.buildTemplateForNested} / {@link MobileKeyword.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored @@ -445,7 +445,7 @@ class MobileKeyword extends MetadataType { return metadata; } /** - * helper for {@link createREST} + * helper for {@link MetadataType.createREST} * * @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call @@ -455,7 +455,7 @@ class MobileKeyword extends MetadataType { await super.postDeployTasks_legacyApi(metadataEntry, apiResponse); } /** - * helper for {@link updateREST} + * helper for {@link MetadataType.updateREST} * * @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call @@ -466,7 +466,7 @@ class MobileKeyword extends MetadataType { } /** - * helper for {@link preDeployTasks} that loads extracted code content back into JSON + * helper for {@link MobileKeyword.preDeployTasks} that loads extracted code content back into JSON * * @param {TYPE.MetadataTypeItem} metadata a single definition * @param {string} deployDir directory of deploy files diff --git a/lib/metadataTypes/MobileMessage.js b/lib/metadataTypes/MobileMessage.js index a9a1f8227..8514b5cd0 100644 --- a/lib/metadataTypes/MobileMessage.js +++ b/lib/metadataTypes/MobileMessage.js @@ -83,7 +83,7 @@ class MobileMessage extends MetadataType { return super.createREST(metadata, '/legacy/v1/beta/mobile/message/'); } /** - * helper for {@link preDeployTasks} that loads extracted code content back into JSON + * helper for {@link MobileMessage.preDeployTasks} that loads extracted code content back into JSON * * @param {TYPE.MetadataTypeItem} metadata a single definition * @param {string} deployDir directory of deploy files @@ -110,7 +110,7 @@ class MobileMessage extends MetadataType { } } /** - * helper for {@link parseMetadata} and {@link _buildForNested} + * helper for {@link MobileMessage.postRetrieveTasks} and {@link MobileMessage._buildForNested} * * @param {string} code the code of the file * @returns {{fileExt:string,code:string}} returns found extension and file content @@ -304,7 +304,7 @@ class MobileMessage extends MetadataType { return metadata; } /** - * helper for {@link createREST} + * helper for {@link MetadataType.createREST} * * @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call @@ -314,7 +314,7 @@ class MobileMessage extends MetadataType { await super.postDeployTasks_legacyApi(metadataEntry, apiResponse); } /** - * helper for {@link updateREST} + * helper for {@link MetadataType.updateREST} * * @param {TYPE.MetadataTypeItem} metadataEntry a single metadata Entry * @param {object} apiResponse varies depending on the API call @@ -380,7 +380,7 @@ class MobileMessage extends MetadataType { } /** - * helper for {@link buildTemplateForNested} / {@link buildDefinitionForNested} + * helper for {@link MobileMessage.buildTemplateForNested} / {@link MobileMessage.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored diff --git a/lib/metadataTypes/Query.js b/lib/metadataTypes/Query.js index f33d9a9d4..4fe76d256 100644 --- a/lib/metadataTypes/Query.js +++ b/lib/metadataTypes/Query.js @@ -250,7 +250,7 @@ class Query extends MetadataType { return metadata; } /** - * helper for {@link buildDefinitionForNested} + * helper for {@link Query.buildDefinitionForNested} * searches extracted SQL file for template variables and applies the market values * * @param {string} code code from extracted code @@ -328,7 +328,7 @@ class Query extends MetadataType { ); } /** - * helper for {@link buildTemplateForNested} / {@link buildDefinitionForNested} + * helper for {@link Query.buildTemplateForNested} / {@link Query.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @private diff --git a/lib/metadataTypes/Script.js b/lib/metadataTypes/Script.js index aec027bfb..1f33b1c1f 100644 --- a/lib/metadataTypes/Script.js +++ b/lib/metadataTypes/Script.js @@ -82,7 +82,7 @@ class Script extends MetadataType { } /** - * helper for {@link preDeployTasks} that loads extracted code content back into JSON + * helper for {@link Script.preDeployTasks} that loads extracted code content back into JSON * * @param {TYPE.ScriptItem} metadata a single asset definition * @param {string} deployDir directory of deploy files @@ -189,7 +189,7 @@ class Script extends MetadataType { } /** - * helper for {@link buildTemplateForNested} / {@link buildDefinitionForNested} + * helper for {@link Script.buildTemplateForNested} / {@link Script.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored @@ -279,7 +279,7 @@ class Script extends MetadataType { return { json: metadata, codeArr: codeArr, subFolder: null }; } /** - * helper for {@link parseMetadata} and {@link _buildForNested} + * helper for {@link Script.parseMetadata} and {@link Script._buildForNested} * * @param {string} metadataScript the code of the file * @param {string} metadataName the name of the metadata diff --git a/lib/metadataTypes/TransactionalSMS.js b/lib/metadataTypes/TransactionalSMS.js index 4e9bfb3db..dd568c10c 100644 --- a/lib/metadataTypes/TransactionalSMS.js +++ b/lib/metadataTypes/TransactionalSMS.js @@ -66,7 +66,7 @@ class TransactionalSMS extends TransactionalMessage { return metadata; } /** - * helper for {@link preDeployTasks} that loads extracted code content back into JSON + * helper for {@link TransactionalSMS.preDeployTasks} that loads extracted code content back into JSON * * @param {TYPE.MetadataTypeItem} metadata a single definition * @param {string} deployDir directory of deploy files @@ -158,7 +158,7 @@ class TransactionalSMS extends TransactionalMessage { return { json: metadata, codeArr: codeArr, subFolder: null }; } /** - * helper for {@link parseMetadata} and {@link _buildForNested} + * helper for {@link TransactionalSMS.postRetrieveTasks} and {@link TransactionalSMS._buildForNested} * * @param {string} metadataScript the code of the file * @returns {{fileExt:string,code:string}} returns found extension and file content @@ -189,7 +189,7 @@ class TransactionalSMS extends TransactionalMessage { return { fileExt, code }; } /** - * helper for {@link MetadataType.buildDefinition} + * helper for {@link TransactionalMessage.buildDefinition} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored @@ -216,7 +216,7 @@ class TransactionalSMS extends TransactionalMessage { ); } /** - * helper for {@link MetadataType.buildTemplate} + * helper for {@link TransactionalMessage.buildTemplate} * handles extracted code if any are found for complex types * * @example scripts are saved as 1 json and 1 ssjs file. both files need to be run through templating @@ -245,7 +245,7 @@ class TransactionalSMS extends TransactionalMessage { } /** - * helper for {@link buildTemplateForNested} / {@link buildDefinitionForNested} + * helper for {@link TransactionalSMS.buildTemplateForNested} / {@link TransactionalSMS.buildDefinitionForNested} * handles extracted code if any are found for complex types * * @param {string} templateDir Directory where metadata templates are stored diff --git a/lib/metadataTypes/TriggeredSend.js b/lib/metadataTypes/TriggeredSend.js index 71d8bd35a..e0df317af 100644 --- a/lib/metadataTypes/TriggeredSend.js +++ b/lib/metadataTypes/TriggeredSend.js @@ -236,7 +236,7 @@ class TriggeredSend extends MetadataType { } /** - * helper for {@link refresh} that extracts the keys from the TSD item map and eli + * helper for {@link TriggeredSend.refresh} that extracts the keys from the TSD item map and eli * * @param {TYPE.MetadataTypeMapObj} metadata TSD item map * @returns {Promise.} keyArr @@ -250,7 +250,7 @@ class TriggeredSend extends MetadataType { return keyArr; } /** - * helper for {@link refresh} that finds active TSDs on the server and filters it by the same rules that {@link retrieve} is using to avoid refreshing TSDs with broken dependencies + * helper for {@link TriggeredSend.refresh} that finds active TSDs on the server and filters it by the same rules that {@link TriggeredSend.retrieve} is using to avoid refreshing TSDs with broken dependencies * * @param {boolean} [assetLoaded] if run after Asset.deploy via --refresh option this will skip caching assets * @returns {Promise.} Promise of TSD item map @@ -304,7 +304,7 @@ class TriggeredSend extends MetadataType { } /** - * helper for {@link refresh} that pauses, publishes and starts a triggered send + * helper for {@link TriggeredSend.refresh} that pauses, publishes and starts a triggered send * * @param {string} key external key of triggered send item * @param {boolean} checkKey whether to check if key exists on the server diff --git a/lib/metadataTypes/User.js b/lib/metadataTypes/User.js index 28e942215..5d86c32b4 100644 --- a/lib/metadataTypes/User.js +++ b/lib/metadataTypes/User.js @@ -740,7 +740,7 @@ class User extends MetadataType { } /** - * helper for {@link retrieveSOAP} + * helper for {@link User.retrieveSOAP} * * @private * @param {TYPE.SoapRequestParams} [requestParams] required for the specific request (filter for example) @@ -900,7 +900,7 @@ class User extends MetadataType { } } /** - * helper for {@link createOrUpdate} to generate a random initial password for new users + * helper for {@link User.createOrUpdate} to generate a random initial password for new users * note: possible minimum length values in SFMC are 6, 8, 10, 15 chars. Therefore we should default here to 15 chars. * * @private From 94ac24eff328346808c9a0a05d544fd6399fbb4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 4 Jul 2023 14:45:36 +0200 Subject: [PATCH 074/208] #870: fix query tests --- docs/dist/documentation.md | 94 ++++++++++++++++++++++++++------------ lib/cli.js | 4 +- lib/index.js | 42 +++++++++++++---- 3 files changed, 99 insertions(+), 41 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index d988436b2..8869a8e2e 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -186,6 +186,15 @@ Provides default functionality that can be overwritten by child metadata type cl
csvToArray(csv)Array.<string>

helper to convert CSVs into an array. if only one value was given, it's also returned as an array

+
Mcdev.(methodName, businessUnit, [selectedType], [keys])Promise.<boolean>
+

run a method across BUs

+
+
Mcdev.(methodName, cred, bu, [type], keyArr)Promise.<boolean>
+

helper for Mcdev.#runMethod

+
+
Mcdev.(selectedType, buObject)Array.<string>
+

helper for Mcdev.#runOnBU

+
Automation.(metadata)boolean

helper for postRetrieveTasks and execute

@@ -507,9 +516,8 @@ main class * [.buildDefinition(businessUnit, selectedType, name, market)](#Mcdev.buildDefinition) ⇒ Promise.<void> * [.buildDefinitionBulk(listName, type, name)](#Mcdev.buildDefinitionBulk) ⇒ Promise.<void> * [.getFilesToCommit(businessUnit, selectedType, keyArr)](#Mcdev.getFilesToCommit) ⇒ Promise.<Array.<string>> - * [.runMethod(methodName, businessUnit, [selectedType], [keys])](#Mcdev.runMethod) ⇒ Promise.<boolean> - * [._runOnBU(methodName, cred, bu, [type], keyArr)](#Mcdev._runOnBU) ⇒ Promise.<boolean> - * [._retrieveKeysWithLike(selectedType, buObject)](#Mcdev._retrieveKeysWithLike) ⇒ Array.<string> + * [.execute(businessUnit, [selectedType], [keys])](#Mcdev.execute) ⇒ Promise.<boolean> + * [.pause(businessUnit, [selectedType], [keys])](#Mcdev.pause) ⇒ Promise.<boolean> @@ -762,49 +770,33 @@ Build a specific metadata file based on a template using a list of bu-market com | selectedType | string | supported metadata type | | keyArr | Array.<string> | customerkey of the metadata | - + -### Mcdev.runMethod(methodName, businessUnit, [selectedType], [keys]) ⇒ Promise.<boolean> -Start an item (query) +### Mcdev.execute(businessUnit, [selectedType], [keys]) ⇒ Promise.<boolean> +Start/execute an item **Kind**: static method of [Mcdev](#Mcdev) **Returns**: Promise.<boolean> - true if all started successfully, false if not | Param | Type | Description | | --- | --- | --- | -| methodName | 'execute' \| 'pause' | what to run | | businessUnit | string | name of BU | | [selectedType] | TYPE.SupportedMetadataTypes | limit to given metadata types | | [keys] | Array.<string> | customerkey of the metadata | - - -### Mcdev.\_runOnBU(methodName, cred, bu, [type], keyArr) ⇒ Promise.<boolean> -helper for [runMethod](#Mcdev.runMethod) - -**Kind**: static method of [Mcdev](#Mcdev) -**Returns**: Promise.<boolean> - true if all items were executed, false otherwise - -| Param | Type | Description | -| --- | --- | --- | -| methodName | 'execute' \| 'pause' | what to run | -| cred | string | name of Credential | -| bu | string | name of BU | -| [type] | TYPE.SupportedMetadataTypes | limit execution to given metadata type | -| keyArr | Array.<string> | customerkey of the metadata | - - + -### Mcdev.\_retrieveKeysWithLike(selectedType, buObject) ⇒ Array.<string> -helper for [_runOnBU](#Mcdev._runOnBU) +### Mcdev.pause(businessUnit, [selectedType], [keys]) ⇒ Promise.<boolean> +pause an item **Kind**: static method of [Mcdev](#Mcdev) -**Returns**: Array.<string> - keyArr +**Returns**: Promise.<boolean> - true if all started successfully, false if not | Param | Type | Description | | --- | --- | --- | -| selectedType | TYPE.SupportedMetadataTypes | limit execution to given metadata type | -| buObject | TYPE.BuObject | properties for auth | +| businessUnit | string | name of BU | +| [selectedType] | TYPE.SupportedMetadataTypes | limit to given metadata types | +| [keys] | Array.<string> | customerkey of the metadata | @@ -8267,6 +8259,50 @@ helper to convert CSVs into an array. if only one value was given, it's also ret | --- | --- | --- | | csv | string | potentially comma-separated value or null | + + +## Mcdev.(methodName, businessUnit, [selectedType], [keys]) ⇒ Promise.<boolean> +run a method across BUs + +**Kind**: global function +**Returns**: Promise.<boolean> - true if all started successfully, false if not + +| Param | Type | Description | +| --- | --- | --- | +| methodName | 'execute' \| 'pause' | what to run | +| businessUnit | string | name of BU | +| [selectedType] | TYPE.SupportedMetadataTypes | limit to given metadata types | +| [keys] | Array.<string> | customerkey of the metadata | + + + +## Mcdev.(methodName, cred, bu, [type], keyArr) ⇒ Promise.<boolean> +helper for [Mcdev.#runMethod](Mcdev.#runMethod) + +**Kind**: global function +**Returns**: Promise.<boolean> - true if all items were executed, false otherwise + +| Param | Type | Description | +| --- | --- | --- | +| methodName | 'execute' \| 'pause' | what to run | +| cred | string | name of Credential | +| bu | string | name of BU | +| [type] | TYPE.SupportedMetadataTypes | limit execution to given metadata type | +| keyArr | Array.<string> | customerkey of the metadata | + + + +## Mcdev.(selectedType, buObject) ⇒ Array.<string> +helper for [Mcdev.#runOnBU](Mcdev.#runOnBU) + +**Kind**: global function +**Returns**: Array.<string> - keyArr + +| Param | Type | Description | +| --- | --- | --- | +| selectedType | TYPE.SupportedMetadataTypes | limit execution to given metadata type | +| buObject | TYPE.BuObject | properties for auth | + ## Automation.(metadata) ⇒ boolean diff --git a/lib/cli.js b/lib/cli.js index ddec010e8..36476badb 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -435,7 +435,7 @@ yargs handler: (argv) => { Mcdev.setOptions(argv); // ! do not allow multiple types to be passed in here via csvToArray - Mcdev.runMethod('execute', argv.BU, argv.TYPE, csvToArray(argv.KEY)); + Mcdev.execute(argv.BU, argv.TYPE, csvToArray(argv.KEY)); }, }) .command({ @@ -466,7 +466,7 @@ yargs handler: (argv) => { Mcdev.setOptions(argv); // ! do not allow multiple types to be passed in here via csvToArray - Mcdev.runMethod('pause', argv.BU, argv.TYPE, csvToArray(argv.KEY)); + Mcdev.pause(argv.BU, argv.TYPE, csvToArray(argv.KEY)); }, }) .command({ diff --git a/lib/index.js b/lib/index.js index 245992499..35274e4b6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -703,7 +703,29 @@ class Mcdev { } } /** - * Start an item (query) + * Start/execute an item + * + * @param {string} businessUnit name of BU + * @param {TYPE.SupportedMetadataTypes} [selectedType] limit to given metadata types + * @param {string[]} [keys] customerkey of the metadata + * @returns {Promise.} true if all started successfully, false if not + */ + static async execute(businessUnit, selectedType, keys) { + return this.#runMethod('execute', businessUnit, selectedType, keys); + } + /** + * pause an item + * + * @param {string} businessUnit name of BU + * @param {TYPE.SupportedMetadataTypes} [selectedType] limit to given metadata types + * @param {string[]} [keys] customerkey of the metadata + * @returns {Promise.} true if all started successfully, false if not + */ + static async pause(businessUnit, selectedType, keys) { + return this.#runMethod('pause', businessUnit, selectedType, keys); + } + /** + * run a method across BUs * * @param {'execute'|'pause'} methodName what to run * @param {string} businessUnit name of BU @@ -711,7 +733,7 @@ class Mcdev { * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.} true if all started successfully, false if not */ - static async runMethod(methodName, businessUnit, selectedType, keys) { + static async #runMethod(methodName, businessUnit, selectedType, keys) { Util.startLogger(); let lang_past; let lang_present; @@ -770,7 +792,7 @@ class Mcdev { Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`); for (const bu in properties.credentials[cred].businessUnits) { - if (await this._runOnBU(methodName, cred, bu, selectedType, keys)) { + if (await this.#runOnBU(methodName, cred, bu, selectedType, keys)) { counter_credBu++; } else { counter_failed++; @@ -810,7 +832,7 @@ class Mcdev { Util.logger.info(`:: ${lang_present} ${selectedType} on all BUs for ${cred}`); let counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { - if (await this._runOnBU(methodName, cred, bu, selectedType, keys)) { + if (await this.#runOnBU(methodName, cred, bu, selectedType, keys)) { counter_credBu++; } else { counter_failed++; @@ -822,7 +844,7 @@ class Mcdev { ); } else { // execute runMethod for the entity on one BU only - if (await this._runOnBU(methodName, cred, bu, selectedType, keys)) { + if (await this.#runOnBU(methodName, cred, bu, selectedType, keys)) { counter_credBu++; } else { counter_failed++; @@ -836,7 +858,7 @@ class Mcdev { return counter_failed === 0 ? true : false; } /** - * helper for {@link Mcdev.runMethod} + * helper for {@link Mcdev.#runMethod} * * @param {'execute'|'pause'} methodName what to run * @param {string} cred name of Credential @@ -845,7 +867,7 @@ class Mcdev { * @param {string[]} keyArr customerkey of the metadata * @returns {Promise.} true if all items were executed, false otherwise */ - static async _runOnBU(methodName, cred, bu, type, keyArr) { + static async #runOnBU(methodName, cred, bu, type, keyArr) { const properties = await config.getProperties(); let counter_failed = 0; const buObject = await Cli.getCredentialObject( @@ -866,7 +888,7 @@ class Mcdev { Util.logger.info(`:: ${methodName} ${type} on ${cred}/${bu}`); MetadataTypeInfo[type].client = auth.getSDK(buObject); if (Util.OPTIONS.like && Object.keys(Util.OPTIONS.like).length) { - keyArr = await this._retrieveKeysWithLike(type, buObject); + keyArr = await this.#retrieveKeysWithLike(type, buObject); } else { MetadataTypeInfo[type].properties = properties; MetadataTypeInfo[type].buObject = buObject; @@ -887,13 +909,13 @@ class Mcdev { } /** - * helper for {@link Mcdev._runOnBU} + * helper for {@link Mcdev.#runOnBU} * * @param {TYPE.SupportedMetadataTypes} selectedType limit execution to given metadata type * @param {TYPE.BuObject} buObject properties for auth * @returns {string[]} keyArr */ - static async _retrieveKeysWithLike(selectedType, buObject) { + static async #retrieveKeysWithLike(selectedType, buObject) { const properties = await config.getProperties(); // cache depenencies From cb2cbb5023bcf49b3c7101543a6b04b530c23442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 4 Jul 2023 14:48:35 +0200 Subject: [PATCH 075/208] #870: refactoring --- lib/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/index.js b/lib/index.js index 35274e4b6..34543998f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -181,7 +181,7 @@ class Mcdev { Util.logger.info(`:: Retrieving all BUs for ${cred}`); let counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { - await this._retrieveBU(cred, bu, selectedTypesArr, keys); + await this.#retrieveBU(cred, bu, selectedTypesArr, keys); counter_credBu++; Util.startLogger(true); } @@ -215,14 +215,14 @@ class Mcdev { Util.logger.info(`:: Retrieving all BUs for ${cred}`); let counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { - await this._retrieveBU(cred, bu, selectedTypesArr, keys); + await this.#retrieveBU(cred, bu, selectedTypesArr, keys); counter_credBu++; Util.startLogger(true); } Util.logger.info(`:: ${counter_credBu} BUs for ${cred}\n`); } else { // retrieve a single BU; return - const retrieveChangelog = await this._retrieveBU( + const retrieveChangelog = await this.#retrieveBU( cred, bu, selectedTypesArr, @@ -247,7 +247,7 @@ class Mcdev { * @param {boolean} [changelogOnly] skip saving, only create json in memory * @returns {Promise.} ensure that BUs are worked on sequentially */ - static async _retrieveBU(cred, bu, selectedTypesArr, keys, changelogOnly) { + static async #retrieveBU(cred, bu, selectedTypesArr, keys, changelogOnly) { const properties = await config.getProperties(); if (!(await config.checkProperties(properties))) { return null; From 5b288b579b99773b48c62e040952e6b5ea2f2f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 4 Jul 2023 14:51:02 +0200 Subject: [PATCH 076/208] #870: fix automation tests --- test/resources/9999999/automation/build-expected.json | 3 +-- test/resources/9999999/automation/create-expected.json | 3 +-- test/resources/9999999/automation/retrieve-expected.json | 3 +-- test/resources/9999999/automation/template-expected.json | 3 +-- test/resources/9999999/automation/update-expected.json | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/test/resources/9999999/automation/build-expected.json b/test/resources/9999999/automation/build-expected.json index ecd94cb33..87301aa55 100644 --- a/test/resources/9999999/automation/build-expected.json +++ b/test/resources/9999999/automation/build-expected.json @@ -7,8 +7,7 @@ "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", - "timezoneName": "W. Europe Standard Time", - "typeId": 3 + "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ diff --git a/test/resources/9999999/automation/create-expected.json b/test/resources/9999999/automation/create-expected.json index 2a1caee12..e22edb382 100644 --- a/test/resources/9999999/automation/create-expected.json +++ b/test/resources/9999999/automation/create-expected.json @@ -7,8 +7,7 @@ "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", - "timezoneName": "W. Europe Standard Time", - "typeId": 3 + "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ diff --git a/test/resources/9999999/automation/retrieve-expected.json b/test/resources/9999999/automation/retrieve-expected.json index fa80b0f99..f4771678a 100644 --- a/test/resources/9999999/automation/retrieve-expected.json +++ b/test/resources/9999999/automation/retrieve-expected.json @@ -7,8 +7,7 @@ "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", - "timezoneName": "W. Europe Standard Time", - "typeId": 3 + "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ diff --git a/test/resources/9999999/automation/template-expected.json b/test/resources/9999999/automation/template-expected.json index 038ecc7ff..32a6bcbc5 100644 --- a/test/resources/9999999/automation/template-expected.json +++ b/test/resources/9999999/automation/template-expected.json @@ -7,8 +7,7 @@ "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", - "timezoneName": "W. Europe Standard Time", - "typeId": 3 + "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ diff --git a/test/resources/9999999/automation/update-expected.json b/test/resources/9999999/automation/update-expected.json index 47860e944..0705285b5 100644 --- a/test/resources/9999999/automation/update-expected.json +++ b/test/resources/9999999/automation/update-expected.json @@ -7,8 +7,7 @@ "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", - "timezoneName": "W. Europe Standard Time", - "typeId": 3 + "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ From 70c5f0fd4602d99fe5d036686a8e826a99a04aad Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Wed, 5 Jul 2023 09:24:16 +0200 Subject: [PATCH 077/208] #38: added a test for query fixKeys --- lib/index.js | 23 +++++--- .../query/testNew_query1.query-meta.json | 11 ++++ .../query/testNew_query1.query-meta.sql | 4 ++ .../patch-response.json | 17 ++++++ .../automation/v1/queries/get-response.json | 17 ++++++ .../9999999/query/post2-expected.json | 11 ++++ .../9999999/query/post2-expected.sql | 4 ++ test/type.query.test.js | 54 +++++++++++++++++-- 8 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json create mode 100644 test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.sql create mode 100644 test/resources/9999999/automation/v1/queries/b28a1c2f-6656-478a-be51-4f12be4c9088/patch-response.json create mode 100644 test/resources/9999999/query/post2-expected.json create mode 100644 test/resources/9999999/query/post2-expected.sql diff --git a/lib/index.js b/lib/index.js index f250aabc6..b0401012a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -882,7 +882,7 @@ class Mcdev { Util.logger.error('fixKeys expects a single type to be deployed'); return null; } - if (type.definition.keyField === this.definition.idField) { + if (MetadataTypeDefinitions[type].keyField === MetadataTypeDefinitions[type].idField) { Util.logger.error(`Key cannot be updated for this type`); return null; } @@ -926,11 +926,13 @@ class Mcdev { * @param {string} bu name of BU * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit execution to given metadata type * @param {string[]} keyArr customerkey of the metadata - * @returns {Promise.>} deployed metadata per BU (first key: bu name, second key: metadata type) + * @returns {Promise.} true if all successfully, false if not */ static async _fixKeysBU(cred, bu, type, keyArr) { const properties = await config.getProperties(); - let counter_failed = 0; + let counter_success = 0; + let numItemsToUpdate = 0; + let deployed; const toDeploy = []; const buObject = await Cli.getCredentialObject( properties, @@ -956,11 +958,20 @@ class Mcdev { const retrieved = await retriever.retrieve(type, keyArr, null, false); Object.keys(retrieved).forEach((key) => { for (const item of Object.values(retrieved[key][0])) { + if (item.name.length > MetadataTypeDefinitions[type].maxKeyLength) { + Util.logger.warn( + `Name of the item ${item.key} is too long for a key. Consider renaming your item. Key will be equal first ${MetadataTypeDefinitions[type].maxKeyLength} characters of the name` + ); + item.name = item.name.slice(0, MetadataTypeDefinitions[type].maxKeyLength); + } + numItemsToUpdate = Object.values(retrieved[key][0]).length; if (item != null) { - if (item.name != item.key) { + if (item.name != item.key && !MetadataTypeDefinitions[type].keyIsFixed) { toDeploy.push(item.key); + counter_success++; Util.logger.info(`Updating key for query ${item.key}`); } else { + numItemsToUpdate--; Util.logger.info( ` ☇ skipping query ${item.key} - key does not need to be updated` ); @@ -972,12 +983,12 @@ class Mcdev { }); Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; properties.directories.deploy = properties.directories.retrieve; - await Deployer._deployBU(cred, bu, properties, type, toDeploy, true); + deployed = await Deployer._deployBU(cred, bu, properties, type, toDeploy, true); this._retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } - return counter_failed === 0 ? true : false; + return numItemsToUpdate === Object.values(deployed).length ? true : false; } } diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json b/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json new file mode 100644 index 000000000..c29f18dc3 --- /dev/null +++ b/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json @@ -0,0 +1,11 @@ +{ + "name": "updateMePlease", + "key": "testNew_query1", + "description": "created on deploy", + "targetKey": "testExisting_dataExtension", + "createdDate": "2022-04-26T15:21:16.453", + "modifiedDate": "2022-04-26T16:04:15.88", + "targetUpdateTypeName": "Overwrite", + "isFrozen": false, + "r__folder_Path": "Query" +} diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.sql b/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.sql new file mode 100644 index 000000000..8020314ea --- /dev/null +++ b/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.sql @@ -0,0 +1,4 @@ +SELECT + SubscriberKey as testField +FROM + _Subscribers diff --git a/test/resources/9999999/automation/v1/queries/b28a1c2f-6656-478a-be51-4f12be4c9088/patch-response.json b/test/resources/9999999/automation/v1/queries/b28a1c2f-6656-478a-be51-4f12be4c9088/patch-response.json new file mode 100644 index 000000000..8b09c6842 --- /dev/null +++ b/test/resources/9999999/automation/v1/queries/b28a1c2f-6656-478a-be51-4f12be4c9088/patch-response.json @@ -0,0 +1,17 @@ +{ + "queryDefinitionId": "b28a1c2f-6656-478a-be51-4f12be4c9088", + "name": "updateMePlease", + "key": "updateMePlease", + "description": "bla bla", + "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", + "targetName": "testExisting_dataExtension", + "targetKey": "testExisting_dataExtension-WRONG", + "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", + "targetDescription": "", + "createdDate": "2022-04-26T15:21:16.453", + "modifiedDate": "2022-04-26T16:02:44.01", + "targetUpdateTypeId": 0, + "targetUpdateTypeName": "Overwrite", + "categoryId": 999, + "isFrozen": false +} diff --git a/test/resources/9999999/automation/v1/queries/get-response.json b/test/resources/9999999/automation/v1/queries/get-response.json index 4a7b047ec..31305c1f3 100644 --- a/test/resources/9999999/automation/v1/queries/get-response.json +++ b/test/resources/9999999/automation/v1/queries/get-response.json @@ -36,6 +36,23 @@ "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false + }, + { + "queryDefinitionId": "b28a1c2f-6656-478a-be51-4f12be4c9088", + "name": "updateMePlease", + "key": "testNew_query1", + "description": "bla bla", + "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", + "targetName": "testExisting_dataExtension", + "targetKey": "testExisting_dataExtension-WRONG", + "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", + "targetDescription": "", + "createdDate": "2022-04-26T15:21:16.453", + "modifiedDate": "2022-04-26T16:02:44.01", + "targetUpdateTypeId": 0, + "targetUpdateTypeName": "Overwrite", + "categoryId": 999, + "isFrozen": false } ] } diff --git a/test/resources/9999999/query/post2-expected.json b/test/resources/9999999/query/post2-expected.json new file mode 100644 index 000000000..95177685f --- /dev/null +++ b/test/resources/9999999/query/post2-expected.json @@ -0,0 +1,11 @@ +{ + "name": "updateMePlease", + "key": "testNew_query", + "description": "created on deploy", + "targetKey": "testExisting_dataExtension", + "createdDate": "2022-04-26T15:21:16.453", + "modifiedDate": "2022-04-26T16:04:15.88", + "targetUpdateTypeName": "Overwrite", + "isFrozen": false, + "r__folder_Path": "Query" +} diff --git a/test/resources/9999999/query/post2-expected.sql b/test/resources/9999999/query/post2-expected.sql new file mode 100644 index 000000000..4148833c4 --- /dev/null +++ b/test/resources/9999999/query/post2-expected.sql @@ -0,0 +1,4 @@ +SELECT + SubscriberKey AS testField +FROM + _Subscribers diff --git a/test/type.query.test.js b/test/type.query.test.js index edaf72161..c4b26bedf 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -27,7 +27,7 @@ describe('type: query', () => { const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 2, + 3, 'only two queries expected' ); // normal test @@ -87,14 +87,18 @@ describe('type: query', () => { }); it('Should create & upsert a query', async () => { // WHEN - await handler.deploy('testInstance/testBU', ['query']); + await handler.deploy( + 'testInstance/testBU', + ['query'], + ['testNew_query', 'testExisting_query'] + ); // THEN assert.equal(process.exitCode, false, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 3, + 4, 'three queries expected' ); // confirm created item @@ -125,6 +129,50 @@ describe('type: query', () => { }); it('Should change the key during update with --changeKeyValue'); }); + describe('FixKeys ================', () => { + beforeEach(() => { + testUtils.mockSetup(true); + }); + it('Should create & upsert a query', async () => { + // WHEN + await handler.deploy('testInstance/testBU', ['query']); + // THEN + assert.equal(process.exitCode, false, 'deploy should not have thrown an error'); + // get results from cache + const result = cache.getCache(); + assert.equal( + result.query ? Object.keys(result.query).length : 0, + 4, + 'three queries expected' + ); + // confirm created item + // assert.deepEqual( + // await testUtils.getActualJson('testNew_query', 'query'), + // await testUtils.getExpectedJson('9999999', 'query', 'post'), + // 'returned metadata was not equal expected for insert query' + // ); + // expect(file(testUtils.getActualFile('testNew_query', 'query', 'sql'))).to.equal( + // file(testUtils.getExpectedFile('9999999', 'query', 'post', 'sql')) + // ); + // // confirm updated item + // assert.deepEqual( + // await testUtils.getActualJson('testExisting_query', 'query'), + // await testUtils.getExpectedJson('9999999', 'query', 'patch'), + // 'returned metadata was not equal expected for insert query' + // ); + // expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.equal( + // file(testUtils.getExpectedFile('9999999', 'query', 'patch', 'sql')) + // ); + // // check number of API calls + // assert.equal( + // testUtils.getAPIHistoryLength(), + // 8, + // 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + // ); + return; + }); + it('Should change the key during update with --changeKeyValue'); + }); describe('Templating ================', () => { it('Should create a query template via retrieveAsTemplate and build it', async () => { // GIVEN there is a template From 75a74d8fdbecf8766d94245de4f10e250861d1c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 5 Jul 2023 09:43:16 +0200 Subject: [PATCH 078/208] #870: make standard create test auto-schedule the new automation (not via --execute) needed to add support for testing SOAP-Schedule callouts --- lib/metadataTypes/Automation.js | 36 ++++++++++--- .../definitions/Automation.definition.js | 22 ++++---- ...stExisting_automation.automation-meta.json | 3 +- .../testNew_automation.automation-meta.json | 11 ++-- test/resourceFactory.js | 23 ++++++-- .../9999999/automation/create-expected.json | 14 ++--- .../create-testNew_automation-expected.md | 6 +-- ...2-b00a-4c88-ad2e-1f7f8788c560-response.xml | 52 +++++++++++++++++++ .../v1/automations/post-response.json | 39 +++++++------- test/type.automation.test.js | 2 +- 10 files changed, 147 insertions(+), 61 deletions(-) create mode 100644 test/resources/9999999/automation/schedule-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index d2e59ed23..c6f7caaca 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -805,6 +805,30 @@ class Automation extends MetadataType { */ static async postDeployTasks(metadataMap, originalMetadataMap) { for (const key in metadataMap) { + if (!metadataMap[key].type) { + // create response does not return the type attribute + + // el.schedule.timezoneName + const scheduleHelper = + metadataMap[key].schedule || metadataMap[key].startSource.schedule; + scheduleHelper.timezoneName ||= Util.inverseGet( + this.definition.timeZoneMapping, + scheduleHelper.timezoneId + ); + + // el.type + metadataMap[key].type = scheduleHelper + ? 'scheduled' + : metadataMap[key].fileTrigger + ? 'triggered' + : undefined; + + // el.status + metadataMap[key].status ||= Util.inverseGet( + this.definition.statusMapping, + metadataMap[key].statusId + ); + } // need to put schedule on here if status is scheduled await Automation.#scheduleAutomation(metadataMap, originalMetadataMap, key); @@ -923,12 +947,10 @@ class Automation extends MetadataType { schedule_StartDateTime.split('T').join(' ').split('.')[0] } ${schedule_timezoneString}` ); - } catch (ex) { - this._handleSOAPErrors( - ex, - 'starting scheduled', - originalMetadataMap, - false + } catch { + // API does not return anything usefull here. We have to know the rules instead + Util.logger.error( + ` ☇ error starting scheduled ${this.definition.type}${key}: Please check schedule settings` ); } } @@ -1200,7 +1222,7 @@ class Automation extends MetadataType { const automationType = { scheduled: 'Schedule', triggered: 'File Drop' }; output += `**Started by:** ${automationType[json.type] || 'Not defined'}\n\n`; output += `**Status:** ${json.status}\n\n`; - if (json.type === 'scheduled') { + if (json.type === 'scheduled' || json.schedule) { const tz = this.definition.timeZoneDifference[ this.definition.timeZoneMapping[json?.schedule?.timezoneName] diff --git a/lib/metadataTypes/definitions/Automation.definition.js b/lib/metadataTypes/definitions/Automation.definition.js index 719ec6005..e34b258ca 100644 --- a/lib/metadataTypes/definitions/Automation.definition.js +++ b/lib/metadataTypes/definitions/Automation.definition.js @@ -42,10 +42,10 @@ module.exports = { keyField: 'key', nameField: 'name', folderIdField: 'categoryId', - createdDateField: 'createdDate', - createdNameField: 'createdByName', - lastmodDateField: 'lastSavedDate', - lastmodNameField: 'lastSavedByName', + createdDateField: 'createdDate', // only returned by upsert + createdNameField: 'createdByName', // only returned by upsert + lastmodDateField: 'lastSavedDate', // only returned by upsert + lastmodNameField: 'lastSavedByName', // only returned by upsert restPagination: true, maxKeyLength: 200, // confirmed max length scheduleTypeMapping: { @@ -343,31 +343,31 @@ module.exports = { lastSavedDate: { isCreateable: false, isUpdateable: false, - retrieving: true, + retrieving: false, // only returned by upsert template: false, }, lastSavedByName: { isCreateable: false, isUpdateable: false, - retrieving: true, + retrieving: false, // only returned by upsert template: false, }, createdDate: { isCreateable: false, isUpdateable: false, - retrieving: true, + retrieving: false, // only returned by upsert template: false, }, createdByName: { isCreateable: false, isUpdateable: false, - retrieving: true, + retrieving: false, // only returned by upsertt template: false, }, updateInProgress: { isCreateable: false, isUpdateable: false, - retrieving: true, + retrieving: false, template: false, }, name: { @@ -481,8 +481,8 @@ module.exports = { 'schedule.timezoneId': { isCreateable: true, isUpdateable: true, - retrieving: true, - template: true, + retrieving: false, + template: false, }, 'schedule.timezoneName': { isCreateable: true, diff --git a/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json b/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json index b901a271a..0110ca3e6 100644 --- a/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json +++ b/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json @@ -7,8 +7,7 @@ "endDate": "2022-07-30T00:00:00", "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", "startDate": "2022-07-30T00:00:00", - "timezoneName": "W. Europe Standard Time", - "typeId": 3 + "timezoneName": "W. Europe Standard Time" }, "status": "PausedSchedule", "steps": [ diff --git a/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json b/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json index 2a1caee12..715b69f27 100644 --- a/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json +++ b/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json @@ -4,13 +4,12 @@ "name": "testNew_automation", "r__folder_Path": "my automations", "schedule": { - "endDate": "2022-07-30T00:00:00", - "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", - "startDate": "2022-07-30T00:00:00", - "timezoneName": "W. Europe Standard Time", - "typeId": 3 + "startDate": "2020-05-14T02:30:32.11", + "endDate": "2079-06-06T21:00:00", + "icalRecur": "FREQ=MINUTELY;UNTIL=20790607T050000;INTERVAL=5", + "timezoneName": "W. Europe Standard Time" }, - "status": "PausedSchedule", + "status": "Scheduled", "steps": [ { "activities": [ diff --git a/test/resourceFactory.js b/test/resourceFactory.js index a8100c963..766eced42 100644 --- a/test/resourceFactory.js +++ b/test/resourceFactory.js @@ -10,13 +10,14 @@ const attributeParser = new XMLParser({ ignoreAttributes: false }); * @param {string} mcdevAction SOAP action * @param {string} type metadata Type * @param {string} mid of Business Unit - * @param {object} filter likely for customer key + * @param {object|string} filter likely for customer key * @returns {string} relevant metadata stringified */ exports.loadSOAPRecords = async (mcdevAction, type, mid, filter) => { type = type[0].toLowerCase() + type.slice(1); const testPath = path.join('test', 'resources', mid.toString(), type, mcdevAction); - const filterPath = this.filterToPath(filter); + const filterPath = + typeof filter === 'string' && filter ? '-' + filter : this.filterToPath(filter); if (await fs.pathExists(testPath + filterPath + '-response.xml')) { return fs.readFile(testPath + filterPath + '-response.xml', { encoding: 'utf8', @@ -42,8 +43,8 @@ exports.loadSOAPRecords = async (mcdevAction, type, mid, filter) => { /* eslint-disable no-console */ console.log( `${color.bgRed}${color.fgBlack}test-error${color.reset}: Please create file ${ - testPath + filterPath + '-response.xml' - } or ${testPath + '-response.xml'}` + filterPath ? testPath + filterPath + '-response.xml or ' : '' + }${testPath + '-response.xml'}` ); /* eslint-enable no-console */ @@ -138,8 +139,20 @@ exports.handleSOAPRequest = async (config) => { break; } + case 'Schedule': { + responseXML = await this.loadSOAPRecords( + config.headers.SOAPAction.toLocaleLowerCase(), + fullObj.Envelope.Body.ScheduleRequestMsg.Interactions.Interaction['@_xsi:type'], + jObj.Envelope.Header.fueloauth, + fullObj.Envelope.Body.ScheduleRequestMsg.Interactions.Interaction.ObjectID + ); + + break; + } default: { - throw new Error('This SOAP Action is not supported by test handler'); + throw new Error( + `The SOAP Action ${config.headers.SOAPAction} is not supported by test handler` + ); } } diff --git a/test/resources/9999999/automation/create-expected.json b/test/resources/9999999/automation/create-expected.json index e22edb382..953d935af 100644 --- a/test/resources/9999999/automation/create-expected.json +++ b/test/resources/9999999/automation/create-expected.json @@ -3,13 +3,14 @@ "key": "testNew_automation", "name": "testNew_automation", "r__folder_Path": "my automations", - "schedule": { - "endDate": "2022-07-30T00:00:00", - "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", - "startDate": "2022-07-30T00:00:00", + "type": "scheduled", + "status": "PausedSchedule", + "schedule": { + "endDate": "2079-06-06T21:00:00-06:00", + "icalRecur": "FREQ=MINUTELY;UNTIL=20790607T050000;INTERVAL=5", + "startDate": "2020-05-13T18:30:32.11-06:00", "timezoneName": "W. Europe Standard Time" }, - "status": "PausedSchedule", "steps": [ { "activities": [ @@ -40,6 +41,5 @@ ], "name": "" } - ], - "type": "scheduled" + ] } diff --git a/test/resources/9999999/automation/create-testNew_automation-expected.md b/test/resources/9999999/automation/create-testNew_automation-expected.md index d596cc549..4e0ea77ff 100644 --- a/test/resources/9999999/automation/create-testNew_automation-expected.md +++ b/test/resources/9999999/automation/create-testNew_automation-expected.md @@ -10,10 +10,10 @@ **Schedule:** -* Start: 2022-07-30 00:00:00 +01:00 -* End: 2022-07-30 00:00:00 +01:00 +* Start: 2020-05-13 18:30:32.11-06:00 +01:00 +* End: 2079-06-06 21:00:00-06:00 +01:00 * Timezone: W. Europe Standard Time -* Recurrance: every day for 1 times +* Recurrance: every 5 minutes **Notifications:** _none_ diff --git a/test/resources/9999999/automation/schedule-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml b/test/resources/9999999/automation/schedule-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml new file mode 100644 index 000000000..c0876dbef --- /dev/null +++ b/test/resources/9999999/automation/schedule-a8afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml @@ -0,0 +1,52 @@ + + + + ScheduleResponse + urn:uuid:6c743640-b80f-456a-abed-b542247f2414 + urn:uuid:29fc6536-3c75-4e07-a05d-e63f7ee520d3 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-07-04T13:13:15Z + 2023-07-04T13:18:15Z + + + + + + + + OK + Program scheduled. + 89cd977a-3927-49fa-b8e5-47c7e6093bef + + + + + Interval + 5 + + Minutely + EndOn + 2023-07-04T06:21:14.408 + 2079-06-06T20:00:00 + + + 5 + + + + + + + OK + + 3b03417b-649e-4a1d-963d-05f42fc8f1b5 + + + diff --git a/test/resources/9999999/automation/v1/automations/post-response.json b/test/resources/9999999/automation/v1/automations/post-response.json index 6f82ef7c9..ba11ebf1e 100644 --- a/test/resources/9999999/automation/v1/automations/post-response.json +++ b/test/resources/9999999/automation/v1/automations/post-response.json @@ -1,25 +1,28 @@ { + "id": "a8afb0e2-b00a-4c88-ad2e-1f7f8788c560", "legacyId": "NewRkpOcE9qSVh2VUdnYTVJbWFfWW14dzoyNTow", "name": "testNew_automation", "description": "created on deploy", "key": "testNew_automation", - "typeId": 1, - "type": "scheduled", + "categoryId": 290937, "statusId": 4, - "status": "PausedSchedule", - "schedule": { - "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", - "typeId": 3, - "startDate": "2022-07-30T00:00:00", - "endDate": "2022-07-30T00:00:00", - "scheduledTime": "0001-01-01T07:00:00", - "rangeTypeId": 0, - "occurrences": 1, - "pattern": "01", - "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", - "timezoneName": "W. Europe Standard Time", - "scheduleStatus": "paused", - "timezoneId": 5 + "lastSavedDate": "2023-07-04T07:49:08.577", + "lastSavedByName": "SFMC DevTools app user", + "createdDate": "2023-07-04T07:49:08.297", + "createdByName": "SFMC DevTools app user", + "updateInProgress": false, + "startSource": { + "typeId": 1, + "schedule": { + "scheduleTypeId": 1, + "startDate": "2020-05-13T18:30:32.11-06:00", + "endDate": "2079-06-06T21:00:00-06:00", + "rangeTypeId": 1, + "occurrences": 6213054, + "icalRecur": "FREQ=MINUTELY;UNTIL=20790607T050000;INTERVAL=5", + "timezoneId": 5, + "statusId": 0 + } }, "steps": [ { @@ -79,7 +82,5 @@ "annotation": "", "stepNumber": 0 } - ], - "categoryId": 290937, - "id": "a8afb0e2-b00a-4c88-ad2e-1f7f8788c560" + ] } diff --git a/test/type.automation.test.js b/test/type.automation.test.js index 5f9dd60bb..8ba01b767 100644 --- a/test/type.automation.test.js +++ b/test/type.automation.test.js @@ -111,7 +111,7 @@ describe('type: automation', () => { assert.equal( testUtils.getAPIHistoryLength(), - 15, + 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; From 7b3b60e1362074eb9b434d53a8b3cb7a670a5ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 5 Jul 2023 13:06:33 +0200 Subject: [PATCH 079/208] #870: add tests for execute automation --- lib/metadataTypes/Automation.js | 4 ++ ...2-b00a-4c88-ad2e-1f7f8788c560-response.xml | 52 ++++++++++++++ test/type.automation.test.js | 68 ++++++++++++++++++- 3 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index c6f7caaca..e9d493f4b 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -844,6 +844,10 @@ class Automation extends MetadataType { } } } + if (Util.OPTIONS.execute) { + Util.logger.info(`Executing: ${this.definition.type}`); + await this.execute(Object.keys(metadataMap)); + } } /** * helper for {@link Automation.postDeployTasks} diff --git a/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml b/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml new file mode 100644 index 000000000..55576611b --- /dev/null +++ b/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml @@ -0,0 +1,52 @@ + + + + ScheduleResponse + urn:uuid:b58a82d9-a251-4be4-b50c-bd300d71601d + urn:uuid:9d3dbeb3-68b7-4f0a-b0af-04855dc0fd1e + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-07-05T10:29:58Z + 2023-07-05T10:34:58Z + + + + + + + + OK + Program scheduled. + 3a677ca8-5423-4d59-a1bb-c5fbe1c87197 + + + + + Interval + 1 + + Daily + EndAfter + 2023-07-05T16:00:57 + 1 + + + 5 + + + + + + + OK + + cfe97488-3c5e-49a9-b338-c0e9f6b6f684 + + + \ No newline at end of file diff --git a/test/type.automation.test.js b/test/type.automation.test.js index 8ba01b767..db54a7a3a 100644 --- a/test/type.automation.test.js +++ b/test/type.automation.test.js @@ -97,13 +97,49 @@ describe('type: automation', () => { ) ); + assert.equal( + testUtils.getAPIHistoryLength(), + 16, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + it('Should update & start an automation with --execute option', async () => { + // WHEN + handler.setOptions({ execute: true }); + await handler.deploy( + 'testInstance/testBU', + ['automation'], + ['testExisting_automation'] + ); + // THEN + assert.equal( + process.exitCode, + false, + 'deploy with --execute should not have thrown an error' + ); + + // get results from cache + const result = cache.getCache(); + assert.equal( + result.automation ? Object.keys(result.automation).length : 0, + 1, + 'one automation expected' + ); + + // update + assert.deepEqual( + await testUtils.getActualJson('testExisting_automation', 'automation'), + await testUtils.getExpectedJson('9999999', 'automation', 'update'), + 'returned metadata was not equal expected for update' + ); // check if MD file was created and equals expectations - expect(file(testUtils.getActualDoc('testNew_automation', 'automation'))).to.equal( + expect(file(testUtils.getActualDoc('testExisting_automation', 'automation'))).to.equal( file( testUtils.getExpectedFile( '9999999', 'automation', - 'create-testNew_automation', + 'update-testExisting_automation', 'md' ) ) @@ -111,7 +147,7 @@ describe('type: automation', () => { assert.equal( testUtils.getAPIHistoryLength(), - 16, + 19, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; @@ -256,4 +292,30 @@ describe('type: automation', () => { return; }); }); + describe('Execute ================', () => { + it('Should start an automation by key', async () => { + const execute = await handler.execute('testInstance/testBU', 'automation', [ + 'testExisting_automation', + ]); + assert.equal(process.exitCode, false, 'execute should not have thrown an error'); + assert.equal(execute, true, 'automation was supposed to be executed'); + return; + }); + it('Should start an automation selected via --like', async () => { + handler.setOptions({ like: { key: 'testExist%automation' } }); + const execute = await handler.execute('testInstance/testBU', 'automation'); + assert.equal(process.exitCode, false, 'execute should not have thrown an error'); + assert.equal(execute, true, 'automation was supposed to be executed'); + return; + }); + it('Should not start executing an automation because key and --like was specified', async () => { + handler.setOptions({ like: { key: 'testExisting%' } }); + const execute = await handler.execute('testInstance/testBU', 'automation', [ + 'testExisting_automation', + ]); + assert.equal(process.exitCode, true, 'execute should not have thrown an error'); + assert.equal(execute, false, 'automation was not supposed to be executed'); + return; + }); + }); }); From 1da3bd130f0f1b83f712b27a7047dd4d3d41a267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 5 Jul 2023 13:11:44 +0200 Subject: [PATCH 080/208] #870: fix generated start times to not include miliseconds --- lib/metadataTypes/Automation.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index e9d493f4b..3a7fefcab 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -1198,8 +1198,8 @@ class Automation extends MetadataType { // create new Date object reflecting SFMC's servertime const dateServer = new Date(utc + 3600000 * offsetServer); - // return time as a string without trailing "Z" - return dateServer.toISOString().slice(0, -1); + // return time as a string without trailing "Z" and without miliseconds (separated by .) + return dateServer.toISOString().slice(0, -1).split('.')[0]; } /** * Experimental: Only working for DataExtensions: From 0e49714f4766eccac83cb1a64b7158309f6d1742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 7 Jul 2023 16:15:49 +0200 Subject: [PATCH 081/208] #870: added tests for pause automation --- ...08afb0e2-b00a-4c88-ad2e-pause-response.xml | 38 +++++++++ .../get-response.json | 85 +++++++++++++++++++ .../get-response.json | 2 +- ...testExisting_automation_pause-response.xml | 30 +++++++ .../9999999/program/retrieve-response.xml | 12 ++- test/type.automation.test.js | 60 ++++++++++--- 6 files changed, 213 insertions(+), 14 deletions(-) create mode 100644 test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-pause-response.xml create mode 100644 test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/get-response.json create mode 100644 test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_pause-response.xml diff --git a/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-pause-response.xml b/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-pause-response.xml new file mode 100644 index 000000000..072b427e5 --- /dev/null +++ b/test/resources/9999999/automation/schedule-08afb0e2-b00a-4c88-ad2e-pause-response.xml @@ -0,0 +1,38 @@ + + + + ScheduleResponse + urn:uuid:b58a82d9-a251-4be4-b50c-bd300d71601d + urn:uuid:9d3dbeb3-68b7-4f0a-b0af-04855dc0fd1e + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-07-05T10:29:58Z + 2023-07-05T10:34:58Z + + + + + + + + OK + Schedule Paused. To reactivate the schedule use proxy.Schedule with the action 'start'. + + + + + + + + OK + + cfe97488-3c5e-49a9-b338-c0e9f6b6f684 + + + diff --git a/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/get-response.json b/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/get-response.json new file mode 100644 index 000000000..58ec6b51c --- /dev/null +++ b/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/get-response.json @@ -0,0 +1,85 @@ +{ + "id": "08afb0e2-b00a-4c88-ad2e-pause", + "name": "testExisting_automation_pause", + "description": "bla bla", + "key": "testExisting_automation_pause", + "typeId": 1, + "type": "scheduled", + "statusId": 4, + "status": "Scheduled", + "categoryId": 290937, + "schedule": { + "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", + "typeId": 3, + "startDate": "2022-07-30T00:00:00", + "endDate": "2022-07-30T00:00:00", + "scheduledTime": "0001-01-01T07:00:00", + "rangeTypeId": 0, + "occurrences": 1, + "pattern": "01", + "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", + "timezoneName": "W. Europe Standard Time", + "scheduleStatus": "scheduled", + "timezoneId": 5 + }, + "steps": [ + { + "id": "13fda077-0e82-4936-b936-a36b0997fc44", + "name": "", + "step": 1, + "activities": [ + { + "id": "8081a992-a27d-4a43-984a-d60114ea1025", + "name": "testExisting_dataExtract", + "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", + "objectTypeId": 73, + "displayOrder": 1 + }, + { + "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", + "name": "testExisting_emailSend", + "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", + "objectTypeId": 42, + "displayOrder": 2 + }, + { + "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", + "name": "testExisting_fileTransfer", + "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", + "objectTypeId": 53, + "displayOrder": 3 + }, + { + "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", + "name": "testExisting_importFile", + "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", + "objectTypeId": 43, + "displayOrder": 4, + "targetDataExtensions": [ + { + "id": "21711373-72c1-ec11-b83b-48df37d1deb7", + "name": "testExisting_dataExtension", + "key": "testExisting_dataExtension", + "description": "bla bla", + "rowCount": 0 + } + ] + }, + { + "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", + "name": "testExisting_query_WRONG_NAME", + "activityObjectId": "549f0568-607c-4940-afef-437965094dat", + "objectTypeId": 300, + "displayOrder": 5 + }, + { + "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", + "name": "testExisting_script", + "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", + "objectTypeId": 423, + "displayOrder": 6 + } + ] + } + ] +} diff --git a/test/resources/9999999/automation/v1/automations/a8afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json b/test/resources/9999999/automation/v1/automations/a8afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json index b58d358fb..0f20856b9 100644 --- a/test/resources/9999999/automation/v1/automations/a8afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json +++ b/test/resources/9999999/automation/v1/automations/a8afb0e2-b00a-4c88-ad2e-1f7f8788c560/get-response.json @@ -6,7 +6,7 @@ "typeId": 1, "type": "scheduled", "statusId": 4, - "status": "PausedSchedule", + "status": "Scheduled", "categoryId": 290937, "schedule": { "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", diff --git a/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_pause-response.xml b/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_pause-response.xml new file mode 100644 index 000000000..6d33a7bfc --- /dev/null +++ b/test/resources/9999999/program/retrieve-CustomerKey=testExisting_automation_pause-response.xml @@ -0,0 +1,30 @@ + + + + RetrieveResponse + urn:uuid:60a72d4a-847e-4d9b-a4eb-a42951078298 + urn:uuid:0b59ed53-72ec-4481-ae06-4ee78912aef2 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-06-01T12:04:20Z + 2023-06-01T12:09:20Z + + + + + + OK + 3b1c8cee-b270-49cb-b77b-e7b33934d1b6 + + + 08afb0e2-b00a-4c88-ad2e-pause + + + + diff --git a/test/resources/9999999/program/retrieve-response.xml b/test/resources/9999999/program/retrieve-response.xml index 67ede7785..bcb9045c8 100644 --- a/test/resources/9999999/program/retrieve-response.xml +++ b/test/resources/9999999/program/retrieve-response.xml @@ -24,9 +24,15 @@ 08afb0e2-b00a-4c88-ad2e-1f7f8788c560 - testExisting_automation - testExisting_automation + testExisting_automation + testExisting_automation + + + + 08afb0e2-b00a-4c88-ad2e-pause + testExisting_automation_pause + testExisting_automation_pause - \ No newline at end of file + diff --git a/test/type.automation.test.js b/test/type.automation.test.js index db54a7a3a..a3cc51cd3 100644 --- a/test/type.automation.test.js +++ b/test/type.automation.test.js @@ -27,8 +27,8 @@ describe('type: automation', () => { const result = cache.getCache(); assert.equal( result.automation ? Object.keys(result.automation).length : 0, - 1, - 'only one automation expected' + 2, + 'only two automations expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_automation', 'automation'), @@ -50,7 +50,7 @@ describe('type: automation', () => { assert.equal( testUtils.getAPIHistoryLength(), - 14, + 15, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; @@ -70,8 +70,8 @@ describe('type: automation', () => { const result = cache.getCache(); assert.equal( result.automation ? Object.keys(result.automation).length : 0, - 2, - 'two automations expected' + 3, + 'three automations expected' ); // insert assert.deepEqual( @@ -107,7 +107,7 @@ describe('type: automation', () => { it('Should update & start an automation with --execute option', async () => { // WHEN handler.setOptions({ execute: true }); - await handler.deploy( + const deployed = await handler.deploy( 'testInstance/testBU', ['automation'], ['testExisting_automation'] @@ -120,11 +120,25 @@ describe('type: automation', () => { ); // get results from cache - const result = cache.getCache(); + const cached = cache.getCache(); assert.equal( - result.automation ? Object.keys(result.automation).length : 0, + cached.automation ? Object.keys(cached.automation).length : 0, + 2, + 'two cached automation expected' + ); + assert.equal( + deployed['testInstance/testBU'].automation + ? Object.keys(deployed['testInstance/testBU'].automation).length + : 0, 1, - 'one automation expected' + 'one deployed automation expected' + ); + assert.equal( + deployed['testInstance/testBU'].automation + ? Object.keys(deployed['testInstance/testBU'].automation)[0] + : null, + 'testExisting_automation', + 'expected specific automation to have been deployed' ); // update @@ -246,7 +260,7 @@ describe('type: automation', () => { ); assert.equal( testUtils.getAPIHistoryLength(), - 14, + 15, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; @@ -318,4 +332,30 @@ describe('type: automation', () => { return; }); }); + describe('Pause ================', () => { + it('Should pause a automation by key', async () => { + const pause = await handler.pause('testInstance/testBU', 'automation', [ + 'testExisting_automation_pause', + ]); + assert.equal(process.exitCode, false, 'pause should not have thrown an error'); + assert.equal(pause, true, 'automation was supposed to be paused'); + return; + }); + it('Should pause a automation selected via --like', async () => { + handler.setOptions({ like: { key: 'testExisting_a%n_pause' } }); + const pause = await handler.pause('testInstance/testBU', 'automation'); + assert.equal(process.exitCode, false, 'pause should not have thrown an error'); + assert.equal(pause, true, 'automation was supposed to be paused'); + return; + }); + it('Should not pause executing a automation because key and --like was specified', async () => { + handler.setOptions({ like: { key: 'testExisting_a%n_pause' } }); + const pause = await handler.pause('testInstance/testBU', 'automation', [ + 'testExisting_automation_pause', + ]); + assert.equal(process.exitCode, true, 'pause should not have thrown an error'); + assert.equal(pause, false, 'automation was not supposed to be paused'); + return; + }); + }); }); From 3bfa69c8ef47e6977fd62e3587fd4fa01196d39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 7 Jul 2023 16:34:48 +0200 Subject: [PATCH 082/208] #870: fix bad whitespace --- lib/metadataTypes/Automation.js | 4 ++-- .../9999999/automation/create-expected.json | 2 +- .../automation/create-testNew_automation-expected.md | 2 +- .../retrieve-testExisting_automation-expected.md | 2 +- .../update-testExisting_automation-expected.md | 2 +- test/type.automation.test.js | 12 ++++++++++++ 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index 3a7fefcab..1f6dd6d19 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -1236,7 +1236,7 @@ class Automation extends MetadataType { output += `**Schedule:**\n\n`; output += `* Start: ${json.schedule.startDate.split('T').join(' ')} ${tz}\n`; output += `* End: ${json.schedule.endDate.split('T').join(' ')} ${tz}\n`; - output += `* Timezone: ${json.schedule.timezoneName}\n`; + output += `* Timezone: ${json.schedule.timezoneName}\n`; const ical = {}; for (const item of json.schedule.icalRecur.split(';')) { @@ -1247,7 +1247,7 @@ class Automation extends MetadataType { output += `* Recurrance: every ${ical.INTERVAL > 1 ? ical.INTERVAL : ''} ${ frequency === 'dai' ? 'day' : frequency - }${ical.INTERVAL > 1 ? 's' : ''} ${ical.COUNT ? `for ${ical.COUNT} times` : ''}\n`; + }${ical.INTERVAL > 1 ? 's' : ''}${ical.COUNT ? ` for ${ical.COUNT} times` : ''}\n`; } else if (json.schedule) { output += `**Schedule:** Not defined\n`; } diff --git a/test/resources/9999999/automation/create-expected.json b/test/resources/9999999/automation/create-expected.json index 953d935af..92ea826e1 100644 --- a/test/resources/9999999/automation/create-expected.json +++ b/test/resources/9999999/automation/create-expected.json @@ -5,7 +5,7 @@ "r__folder_Path": "my automations", "type": "scheduled", "status": "PausedSchedule", - "schedule": { + "schedule": { "endDate": "2079-06-06T21:00:00-06:00", "icalRecur": "FREQ=MINUTELY;UNTIL=20790607T050000;INTERVAL=5", "startDate": "2020-05-13T18:30:32.11-06:00", diff --git a/test/resources/9999999/automation/create-testNew_automation-expected.md b/test/resources/9999999/automation/create-testNew_automation-expected.md index 4e0ea77ff..c607175cc 100644 --- a/test/resources/9999999/automation/create-testNew_automation-expected.md +++ b/test/resources/9999999/automation/create-testNew_automation-expected.md @@ -12,7 +12,7 @@ * Start: 2020-05-13 18:30:32.11-06:00 +01:00 * End: 2079-06-06 21:00:00-06:00 +01:00 -* Timezone: W. Europe Standard Time +* Timezone: W. Europe Standard Time * Recurrance: every 5 minutes **Notifications:** _none_ diff --git a/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md b/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md index 22bd4c500..ae8f4c10a 100644 --- a/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md +++ b/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md @@ -12,7 +12,7 @@ * Start: 2022-07-30 00:00:00 +01:00 * End: 2022-07-30 00:00:00 +01:00 -* Timezone: W. Europe Standard Time +* Timezone: W. Europe Standard Time * Recurrance: every day for 1 times **Notifications:** diff --git a/test/resources/9999999/automation/update-testExisting_automation-expected.md b/test/resources/9999999/automation/update-testExisting_automation-expected.md index 681c2a694..fbee3558c 100644 --- a/test/resources/9999999/automation/update-testExisting_automation-expected.md +++ b/test/resources/9999999/automation/update-testExisting_automation-expected.md @@ -12,7 +12,7 @@ * Start: 2022-07-30 00:00:00 +01:00 * End: 2022-07-30 00:00:00 +01:00 -* Timezone: W. Europe Standard Time +* Timezone: W. Europe Standard Time * Recurrance: every day for 1 times **Notifications:** _none_ diff --git a/test/type.automation.test.js b/test/type.automation.test.js index a3cc51cd3..531b6b802 100644 --- a/test/type.automation.test.js +++ b/test/type.automation.test.js @@ -97,6 +97,18 @@ describe('type: automation', () => { ) ); + // check if MD file was created and equals expectations + expect(file(testUtils.getActualDoc('testNew_automation', 'automation'))).to.equal( + file( + testUtils.getExpectedFile( + '9999999', + 'automation', + 'create-testNew_automation', + 'md' + ) + ) + ); + assert.equal( testUtils.getAPIHistoryLength(), 16, From 5e439073a476bf36ccd0ffdf1e2424e56d781a29 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Mon, 10 Jul 2023 22:41:58 +0200 Subject: [PATCH 083/208] #38: test for query --- lib/index.js | 25 ++++++-- lib/metadataTypes/MetadataType.js | 8 +++ ...stExisting_automation.automation-meta.json | 2 +- .../testNew_automation.automation-meta.json | 2 +- .../query/testExisting_query.query-meta.json | 2 +- ...testExisting_query_fixKeys.query-meta.sql} | 2 + .../9999999/automation/build-expected.json | 2 +- .../9999999/automation/create-expected.json | 2 +- .../9999999/automation/retrieve-expected.json | 2 +- ...trieve-testExisting_automation-expected.md | 26 ++++---- .../9999999/automation/template-expected.json | 2 +- .../9999999/automation/update-expected.json | 2 +- ...update-testExisting_automation-expected.md | 23 ++++--- .../get-response.json | 2 +- .../patch-response.json | 2 +- .../automation/v1/queries/get-response.json | 19 +----- .../9999999/query/build-expected.json | 2 +- .../resources/9999999/query/get-expected.json | 2 +- .../9999999/query/patch-expected.json | 2 +- .../9999999/query/patch1-expected.json} | 6 +- .../9999999/query/patch1-expected.sql | 6 ++ .../9999999/query/template-expected.json | 2 +- test/type.query.test.js | 61 ++++++++----------- 23 files changed, 102 insertions(+), 102 deletions(-) rename test/mockRoot/deploy/testInstance/testBU/query/{testNew_query1.query-meta.sql => testExisting_query_fixKeys.query-meta.sql} (66%) rename test/{mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json => resources/9999999/query/patch1-expected.json} (68%) create mode 100644 test/resources/9999999/query/patch1-expected.sql diff --git a/lib/index.js b/lib/index.js index b0401012a..ea55c327d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -930,7 +930,6 @@ class Mcdev { */ static async _fixKeysBU(cred, bu, type, keyArr) { const properties = await config.getProperties(); - let counter_success = 0; let numItemsToUpdate = 0; let deployed; const toDeploy = []; @@ -953,7 +952,6 @@ class Mcdev { Util.logger.error(ex.message); return; } - Util.logger.info(`First retrieve ${type}`); const retriever = new Retriever(properties, buObject); const retrieved = await retriever.retrieve(type, keyArr, null, false); Object.keys(retrieved).forEach((key) => { @@ -968,7 +966,6 @@ class Mcdev { if (item != null) { if (item.name != item.key && !MetadataTypeDefinitions[type].keyIsFixed) { toDeploy.push(item.key); - counter_success++; Util.logger.info(`Updating key for query ${item.key}`); } else { numItemsToUpdate--; @@ -981,15 +978,33 @@ class Mcdev { } } }); - Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; + await MetadataTypeInfo[type].fixKeys(properties); properties.directories.deploy = properties.directories.retrieve; deployed = await Deployer._deployBU(cred, bu, properties, type, toDeploy, true); - this._retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); + await this.#retrieveDependentMetadata(cred, bu, type[0]); //type is an array with one type only } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } return numItemsToUpdate === Object.values(deployed).length ? true : false; } + /** + *helper for {@link _fixKeysBU}. Retrieve dependent metadata + * + * @private + * @param {string} cred name of Credential + * @param {string} bu name of BU + * @param {string} type type of the metadata passed as a parameter to fixKeys function + */ + static async #retrieveDependentMetadata(cred, bu, type) { + const dependencies = []; + Util.logger.info(`\n :: Retrieving dependent metadata \n`); + for (const dependentType of Object.keys(MetadataTypeDefinitions)) { + if (MetadataTypeDefinitions[dependentType].dependencies.includes(type)) { + dependencies.push(dependentType); + } + } + await this._retrieveBU(cred, bu, dependencies); + } } module.exports = Mcdev; diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 92b1686de..92dbdc169 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -1997,6 +1997,14 @@ class MetadataType { const fileList = keyArr.map((key) => File.normalizePath([path, key + typeExtension])); return fileList; } + /** + * A function to set changeKeyField for fixKeys function + * + * @param {TYPE.Mcdevrc} properties central properties object + */ + static async fixKeys(properties) { + Util.OPTIONS.changeKeyField = this.definition.nameField; + } } MetadataType.definition = { diff --git a/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json b/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json index b901a271a..c0781366e 100644 --- a/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json +++ b/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json @@ -31,7 +31,7 @@ "r__type": "importFile" }, { - "name": "testExisting_query", + "name": "testExisting_query1", "r__type": "query" }, { diff --git a/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json b/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json index 2a1caee12..e1c0c355b 100644 --- a/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json +++ b/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json @@ -31,7 +31,7 @@ "r__type": "importFile" }, { - "name": "testExisting_query", + "name": "testExisting_query1", "r__type": "query" }, { diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query.query-meta.json b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query.query-meta.json index 421e918e5..86a4a393c 100644 --- a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query.query-meta.json +++ b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query.query-meta.json @@ -1,5 +1,5 @@ { - "name": "testExisting_query", + "name": "testExisting_query1", "key": "testExisting_query", "description": "updated on deploy", "targetKey": "testExisting_dataExtension", diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.sql b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql similarity index 66% rename from test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.sql rename to test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql index 8020314ea..e78525408 100644 --- a/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.sql +++ b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql @@ -2,3 +2,5 @@ SELECT SubscriberKey as testField FROM _Subscribers +WHERE + country IN ('test') diff --git a/test/resources/9999999/automation/build-expected.json b/test/resources/9999999/automation/build-expected.json index ecd94cb33..8422713d0 100644 --- a/test/resources/9999999/automation/build-expected.json +++ b/test/resources/9999999/automation/build-expected.json @@ -31,7 +31,7 @@ "r__type": "importFile" }, { - "name": "testTemplated_query", + "name": "testTemplated_query1", "r__type": "query" }, { diff --git a/test/resources/9999999/automation/create-expected.json b/test/resources/9999999/automation/create-expected.json index 2a1caee12..e1c0c355b 100644 --- a/test/resources/9999999/automation/create-expected.json +++ b/test/resources/9999999/automation/create-expected.json @@ -31,7 +31,7 @@ "r__type": "importFile" }, { - "name": "testExisting_query", + "name": "testExisting_query1", "r__type": "query" }, { diff --git a/test/resources/9999999/automation/retrieve-expected.json b/test/resources/9999999/automation/retrieve-expected.json index fa80b0f99..16ad1ec5a 100644 --- a/test/resources/9999999/automation/retrieve-expected.json +++ b/test/resources/9999999/automation/retrieve-expected.json @@ -31,7 +31,7 @@ "r__type": "importFile" }, { - "name": "testExisting_query", + "name": "testExisting_query1", "r__type": "query" }, { diff --git a/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md b/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md index 22bd4c500..8f4d2396b 100644 --- a/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md +++ b/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md @@ -10,21 +10,21 @@ **Schedule:** -* Start: 2022-07-30 00:00:00 +01:00 -* End: 2022-07-30 00:00:00 +01:00 -* Timezone: W. Europe Standard Time -* Recurrance: every day for 1 times +- Start: 2022-07-30 00:00:00 +01:00 +- End: 2022-07-30 00:00:00 +01:00 +- Timezone: W. Europe Standard Time +- Recurrance: every day for 1 times **Notifications:** -* Complete: complete@test.accenture.com -* Error: error@test.accenture.com ("test") +- Complete: complete@test.accenture.com +- Error: error@test.accenture.com ("test") -| Step 1
_-_ | -| --- | -| _1.1: dataExtract_
testExisting_dataExtract | -| _1.2: emailSend_
testExisting_emailSend | +| Step 1
_-_ | +| ------------------------------------------------ | +| _1.1: dataExtract_
testExisting_dataExtract | +| _1.2: emailSend_
testExisting_emailSend | | _1.3: fileTransfer_
testExisting_fileTransfer | -| _1.4: importFile_
testExisting_importFile | -| _1.5: query_
testExisting_query | -| _1.6: script_
testExisting_script | +| _1.4: importFile_
testExisting_importFile | +| _1.5: query_
testExisting_query1 | +| _1.6: script_
testExisting_script | diff --git a/test/resources/9999999/automation/template-expected.json b/test/resources/9999999/automation/template-expected.json index 038ecc7ff..83e7df307 100644 --- a/test/resources/9999999/automation/template-expected.json +++ b/test/resources/9999999/automation/template-expected.json @@ -31,7 +31,7 @@ "r__type": "importFile" }, { - "name": "{{{prefix}}}query", + "name": "{{{prefix}}}query1", "r__type": "query" }, { diff --git a/test/resources/9999999/automation/update-expected.json b/test/resources/9999999/automation/update-expected.json index 47860e944..cd5ecc8c5 100644 --- a/test/resources/9999999/automation/update-expected.json +++ b/test/resources/9999999/automation/update-expected.json @@ -31,7 +31,7 @@ "r__type": "importFile" }, { - "name": "testExisting_query", + "name": "testExisting_query1", "r__type": "query" }, { diff --git a/test/resources/9999999/automation/update-testExisting_automation-expected.md b/test/resources/9999999/automation/update-testExisting_automation-expected.md index 681c2a694..a18e49e0f 100644 --- a/test/resources/9999999/automation/update-testExisting_automation-expected.md +++ b/test/resources/9999999/automation/update-testExisting_automation-expected.md @@ -10,19 +10,18 @@ **Schedule:** -* Start: 2022-07-30 00:00:00 +01:00 -* End: 2022-07-30 00:00:00 +01:00 -* Timezone: W. Europe Standard Time -* Recurrance: every day for 1 times +- Start: 2022-07-30 00:00:00 +01:00 +- End: 2022-07-30 00:00:00 +01:00 +- Timezone: W. Europe Standard Time +- Recurrance: every day for 1 times **Notifications:** _none_ - -| Step 1
_-_ | -| --- | -| _1.1: dataExtract_
testExisting_dataExtract | -| _1.2: emailSend_
testExisting_emailSend | +| Step 1
_-_ | +| ------------------------------------------------ | +| _1.1: dataExtract_
testExisting_dataExtract | +| _1.2: emailSend_
testExisting_emailSend | | _1.3: fileTransfer_
testExisting_fileTransfer | -| _1.4: importFile_
testExisting_importFile | -| _1.5: query_
testExisting_query | -| _1.6: script_
testExisting_script | +| _1.4: importFile_
testExisting_importFile | +| _1.5: query_
testExisting_query1 | +| _1.6: script_
testExisting_script | diff --git a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json index 9144d0e0b..fff3e1592 100644 --- a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json +++ b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json @@ -1,6 +1,6 @@ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat", - "name": "testExisting_query", + "name": "testExisting_query1", "key": "testExisting_query", "description": "bla bla", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", diff --git a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json index 6414f11dc..8433390a8 100644 --- a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json +++ b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json @@ -1,6 +1,6 @@ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat", - "name": "testExisting_query", + "name": "testExisting_query1", "key": "testExisting_query", "description": "updated on deploy", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", diff --git a/test/resources/9999999/automation/v1/queries/get-response.json b/test/resources/9999999/automation/v1/queries/get-response.json index 31305c1f3..39ee926c5 100644 --- a/test/resources/9999999/automation/v1/queries/get-response.json +++ b/test/resources/9999999/automation/v1/queries/get-response.json @@ -5,7 +5,7 @@ "items": [ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat", - "name": "testExisting_query", + "name": "testExisting_query1", "key": "testExisting_query", "description": "bla bla", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", @@ -36,23 +36,6 @@ "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false - }, - { - "queryDefinitionId": "b28a1c2f-6656-478a-be51-4f12be4c9088", - "name": "updateMePlease", - "key": "testNew_query1", - "description": "bla bla", - "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", - "targetName": "testExisting_dataExtension", - "targetKey": "testExisting_dataExtension-WRONG", - "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", - "targetDescription": "", - "createdDate": "2022-04-26T15:21:16.453", - "modifiedDate": "2022-04-26T16:02:44.01", - "targetUpdateTypeId": 0, - "targetUpdateTypeName": "Overwrite", - "categoryId": 999, - "isFrozen": false } ] } diff --git a/test/resources/9999999/query/build-expected.json b/test/resources/9999999/query/build-expected.json index a7df67267..72c92e729 100644 --- a/test/resources/9999999/query/build-expected.json +++ b/test/resources/9999999/query/build-expected.json @@ -1,5 +1,5 @@ { - "name": "testTemplated_query", + "name": "testTemplated_query1", "key": "testTemplated_query", "description": "foobar", "targetKey": "testTemplated_dataExtension", diff --git a/test/resources/9999999/query/get-expected.json b/test/resources/9999999/query/get-expected.json index 4cd606716..e5571691e 100644 --- a/test/resources/9999999/query/get-expected.json +++ b/test/resources/9999999/query/get-expected.json @@ -1,5 +1,5 @@ { - "name": "testExisting_query", + "name": "testExisting_query1", "key": "testExisting_query", "description": "bla bla", "targetKey": "testExisting_dataExtension", diff --git a/test/resources/9999999/query/patch-expected.json b/test/resources/9999999/query/patch-expected.json index 421e918e5..86a4a393c 100644 --- a/test/resources/9999999/query/patch-expected.json +++ b/test/resources/9999999/query/patch-expected.json @@ -1,5 +1,5 @@ { - "name": "testExisting_query", + "name": "testExisting_query1", "key": "testExisting_query", "description": "updated on deploy", "targetKey": "testExisting_dataExtension", diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json b/test/resources/9999999/query/patch1-expected.json similarity index 68% rename from test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json rename to test/resources/9999999/query/patch1-expected.json index c29f18dc3..86a4a393c 100644 --- a/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json +++ b/test/resources/9999999/query/patch1-expected.json @@ -1,7 +1,7 @@ { - "name": "updateMePlease", - "key": "testNew_query1", - "description": "created on deploy", + "name": "testExisting_query1", + "key": "testExisting_query", + "description": "updated on deploy", "targetKey": "testExisting_dataExtension", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", diff --git a/test/resources/9999999/query/patch1-expected.sql b/test/resources/9999999/query/patch1-expected.sql new file mode 100644 index 000000000..2a32f5fad --- /dev/null +++ b/test/resources/9999999/query/patch1-expected.sql @@ -0,0 +1,6 @@ +SELECT + SubscriberKey AS testField +FROM + _Subscribers +WHERE + country IN ('test') diff --git a/test/resources/9999999/query/template-expected.json b/test/resources/9999999/query/template-expected.json index 9f9bd2806..3f6caf4a6 100644 --- a/test/resources/9999999/query/template-expected.json +++ b/test/resources/9999999/query/template-expected.json @@ -1,5 +1,5 @@ { - "name": "{{{prefix}}}query", + "name": "{{{prefix}}}query1", "key": "{{{prefix}}}query", "description": "{{{description}}}", "targetKey": "{{{prefix}}}dataExtension", diff --git a/test/type.query.test.js b/test/type.query.test.js index c4b26bedf..69bbab6bd 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -27,7 +27,7 @@ describe('type: query', () => { const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 3, + 2, 'only two queries expected' ); // normal test @@ -87,18 +87,14 @@ describe('type: query', () => { }); it('Should create & upsert a query', async () => { // WHEN - await handler.deploy( - 'testInstance/testBU', - ['query'], - ['testNew_query', 'testExisting_query'] - ); + await handler.deploy('testInstance/testBU', ['query']); // THEN assert.equal(process.exitCode, false, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 4, + 3, 'three queries expected' ); // confirm created item @@ -133,42 +129,33 @@ describe('type: query', () => { beforeEach(() => { testUtils.mockSetup(true); }); - it('Should create & upsert a query', async () => { + it('Should update the key and re-deploy', async () => { // WHEN - await handler.deploy('testInstance/testBU', ['query']); + await handler.fixKeys('testInstance/testBU', ['query']); // THEN - assert.equal(process.exitCode, false, 'deploy should not have thrown an error'); + assert.equal(process.exitCode, false, 'fixKeys should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 4, - 'three queries expected' + 2, + 'two queries expected' + ); + // confirm updated item + assert.deepEqual( + await testUtils.getActualJson('testExisting_query', 'query'), + await testUtils.getExpectedJson('9999999', 'query', 'patch1'), + 'returned metadata was not equal expected for insert query' + ); + expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.equal( + file(testUtils.getExpectedFile('9999999', 'query', 'patch1', 'sql')) + ); + // check number of API calls + assert.equal( + testUtils.getAPIHistoryLength(), + 27, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); - // confirm created item - // assert.deepEqual( - // await testUtils.getActualJson('testNew_query', 'query'), - // await testUtils.getExpectedJson('9999999', 'query', 'post'), - // 'returned metadata was not equal expected for insert query' - // ); - // expect(file(testUtils.getActualFile('testNew_query', 'query', 'sql'))).to.equal( - // file(testUtils.getExpectedFile('9999999', 'query', 'post', 'sql')) - // ); - // // confirm updated item - // assert.deepEqual( - // await testUtils.getActualJson('testExisting_query', 'query'), - // await testUtils.getExpectedJson('9999999', 'query', 'patch'), - // 'returned metadata was not equal expected for insert query' - // ); - // expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.equal( - // file(testUtils.getExpectedFile('9999999', 'query', 'patch', 'sql')) - // ); - // // check number of API calls - // assert.equal( - // testUtils.getAPIHistoryLength(), - // 8, - // 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' - // ); return; }); it('Should change the key during update with --changeKeyValue'); @@ -179,7 +166,7 @@ describe('type: query', () => { const result = await handler.retrieveAsTemplate( 'testInstance/testBU', 'query', - ['testExisting_query'], + ['testExisting_query1'], 'testSourceMarket' ); // WHEN From ef4d8683e3a6c96a0743eb20a39ca884e5cd556d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 11 Jul 2023 14:47:09 +0200 Subject: [PATCH 084/208] #870: refactoring --- lib/index.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 34543998f..775364b0a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -737,16 +737,18 @@ class Mcdev { Util.startLogger(); let lang_past; let lang_present; + let requireKeyOrLike; switch (methodName) { case 'execute': { lang_past = 'executed'; lang_present = 'executing'; + requireKeyOrLike = true; break; } case 'pause': { lang_past = 'paused'; lang_present = 'pausing'; - + requireKeyOrLike = true; break; } } @@ -768,7 +770,9 @@ class Mcdev { ); return false; } + if ( + requireKeyOrLike && (!Array.isArray(keys) || !keys.length) && (!Util.OPTIONS.like || !Object.keys(Util.OPTIONS.like).length) ) { @@ -783,6 +787,7 @@ class Mcdev { Util.logger.error('You can either specify keys OR a --like filter.'); return false; } + if (businessUnit === '*') { Util.logger.info( `:: ${lang_present} the ${selectedType} on all BUs for all credentials` From fd76ed967a1bfff39567cc30fe84b205eb61d386 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 12:56:38 +0000 Subject: [PATCH 085/208] Bump lint-staged from 13.2.2 to 13.2.3 Bumps [lint-staged](https://github.com/okonet/lint-staged) from 13.2.2 to 13.2.3. - [Release notes](https://github.com/okonet/lint-staged/releases) - [Commits](https://github.com/okonet/lint-staged/compare/v13.2.2...v13.2.3) --- updated-dependencies: - dependency-name: lint-staged dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index e7eb5b3d9..9816f51c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "fast-xml-parser": "4.2.5", "husky": "8.0.3", "jsdoc-to-markdown": "8.0.0", - "lint-staged": "13.2.2", + "lint-staged": "13.2.3", "mocha": "10.2.0", "mock-fs": "5.2.0", "npm-check": "6.0.1", @@ -5721,9 +5721,9 @@ } }, "node_modules/lint-staged": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.2.tgz", - "integrity": "sha512-71gSwXKy649VrSU09s10uAT0rWCcY3aewhMaHyl2N84oBk4Xs9HgxvUp3AYu+bNsK4NrOYYxvSgg7FyGJ+jGcA==", + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.3.tgz", + "integrity": "sha512-zVVEXLuQIhr1Y7R7YAWx4TZLdvuzk7DnmrsTNL0fax6Z3jrpFcas+vKbzxhhvp6TA55m1SQuWkpzI1qbfDZbAg==", "dev": true, "dependencies": { "chalk": "5.2.0", @@ -14161,9 +14161,9 @@ } }, "lint-staged": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.2.tgz", - "integrity": "sha512-71gSwXKy649VrSU09s10uAT0rWCcY3aewhMaHyl2N84oBk4Xs9HgxvUp3AYu+bNsK4NrOYYxvSgg7FyGJ+jGcA==", + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.3.tgz", + "integrity": "sha512-zVVEXLuQIhr1Y7R7YAWx4TZLdvuzk7DnmrsTNL0fax6Z3jrpFcas+vKbzxhhvp6TA55m1SQuWkpzI1qbfDZbAg==", "dev": true, "requires": { "chalk": "5.2.0", diff --git a/package.json b/package.json index eeb992ebd..292218098 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "fast-xml-parser": "4.2.5", "husky": "8.0.3", "jsdoc-to-markdown": "8.0.0", - "lint-staged": "13.2.2", + "lint-staged": "13.2.3", "mocha": "10.2.0", "mock-fs": "5.2.0", "npm-check": "6.0.1", From 385e89197bcefcb54ba2a0fb0e2be244867f7f9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 13:04:23 +0000 Subject: [PATCH 086/208] Bump eslint from 8.43.0 to 8.44.0 Bumps [eslint](https://github.com/eslint/eslint) from 8.43.0 to 8.44.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.43.0...v8.44.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 140 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 71 insertions(+), 71 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9816f51c2..d2445af6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "axios-mock-adapter": "1.21.5", "chai": "4.3.7", "chai-files": "1.4.0", - "eslint": "8.43.0", + "eslint": "8.44.0", "eslint-config-prettier": "8.7.0", "eslint-config-ssjs": "1.1.11", "eslint-plugin-jsdoc": "46.3.0", @@ -67,6 +67,15 @@ "fsevents": "*" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -545,14 +554,14 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -590,9 +599,9 @@ "dev": true }, "node_modules/@eslint/js": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", - "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1136,9 +1145,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -3138,15 +3147,15 @@ } }, "node_modules/eslint": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", - "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.43.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -3158,7 +3167,7 @@ "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.0", "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "espree": "^9.6.0", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -3178,7 +3187,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -3418,12 +3427,12 @@ "dev": true }, "node_modules/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", + "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, @@ -3618,7 +3627,7 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "node_modules/fast-xml-parser": { @@ -7392,17 +7401,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -9776,15 +9785,6 @@ "node": ">= 6.4.0" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -9974,6 +9974,12 @@ } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -10344,14 +10350,14 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -10381,9 +10387,9 @@ } }, "@eslint/js": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", - "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", "dev": true }, "@humanwhocodes/config-array": { @@ -10810,9 +10816,9 @@ "dev": true }, "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true }, "acorn-jsx": { @@ -12320,15 +12326,15 @@ "dev": true }, "eslint": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", - "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.43.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -12340,7 +12346,7 @@ "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.0", "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "espree": "^9.6.0", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -12360,7 +12366,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -12508,12 +12514,12 @@ "dev": true }, "espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", + "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } @@ -12654,7 +12660,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fast-xml-parser": { @@ -15442,17 +15448,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "ora": { @@ -17226,12 +17232,6 @@ "triple-beam": "^1.3.0" } }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", diff --git a/package.json b/package.json index 292218098..0b6fa36d6 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "axios-mock-adapter": "1.21.5", "chai": "4.3.7", "chai-files": "1.4.0", - "eslint": "8.43.0", + "eslint": "8.44.0", "eslint-config-prettier": "8.7.0", "eslint-config-ssjs": "1.1.11", "eslint-plugin-jsdoc": "46.3.0", From 4164be29ddf020f118c01cf6ab60822514ea966a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jul 2023 13:06:44 +0000 Subject: [PATCH 087/208] Bump eslint-plugin-jsdoc from 46.3.0 to 46.4.3 Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 46.3.0 to 46.4.3. - [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases) - [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc) - [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v46.3.0...v46.4.3) --- updated-dependencies: - dependency-name: eslint-plugin-jsdoc dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index d2445af6f..6bb4830b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "eslint": "8.44.0", "eslint-config-prettier": "8.7.0", "eslint-config-ssjs": "1.1.11", - "eslint-plugin-jsdoc": "46.3.0", + "eslint-plugin-jsdoc": "46.4.3", "eslint-plugin-mocha": "10.1.0", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-unicorn": "47.0.0", @@ -3230,9 +3230,9 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "46.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.3.0.tgz", - "integrity": "sha512-nfSvsR8YJRZyKrWwcXPSQyQC8jllfdEjcRhTXFr7RxfB5Wyl7AxrfjCUz72WwalkXMF4u+R6F/oDoW46ah69HQ==", + "version": "46.4.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.4.3.tgz", + "integrity": "sha512-Prc7ol+vCIghPeECpwZq5+P+VZfoi87suywvbYCiCnkI1kTmVSdcOC2M8mioglWxBbd28wbb1OVjg/8OzGzatA==", "dev": true, "dependencies": { "@es-joy/jsdoccomment": "~0.39.4", @@ -12407,9 +12407,9 @@ "requires": {} }, "eslint-plugin-jsdoc": { - "version": "46.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.3.0.tgz", - "integrity": "sha512-nfSvsR8YJRZyKrWwcXPSQyQC8jllfdEjcRhTXFr7RxfB5Wyl7AxrfjCUz72WwalkXMF4u+R6F/oDoW46ah69HQ==", + "version": "46.4.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.4.3.tgz", + "integrity": "sha512-Prc7ol+vCIghPeECpwZq5+P+VZfoi87suywvbYCiCnkI1kTmVSdcOC2M8mioglWxBbd28wbb1OVjg/8OzGzatA==", "dev": true, "requires": { "@es-joy/jsdoccomment": "~0.39.4", diff --git a/package.json b/package.json index 0b6fa36d6..d11bea506 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "eslint": "8.44.0", "eslint-config-prettier": "8.7.0", "eslint-config-ssjs": "1.1.11", - "eslint-plugin-jsdoc": "46.3.0", + "eslint-plugin-jsdoc": "46.4.3", "eslint-plugin-mocha": "10.1.0", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-unicorn": "47.0.0", From 2c1881fd6c63a5b4c748543f508a4185c08e358a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Tue, 11 Jul 2023 17:27:22 +0200 Subject: [PATCH 088/208] #711: improve log --- docs/dist/documentation.md | 59 +++++++++++++++++++++++++++++++ lib/metadataTypes/AttributeSet.js | 6 ++-- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 0eca226f5..f3fdcfac8 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -17,6 +17,9 @@ Source and target business units are also compared before the deployment to appl
AttributeGroupMetadataType

AttributeGroup MetadataType

+
AttributeRelationshipMetadataType
+

AttributeRelationship MetadataType

+
AttributeSetMetadataType

AttributeSet MetadataType

@@ -1281,6 +1284,62 @@ prepares for deployment | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single item | + + +## AttributeRelationship ⇐ [MetadataType](#MetadataType) +AttributeRelationship MetadataType + +**Kind**: global class +**Extends**: [MetadataType](#MetadataType) + +* [AttributeRelationship](#AttributeRelationship) ⇐ [MetadataType](#MetadataType) + * [.retrieve(retrieveDir, [_], [__], [relationshipID], attributeSetId)](#AttributeRelationship.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> + * [.retrieveForCache(_, __, attributeSetId, relationshipID)](#AttributeRelationship.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> + * [.postRetrieveTasks(metadata)](#AttributeRelationship.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem + + + +### AttributeRelationship.retrieve(retrieveDir, [_], [__], [relationshipID], attributeSetId) ⇒ Promise.<TYPE.MetadataTypeMapObj> +Retrieves Metadata of schema attribute groups. + +**Kind**: static method of [AttributeRelationship](#AttributeRelationship) +**Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of metadata + +| Param | Type | Description | +| --- | --- | --- | +| retrieveDir | string | Directory where retrieved metadata directory will be saved | +| [_] | void | unused parameter | +| [__] | void | unused parameter | +| [relationshipID] | string | customer key of single item to retrieve | +| attributeSetId | string | CUSTOM: Id of the attribute set for which these relationships are defined | + + + +### AttributeRelationship.retrieveForCache(_, __, attributeSetId, relationshipID) ⇒ Promise.<TYPE.MetadataTypeMapObj> +Retrieves Metadata of schema attribute groups for caching. + +**Kind**: static method of [AttributeRelationship](#AttributeRelationship) +**Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of metadata + +| Param | Type | Description | +| --- | --- | --- | +| _ | void | unused parameter | +| __ | void | unused parameter | +| attributeSetId | string | CUSTOM: Id of the attribute set for which these relationships are defined | +| relationshipID | string | CUSTOM: customer key of single item to retrieve | + + + +### AttributeRelationship.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem +manages post retrieve steps + +**Kind**: static method of [AttributeRelationship](#AttributeRelationship) +**Returns**: TYPE.MetadataTypeItem - metadata + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.MetadataTypeItem | a single metadata | + ## AttributeSet ⇐ [MetadataType](#MetadataType) diff --git a/lib/metadataTypes/AttributeSet.js b/lib/metadataTypes/AttributeSet.js index 25aeb2a9b..a0f22faa3 100644 --- a/lib/metadataTypes/AttributeSet.js +++ b/lib/metadataTypes/AttributeSet.js @@ -214,9 +214,9 @@ class AttributeSet extends MetadataType { } } catch (ex) { Util.logger.warn( - ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ - ex.message - }` + ` - ${this.definition.type} ${metadata[this.definition.nameField]} / ${ + metadata[this.definition.keyField] + }: ${ex.message}` ); } } From 97d435529747379d001ee3c578dcd57b5c8802aa Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Tue, 11 Jul 2023 22:22:39 +0200 Subject: [PATCH 089/208] #38: new query for tests --- lib/index.js | 26 +++--------- lib/metadataTypes/MetadataType.js | 8 ---- ...testExisting_query_fixKeys.query-meta.json | 11 +++++ .../testExisting_query_fixKeys.query-meta.sql | 2 - test/type.query.test.js | 41 ++----------------- 5 files changed, 19 insertions(+), 69 deletions(-) create mode 100644 test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json diff --git a/lib/index.js b/lib/index.js index da03af85c..aec68dd85 100644 --- a/lib/index.js +++ b/lib/index.js @@ -977,7 +977,6 @@ class Mcdev { return keyArr; } -} /** * Updates the key to match the name field * @@ -1055,6 +1054,7 @@ class Mcdev { */ static async _fixKeysBU(cred, bu, type, keyArr) { const properties = await config.getProperties(); + let counter_success = 0; let numItemsToUpdate = 0; let deployed; const toDeploy = []; @@ -1077,6 +1077,7 @@ class Mcdev { Util.logger.error(ex.message); return; } + Util.logger.info(`First retrieve ${type}`); const retriever = new Retriever(properties, buObject); const retrieved = await retriever.retrieve(type, keyArr, null, false); Object.keys(retrieved).forEach((key) => { @@ -1091,6 +1092,7 @@ class Mcdev { if (item != null) { if (item.name != item.key && !MetadataTypeDefinitions[type].keyIsFixed) { toDeploy.push(item.key); + counter_success++; Util.logger.info(`Updating key for query ${item.key}`); } else { numItemsToUpdate--; @@ -1103,33 +1105,15 @@ class Mcdev { } } }); - await MetadataTypeInfo[type].fixKeys(properties); + Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; properties.directories.deploy = properties.directories.retrieve; deployed = await Deployer._deployBU(cred, bu, properties, type, toDeploy, true); - await this.#retrieveDependentMetadata(cred, bu, type[0]); //type is an array with one type only + this._retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } return numItemsToUpdate === Object.values(deployed).length ? true : false; } - /** - *helper for {@link _fixKeysBU}. Retrieve dependent metadata - * - * @private - * @param {string} cred name of Credential - * @param {string} bu name of BU - * @param {string} type type of the metadata passed as a parameter to fixKeys function - */ - static async #retrieveDependentMetadata(cred, bu, type) { - const dependencies = []; - Util.logger.info(`\n :: Retrieving dependent metadata \n`); - for (const dependentType of Object.keys(MetadataTypeDefinitions)) { - if (MetadataTypeDefinitions[dependentType].dependencies.includes(type)) { - dependencies.push(dependentType); - } - } - await this._retrieveBU(cred, bu, dependencies); - } } module.exports = Mcdev; diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index 60d273fce..d18f75848 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -2007,14 +2007,6 @@ class MetadataType { const fileList = keyArr.map((key) => File.normalizePath([path, key + typeExtension])); return fileList; } - /** - * A function to set changeKeyField for fixKeys function - * - * @param {TYPE.Mcdevrc} properties central properties object - */ - static async fixKeys(properties) { - Util.OPTIONS.changeKeyField = this.definition.nameField; - } } MetadataType.definition = { diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json new file mode 100644 index 000000000..30b2f2852 --- /dev/null +++ b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json @@ -0,0 +1,11 @@ +{ + "name": "testExisting_query_fixKeys", + "key": "testExisting_query_fixKeys", + "description": "created on deploy", + "targetKey": "testExisting_dataExtension", + "createdDate": "2022-04-26T15:21:16.453", + "modifiedDate": "2022-04-26T16:04:15.88", + "targetUpdateTypeName": "Overwrite", + "isFrozen": false, + "r__folder_Path": "Query" +} diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql index e78525408..8020314ea 100644 --- a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql +++ b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql @@ -2,5 +2,3 @@ SELECT SubscriberKey as testField FROM _Subscribers -WHERE - country IN ('test') diff --git a/test/type.query.test.js b/test/type.query.test.js index ac5746251..20d14c26f 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -173,7 +173,7 @@ describe('type: query', () => { // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 8, + 9, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; @@ -201,54 +201,19 @@ describe('type: query', () => { // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 12, + 13, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); }); - describe('FixKeys ================', () => { - beforeEach(() => { - testUtils.mockSetup(true); - }); - it('Should update the key and re-deploy', async () => { - // WHEN - await handler.fixKeys('testInstance/testBU', ['query']); - // THEN - assert.equal(process.exitCode, false, 'fixKeys should not have thrown an error'); - // get results from cache - const result = cache.getCache(); - assert.equal( - result.query ? Object.keys(result.query).length : 0, - 2, - 'two queries expected' - ); - // confirm updated item - assert.deepEqual( - await testUtils.getActualJson('testExisting_query', 'query'), - await testUtils.getExpectedJson('9999999', 'query', 'patch1'), - 'returned metadata was not equal expected for insert query' - ); - expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.equal( - file(testUtils.getExpectedFile('9999999', 'query', 'patch1', 'sql')) - ); - // check number of API calls - assert.equal( - testUtils.getAPIHistoryLength(), - 27, - 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' - ); - return; - }); - it('Should change the key during update with --changeKeyValue'); - }); describe('Templating ================', () => { it('Should create a query template via retrieveAsTemplate and build it', async () => { // GIVEN there is a template const result = await handler.retrieveAsTemplate( 'testInstance/testBU', 'query', - ['testExisting_query1'], + ['testExisting_query'], 'testSourceMarket' ); // WHEN From 3e09830275df097f8984442c4f2c8100d9167450 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Tue, 11 Jul 2023 22:23:59 +0200 Subject: [PATCH 090/208] #38: revert --- ...stExisting_automation.automation-meta.json | 2 +- .../testNew_automation.automation-meta.json | 2 +- .../query/testExisting_query.query-meta.json | 2 +- .../query/testNew_query1.query-meta.json} | 6 ++--- ...meta.sql => testNew_query1.query-meta.sql} | 0 .../9999999/automation/build-expected.json | 2 +- .../9999999/automation/create-expected.json | 2 +- .../9999999/automation/retrieve-expected.json | 2 +- ...trieve-testExisting_automation-expected.md | 26 +++++++++---------- .../9999999/automation/template-expected.json | 2 +- .../9999999/automation/update-expected.json | 2 +- ...update-testExisting_automation-expected.md | 23 ++++++++-------- .../get-response.json | 2 +- .../patch-response.json | 2 +- .../automation/v1/queries/get-response.json | 19 +++++++++++++- .../9999999/query/build-expected.json | 2 +- .../resources/9999999/query/get-expected.json | 2 +- .../9999999/query/patch-expected.json | 2 +- .../9999999/query/patch1-expected.sql | 6 ----- .../9999999/query/template-expected.json | 2 +- test/type.query.test.js | 12 ++++++--- 21 files changed, 69 insertions(+), 51 deletions(-) rename test/{resources/9999999/query/patch1-expected.json => mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json} (68%) rename test/mockRoot/deploy/testInstance/testBU/query/{testExisting_query_fixKeys.query-meta.sql => testNew_query1.query-meta.sql} (100%) delete mode 100644 test/resources/9999999/query/patch1-expected.sql diff --git a/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json b/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json index 51f7c3efd..0110ca3e6 100644 --- a/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json +++ b/test/mockRoot/deploy/testInstance/testBU/automation/testExisting_automation.automation-meta.json @@ -30,7 +30,7 @@ "r__type": "importFile" }, { - "name": "testExisting_query1", + "name": "testExisting_query", "r__type": "query" }, { diff --git a/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json b/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json index 850ec8a24..715b69f27 100644 --- a/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json +++ b/test/mockRoot/deploy/testInstance/testBU/automation/testNew_automation.automation-meta.json @@ -30,7 +30,7 @@ "r__type": "importFile" }, { - "name": "testExisting_query1", + "name": "testExisting_query", "r__type": "query" }, { diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query.query-meta.json b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query.query-meta.json index 86a4a393c..421e918e5 100644 --- a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query.query-meta.json +++ b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query.query-meta.json @@ -1,5 +1,5 @@ { - "name": "testExisting_query1", + "name": "testExisting_query", "key": "testExisting_query", "description": "updated on deploy", "targetKey": "testExisting_dataExtension", diff --git a/test/resources/9999999/query/patch1-expected.json b/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json similarity index 68% rename from test/resources/9999999/query/patch1-expected.json rename to test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json index 86a4a393c..c29f18dc3 100644 --- a/test/resources/9999999/query/patch1-expected.json +++ b/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json @@ -1,7 +1,7 @@ { - "name": "testExisting_query1", - "key": "testExisting_query", - "description": "updated on deploy", + "name": "updateMePlease", + "key": "testNew_query1", + "description": "created on deploy", "targetKey": "testExisting_dataExtension", "createdDate": "2022-04-26T15:21:16.453", "modifiedDate": "2022-04-26T16:04:15.88", diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql b/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.sql similarity index 100% rename from test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql rename to test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.sql diff --git a/test/resources/9999999/automation/build-expected.json b/test/resources/9999999/automation/build-expected.json index d8c32fd40..87301aa55 100644 --- a/test/resources/9999999/automation/build-expected.json +++ b/test/resources/9999999/automation/build-expected.json @@ -30,7 +30,7 @@ "r__type": "importFile" }, { - "name": "testTemplated_query1", + "name": "testTemplated_query", "r__type": "query" }, { diff --git a/test/resources/9999999/automation/create-expected.json b/test/resources/9999999/automation/create-expected.json index 9e40f520d..92ea826e1 100644 --- a/test/resources/9999999/automation/create-expected.json +++ b/test/resources/9999999/automation/create-expected.json @@ -31,7 +31,7 @@ "r__type": "importFile" }, { - "name": "testExisting_query1", + "name": "testExisting_query", "r__type": "query" }, { diff --git a/test/resources/9999999/automation/retrieve-expected.json b/test/resources/9999999/automation/retrieve-expected.json index 55a7c1767..f4771678a 100644 --- a/test/resources/9999999/automation/retrieve-expected.json +++ b/test/resources/9999999/automation/retrieve-expected.json @@ -30,7 +30,7 @@ "r__type": "importFile" }, { - "name": "testExisting_query1", + "name": "testExisting_query", "r__type": "query" }, { diff --git a/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md b/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md index 8f4d2396b..22bd4c500 100644 --- a/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md +++ b/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md @@ -10,21 +10,21 @@ **Schedule:** -- Start: 2022-07-30 00:00:00 +01:00 -- End: 2022-07-30 00:00:00 +01:00 -- Timezone: W. Europe Standard Time -- Recurrance: every day for 1 times +* Start: 2022-07-30 00:00:00 +01:00 +* End: 2022-07-30 00:00:00 +01:00 +* Timezone: W. Europe Standard Time +* Recurrance: every day for 1 times **Notifications:** -- Complete: complete@test.accenture.com -- Error: error@test.accenture.com ("test") +* Complete: complete@test.accenture.com +* Error: error@test.accenture.com ("test") -| Step 1
_-_ | -| ------------------------------------------------ | -| _1.1: dataExtract_
testExisting_dataExtract | -| _1.2: emailSend_
testExisting_emailSend | +| Step 1
_-_ | +| --- | +| _1.1: dataExtract_
testExisting_dataExtract | +| _1.2: emailSend_
testExisting_emailSend | | _1.3: fileTransfer_
testExisting_fileTransfer | -| _1.4: importFile_
testExisting_importFile | -| _1.5: query_
testExisting_query1 | -| _1.6: script_
testExisting_script | +| _1.4: importFile_
testExisting_importFile | +| _1.5: query_
testExisting_query | +| _1.6: script_
testExisting_script | diff --git a/test/resources/9999999/automation/template-expected.json b/test/resources/9999999/automation/template-expected.json index c82ba388b..32a6bcbc5 100644 --- a/test/resources/9999999/automation/template-expected.json +++ b/test/resources/9999999/automation/template-expected.json @@ -30,7 +30,7 @@ "r__type": "importFile" }, { - "name": "{{{prefix}}}query1", + "name": "{{{prefix}}}query", "r__type": "query" }, { diff --git a/test/resources/9999999/automation/update-expected.json b/test/resources/9999999/automation/update-expected.json index 6ba9e73b8..0705285b5 100644 --- a/test/resources/9999999/automation/update-expected.json +++ b/test/resources/9999999/automation/update-expected.json @@ -30,7 +30,7 @@ "r__type": "importFile" }, { - "name": "testExisting_query1", + "name": "testExisting_query", "r__type": "query" }, { diff --git a/test/resources/9999999/automation/update-testExisting_automation-expected.md b/test/resources/9999999/automation/update-testExisting_automation-expected.md index a18e49e0f..681c2a694 100644 --- a/test/resources/9999999/automation/update-testExisting_automation-expected.md +++ b/test/resources/9999999/automation/update-testExisting_automation-expected.md @@ -10,18 +10,19 @@ **Schedule:** -- Start: 2022-07-30 00:00:00 +01:00 -- End: 2022-07-30 00:00:00 +01:00 -- Timezone: W. Europe Standard Time -- Recurrance: every day for 1 times +* Start: 2022-07-30 00:00:00 +01:00 +* End: 2022-07-30 00:00:00 +01:00 +* Timezone: W. Europe Standard Time +* Recurrance: every day for 1 times **Notifications:** _none_ -| Step 1
_-_ | -| ------------------------------------------------ | -| _1.1: dataExtract_
testExisting_dataExtract | -| _1.2: emailSend_
testExisting_emailSend | + +| Step 1
_-_ | +| --- | +| _1.1: dataExtract_
testExisting_dataExtract | +| _1.2: emailSend_
testExisting_emailSend | | _1.3: fileTransfer_
testExisting_fileTransfer | -| _1.4: importFile_
testExisting_importFile | -| _1.5: query_
testExisting_query1 | -| _1.6: script_
testExisting_script | +| _1.4: importFile_
testExisting_importFile | +| _1.5: query_
testExisting_query | +| _1.6: script_
testExisting_script | diff --git a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json index fff3e1592..9144d0e0b 100644 --- a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json +++ b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/get-response.json @@ -1,6 +1,6 @@ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat", - "name": "testExisting_query1", + "name": "testExisting_query", "key": "testExisting_query", "description": "bla bla", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", diff --git a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json index 8433390a8..6414f11dc 100644 --- a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json +++ b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat/patch-response.json @@ -1,6 +1,6 @@ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat", - "name": "testExisting_query1", + "name": "testExisting_query", "key": "testExisting_query", "description": "updated on deploy", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", diff --git a/test/resources/9999999/automation/v1/queries/get-response.json b/test/resources/9999999/automation/v1/queries/get-response.json index 39ee926c5..31305c1f3 100644 --- a/test/resources/9999999/automation/v1/queries/get-response.json +++ b/test/resources/9999999/automation/v1/queries/get-response.json @@ -5,7 +5,7 @@ "items": [ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat", - "name": "testExisting_query1", + "name": "testExisting_query", "key": "testExisting_query", "description": "bla bla", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", @@ -36,6 +36,23 @@ "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false + }, + { + "queryDefinitionId": "b28a1c2f-6656-478a-be51-4f12be4c9088", + "name": "updateMePlease", + "key": "testNew_query1", + "description": "bla bla", + "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", + "targetName": "testExisting_dataExtension", + "targetKey": "testExisting_dataExtension-WRONG", + "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", + "targetDescription": "", + "createdDate": "2022-04-26T15:21:16.453", + "modifiedDate": "2022-04-26T16:02:44.01", + "targetUpdateTypeId": 0, + "targetUpdateTypeName": "Overwrite", + "categoryId": 999, + "isFrozen": false } ] } diff --git a/test/resources/9999999/query/build-expected.json b/test/resources/9999999/query/build-expected.json index 72c92e729..a7df67267 100644 --- a/test/resources/9999999/query/build-expected.json +++ b/test/resources/9999999/query/build-expected.json @@ -1,5 +1,5 @@ { - "name": "testTemplated_query1", + "name": "testTemplated_query", "key": "testTemplated_query", "description": "foobar", "targetKey": "testTemplated_dataExtension", diff --git a/test/resources/9999999/query/get-expected.json b/test/resources/9999999/query/get-expected.json index e5571691e..4cd606716 100644 --- a/test/resources/9999999/query/get-expected.json +++ b/test/resources/9999999/query/get-expected.json @@ -1,5 +1,5 @@ { - "name": "testExisting_query1", + "name": "testExisting_query", "key": "testExisting_query", "description": "bla bla", "targetKey": "testExisting_dataExtension", diff --git a/test/resources/9999999/query/patch-expected.json b/test/resources/9999999/query/patch-expected.json index 86a4a393c..421e918e5 100644 --- a/test/resources/9999999/query/patch-expected.json +++ b/test/resources/9999999/query/patch-expected.json @@ -1,5 +1,5 @@ { - "name": "testExisting_query1", + "name": "testExisting_query", "key": "testExisting_query", "description": "updated on deploy", "targetKey": "testExisting_dataExtension", diff --git a/test/resources/9999999/query/patch1-expected.sql b/test/resources/9999999/query/patch1-expected.sql deleted file mode 100644 index 2a32f5fad..000000000 --- a/test/resources/9999999/query/patch1-expected.sql +++ /dev/null @@ -1,6 +0,0 @@ -SELECT - SubscriberKey AS testField -FROM - _Subscribers -WHERE - country IN ('test') diff --git a/test/resources/9999999/query/template-expected.json b/test/resources/9999999/query/template-expected.json index 3f6caf4a6..9f9bd2806 100644 --- a/test/resources/9999999/query/template-expected.json +++ b/test/resources/9999999/query/template-expected.json @@ -1,5 +1,5 @@ { - "name": "{{{prefix}}}query1", + "name": "{{{prefix}}}query", "key": "{{{prefix}}}query", "description": "{{{description}}}", "targetKey": "{{{prefix}}}dataExtension", diff --git a/test/type.query.test.js b/test/type.query.test.js index 20d14c26f..b04579c57 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -27,7 +27,7 @@ describe('type: query', () => { const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 2, + 3, 'only two queries expected' ); // normal test @@ -142,14 +142,18 @@ describe('type: query', () => { }); it('Should create & upsert a query', async () => { // WHEN - await handler.deploy('testInstance/testBU', ['query']); + await handler.deploy( + 'testInstance/testBU', + ['query'], + ['testNew_query', 'testExisting_query'] + ); // THEN assert.equal(process.exitCode, false, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 3, + 4, 'three queries expected' ); // confirm created item @@ -183,6 +187,7 @@ describe('type: query', () => { handler.setOptions({ execute: true }); // WHEN await handler.deploy('testInstance/testBU', ['query']); + await handler.deploy('testInstance/testBU', ['query']); // THEN assert.equal( process.exitCode, @@ -214,6 +219,7 @@ describe('type: query', () => { 'testInstance/testBU', 'query', ['testExisting_query'], + ['testExisting_query'], 'testSourceMarket' ); // WHEN From 11ccdb34deea150cbae31e67e71fb01d7cf488aa Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Tue, 11 Jul 2023 22:27:58 +0200 Subject: [PATCH 091/208] #38: test query --- ....sql => testExisting_query_fixKeys.query-meta.sql} | 0 .../testBU/query/testNew_query1.query-meta.json | 11 ----------- 2 files changed, 11 deletions(-) rename test/mockRoot/deploy/testInstance/testBU/query/{testNew_query1.query-meta.sql => testExisting_query_fixKeys.query-meta.sql} (100%) delete mode 100644 test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.sql b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql similarity index 100% rename from test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.sql rename to test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json b/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json deleted file mode 100644 index c29f18dc3..000000000 --- a/test/mockRoot/deploy/testInstance/testBU/query/testNew_query1.query-meta.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "updateMePlease", - "key": "testNew_query1", - "description": "created on deploy", - "targetKey": "testExisting_dataExtension", - "createdDate": "2022-04-26T15:21:16.453", - "modifiedDate": "2022-04-26T16:04:15.88", - "targetUpdateTypeName": "Overwrite", - "isFrozen": false, - "r__folder_Path": "Query" -} From 7cfc7b39ea0b1728849362161ede6a7af89b1286 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Tue, 11 Jul 2023 22:29:54 +0200 Subject: [PATCH 092/208] #38: revert state of test class to origin --- test/type.query.test.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/test/type.query.test.js b/test/type.query.test.js index b04579c57..b82df7cc4 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -27,7 +27,7 @@ describe('type: query', () => { const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 3, + 2, 'only two queries expected' ); // normal test @@ -142,18 +142,14 @@ describe('type: query', () => { }); it('Should create & upsert a query', async () => { // WHEN - await handler.deploy( - 'testInstance/testBU', - ['query'], - ['testNew_query', 'testExisting_query'] - ); + await handler.deploy('testInstance/testBU', ['query']); // THEN assert.equal(process.exitCode, false, 'deploy should not have thrown an error'); // get results from cache const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 4, + 3, 'three queries expected' ); // confirm created item @@ -177,7 +173,7 @@ describe('type: query', () => { // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 9, + 8, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; @@ -187,7 +183,6 @@ describe('type: query', () => { handler.setOptions({ execute: true }); // WHEN await handler.deploy('testInstance/testBU', ['query']); - await handler.deploy('testInstance/testBU', ['query']); // THEN assert.equal( process.exitCode, @@ -206,7 +201,7 @@ describe('type: query', () => { // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 13, + 12, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; @@ -219,7 +214,6 @@ describe('type: query', () => { 'testInstance/testBU', 'query', ['testExisting_query'], - ['testExisting_query'], 'testSourceMarket' ); // WHEN From aaeb6ee3a0dd56396867bcaf919fc69a14403a50 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Wed, 12 Jul 2023 10:43:19 +0200 Subject: [PATCH 093/208] #38: removed space in expected automation files --- .../automation/retrieve-testExisting_automation-expected.md | 2 +- .../automation/update-testExisting_automation-expected.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md b/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md index 22bd4c500..ae8f4c10a 100644 --- a/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md +++ b/test/resources/9999999/automation/retrieve-testExisting_automation-expected.md @@ -12,7 +12,7 @@ * Start: 2022-07-30 00:00:00 +01:00 * End: 2022-07-30 00:00:00 +01:00 -* Timezone: W. Europe Standard Time +* Timezone: W. Europe Standard Time * Recurrance: every day for 1 times **Notifications:** diff --git a/test/resources/9999999/automation/update-testExisting_automation-expected.md b/test/resources/9999999/automation/update-testExisting_automation-expected.md index 681c2a694..fbee3558c 100644 --- a/test/resources/9999999/automation/update-testExisting_automation-expected.md +++ b/test/resources/9999999/automation/update-testExisting_automation-expected.md @@ -12,7 +12,7 @@ * Start: 2022-07-30 00:00:00 +01:00 * End: 2022-07-30 00:00:00 +01:00 -* Timezone: W. Europe Standard Time +* Timezone: W. Europe Standard Time * Recurrance: every day for 1 times **Notifications:** _none_ From e1ad0f1859b5a8c989bf628bae69454b79e2f7a4 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Wed, 12 Jul 2023 11:08:56 +0200 Subject: [PATCH 094/208] #38: reverted test changes --- .../testExisting_query_fixKeys.query-meta.json | 11 ----------- .../testExisting_query_fixKeys.query-meta.sql | 4 ---- .../patch-response.json | 17 ----------------- .../automation/v1/queries/get-response.json | 17 ----------------- .../resources/9999999/query/post2-expected.json | 11 ----------- test/resources/9999999/query/post2-expected.sql | 4 ---- 6 files changed, 64 deletions(-) delete mode 100644 test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json delete mode 100644 test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql delete mode 100644 test/resources/9999999/automation/v1/queries/b28a1c2f-6656-478a-be51-4f12be4c9088/patch-response.json delete mode 100644 test/resources/9999999/query/post2-expected.json delete mode 100644 test/resources/9999999/query/post2-expected.sql diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json deleted file mode 100644 index 30b2f2852..000000000 --- a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "testExisting_query_fixKeys", - "key": "testExisting_query_fixKeys", - "description": "created on deploy", - "targetKey": "testExisting_dataExtension", - "createdDate": "2022-04-26T15:21:16.453", - "modifiedDate": "2022-04-26T16:04:15.88", - "targetUpdateTypeName": "Overwrite", - "isFrozen": false, - "r__folder_Path": "Query" -} diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql deleted file mode 100644 index 8020314ea..000000000 --- a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql +++ /dev/null @@ -1,4 +0,0 @@ -SELECT - SubscriberKey as testField -FROM - _Subscribers diff --git a/test/resources/9999999/automation/v1/queries/b28a1c2f-6656-478a-be51-4f12be4c9088/patch-response.json b/test/resources/9999999/automation/v1/queries/b28a1c2f-6656-478a-be51-4f12be4c9088/patch-response.json deleted file mode 100644 index 8b09c6842..000000000 --- a/test/resources/9999999/automation/v1/queries/b28a1c2f-6656-478a-be51-4f12be4c9088/patch-response.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "queryDefinitionId": "b28a1c2f-6656-478a-be51-4f12be4c9088", - "name": "updateMePlease", - "key": "updateMePlease", - "description": "bla bla", - "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", - "targetName": "testExisting_dataExtension", - "targetKey": "testExisting_dataExtension-WRONG", - "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", - "targetDescription": "", - "createdDate": "2022-04-26T15:21:16.453", - "modifiedDate": "2022-04-26T16:02:44.01", - "targetUpdateTypeId": 0, - "targetUpdateTypeName": "Overwrite", - "categoryId": 999, - "isFrozen": false -} diff --git a/test/resources/9999999/automation/v1/queries/get-response.json b/test/resources/9999999/automation/v1/queries/get-response.json index 31305c1f3..4a7b047ec 100644 --- a/test/resources/9999999/automation/v1/queries/get-response.json +++ b/test/resources/9999999/automation/v1/queries/get-response.json @@ -36,23 +36,6 @@ "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false - }, - { - "queryDefinitionId": "b28a1c2f-6656-478a-be51-4f12be4c9088", - "name": "updateMePlease", - "key": "testNew_query1", - "description": "bla bla", - "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", - "targetName": "testExisting_dataExtension", - "targetKey": "testExisting_dataExtension-WRONG", - "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", - "targetDescription": "", - "createdDate": "2022-04-26T15:21:16.453", - "modifiedDate": "2022-04-26T16:02:44.01", - "targetUpdateTypeId": 0, - "targetUpdateTypeName": "Overwrite", - "categoryId": 999, - "isFrozen": false } ] } diff --git a/test/resources/9999999/query/post2-expected.json b/test/resources/9999999/query/post2-expected.json deleted file mode 100644 index 95177685f..000000000 --- a/test/resources/9999999/query/post2-expected.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "updateMePlease", - "key": "testNew_query", - "description": "created on deploy", - "targetKey": "testExisting_dataExtension", - "createdDate": "2022-04-26T15:21:16.453", - "modifiedDate": "2022-04-26T16:04:15.88", - "targetUpdateTypeName": "Overwrite", - "isFrozen": false, - "r__folder_Path": "Query" -} diff --git a/test/resources/9999999/query/post2-expected.sql b/test/resources/9999999/query/post2-expected.sql deleted file mode 100644 index 4148833c4..000000000 --- a/test/resources/9999999/query/post2-expected.sql +++ /dev/null @@ -1,4 +0,0 @@ -SELECT - SubscriberKey AS testField -FROM - _Subscribers From bbbe4b7320b01ac011e18237ac13af25bed7c2f8 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Wed, 12 Jul 2023 12:08:54 +0200 Subject: [PATCH 095/208] #38: test classes updated --- ...testExisting_query_fixKeys.query-meta.json | 11 ++ .../testExisting_query_fixKeys.query-meta.sql | 6 + .../get-response.json | 17 +++ .../patch-response.json | 18 +++ .../automation/v1/queries/get-response.json | 19 ++- ...query_fixKeysANDStatus=Active-response.xml | 30 ++++ test/type.query.test.js | 136 ++++++++++++++++-- 7 files changed, 226 insertions(+), 11 deletions(-) create mode 100644 test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json create mode 100644 test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql create mode 100644 test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json create mode 100644 test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/patch-response.json create mode 100644 test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixKeysANDStatus=Active-response.xml diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json new file mode 100644 index 000000000..ef7ff4fbe --- /dev/null +++ b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json @@ -0,0 +1,11 @@ +{ + "name": "testExisting_query_fixedKey", + "key": "testExisting_query_fixKeys", + "description": "updated on deploy", + "targetKey": "testExisting_dataExtension", + "createdDate": "2022-04-26T15:21:16.453", + "modifiedDate": "2022-04-26T16:04:15.88", + "targetUpdateTypeName": "Overwrite", + "isFrozen": false, + "r__folder_Path": "Query" +} diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql new file mode 100644 index 000000000..e78525408 --- /dev/null +++ b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.sql @@ -0,0 +1,6 @@ +SELECT + SubscriberKey as testField +FROM + _Subscribers +WHERE + country IN ('test') diff --git a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json new file mode 100644 index 000000000..75b81ceeb --- /dev/null +++ b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json @@ -0,0 +1,17 @@ +{ + "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat_fixKeys", + "name": "testExisting_query_fixedKey", + "key": "testExisting_query_fixKeys", + "description": "bla bla", + "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", + "targetName": "testExisting_dataExtension", + "targetKey": "testExisting_dataExtension", + "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", + "targetDescription": "", + "createdDate": "2022-04-26T15:21:16.453", + "modifiedDate": "2022-04-26T16:02:44.01", + "targetUpdateTypeId": 0, + "targetUpdateTypeName": "Overwrite", + "categoryId": 999, + "isFrozen": false +} diff --git a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/patch-response.json b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/patch-response.json new file mode 100644 index 000000000..599678503 --- /dev/null +++ b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/patch-response.json @@ -0,0 +1,18 @@ +{ + "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat_fixKeys", + "name": "testExisting_query_fixedKeys", + "key": "testExisting_query_fixedKeys", + "description": "updated on deploy", + "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", + "targetName": "testExisting_dataExtension", + "targetKey": "testExisting_dataExtension", + "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", + "targetDescription": "", + "createdDate": "2022-04-26T15:21:16.453", + "modifiedDate": "2022-04-26T16:04:15.88", + "targetUpdateTypeId": 0, + "targetUpdateTypeName": "Overwrite", + "validatedQueryText": "SET NOCOUNT ON; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;\r\n\r\nINSERT INTO C518001158.[testDataExtension] ([testField])\r\nSELECT querydef.[testField]\r\nFROM (SELECT SubscriberKey as testField FROM C518001158._Subscribers ) AS querydef \r\nSELECT @rcInsert = @@ROWCOUNT;;\r\n", + "categoryId": 999, + "isFrozen": false +} diff --git a/test/resources/9999999/automation/v1/queries/get-response.json b/test/resources/9999999/automation/v1/queries/get-response.json index 4a7b047ec..416c68479 100644 --- a/test/resources/9999999/automation/v1/queries/get-response.json +++ b/test/resources/9999999/automation/v1/queries/get-response.json @@ -1,5 +1,5 @@ { - "count": 2, + "count": 3, "page": 1, "pageSize": 50, "items": [ @@ -36,6 +36,23 @@ "targetUpdateTypeName": "Overwrite", "categoryId": 999, "isFrozen": false + }, + { + "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat_fixKeys", + "name": "testExisting_query_fixedKey", + "key": "testExisting_query_fixKeys", + "description": "bla bla", + "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", + "targetName": "testExisting_dataExtension", + "targetKey": "testExisting_dataExtension", + "targetId": "21711373-72c1-ec11-b83b-48df37d1deb7", + "targetDescription": "", + "createdDate": "2022-04-26T15:21:16.453", + "modifiedDate": "2022-04-26T16:02:44.01", + "targetUpdateTypeId": 0, + "targetUpdateTypeName": "Overwrite", + "categoryId": 999, + "isFrozen": false } ] } diff --git a/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixKeysANDStatus=Active-response.xml b/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixKeysANDStatus=Active-response.xml new file mode 100644 index 000000000..d816ae0d9 --- /dev/null +++ b/test/resources/9999999/queryDefinition/retrieve-CustomerKey=testExisting_query_fixKeysANDStatus=Active-response.xml @@ -0,0 +1,30 @@ + + + + RetrieveResponse + urn:uuid:7ef0345e-b559-4fc4-8986-47e54e1a8a58 + urn:uuid:b2e814a6-517c-4882-9bbb-238bfce951ce + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-04-11T16:33:48Z + 2023-04-11T16:38:48Z + + + + + + OK + e8eb2988-2f43-4243-a6b0-6ab6b841a6ab + + + 549f0568-607c-4940-afef-437965094dat_fixKeys + + + + diff --git a/test/type.query.test.js b/test/type.query.test.js index b82df7cc4..34f9cb9d3 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -27,8 +27,8 @@ describe('type: query', () => { const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 2, - 'only two queries expected' + 3, + 'only three queries expected' ); // normal test assert.deepEqual( @@ -90,8 +90,8 @@ describe('type: query', () => { const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 2, - 'two queries in cache expected' + 3, + 'three queries in cache expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_query', 'query'), @@ -120,8 +120,8 @@ describe('type: query', () => { const result = cache.getCache(); assert.equal( result.query ? Object.keys(result.query).length : 0, - 2, - 'two queries in cache expected' + 3, + 'three queries in cache expected' ); expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.not @@ -142,15 +142,27 @@ describe('type: query', () => { }); it('Should create & upsert a query', async () => { // WHEN - await handler.deploy('testInstance/testBU', ['query']); + const resultDeploy = await handler.deploy( + 'testInstance/testBU', + ['query'], + ['testNew_query', 'testExisting_query'] + ); // THEN assert.equal(process.exitCode, false, 'deploy should not have thrown an error'); + assert.equal( + resultDeploy['testInstance/testBU']?.query + ? Object.keys(resultDeploy['testInstance/testBU']?.query).length + : 0, + 2, + 'two queries to be deployed' + ); // get results from cache const result = cache.getCache(); + console.log(result.query); assert.equal( result.query ? Object.keys(result.query).length : 0, - 3, - 'three queries expected' + 4, + 'four queries expected in cache' ); // confirm created item assert.deepEqual( @@ -182,7 +194,11 @@ describe('type: query', () => { it('Should deploy and execute with --execute', async () => { handler.setOptions({ execute: true }); // WHEN - await handler.deploy('testInstance/testBU', ['query']); + await handler.deploy( + 'testInstance/testBU', + ['query'], + ['testExisting_query', 'testNew_query'] + ); // THEN assert.equal( process.exitCode, @@ -207,6 +223,106 @@ describe('type: query', () => { return; }); }); + describe('FixKeys ================', () => { + beforeEach(() => { + testUtils.mockSetup(true); + }); + it('Should not fixKeys and deploy', async () => { + // WHEN + await handler.fixKeys('testInstance/testBU', ['query'], ['testExisting_query']); + // THEN + assert.equal(process.exitCode, false, 'fixKeys should not have thrown an error'); + // get results from cache + const result = cache.getCache(); + assert.equal( + result.query ? Object.keys(result.query).length : 0, + 1, + 'one query expected' + ); + // confirm created item + // assert.deepEqual( + // await testUtils.getActualJson('testNew_query', 'query'), + // await testUtils.getExpectedJson('9999999', 'query', 'post'), + // 'returned metadata was not equal expected for insert query' + // ); + // expect(file(testUtils.getActualFile('testNew_query', 'query', 'sql'))).to.equal( + // file(testUtils.getExpectedFile('9999999', 'query', 'post', 'sql')) + // ); + // // confirm updated item + // assert.deepEqual( + // await testUtils.getActualJson('testExisting_query', 'query'), + // await testUtils.getExpectedJson('9999999', 'query', 'patch'), + // 'returned metadata was not equal expected for insert query' + // ); + // expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.equal( + // file(testUtils.getExpectedFile('9999999', 'query', 'patch', 'sql')) + // ); + // check number of API calls + assert.equal( + testUtils.getAPIHistoryLength(), + 7, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + it('Should fixKeys and deploy', async () => { + // WHEN + await handler.fixKeys('testInstance/testBU', ['query'], ['testExisting_query_fixKeys']); + // THEN + assert.equal(process.exitCode, false, 'fixKeys should not have thrown an error'); + // get results from cache + const result = cache.getCache(); + assert.equal( + result.query ? Object.keys(result.query).length : 0, + 4, + 'four queries expected in cache' + ); + // confirm updated item + assert.deepEqual( + await testUtils.getActualJson('testExisting_query_fixedKey', 'query'), + await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKey'), + 'returned metadata was not equal expected for insert query' + ); + expect( + file(testUtils.getActualFile('testExisting_query_fixedKey', 'query', 'sql')) + ).to.equal(file(testUtils.getExpectedFile('9999999', 'query', 'patch_fixKey', 'sql'))); + // check number of API calls + assert.equal( + testUtils.getAPIHistoryLength(), + 14, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + // it('Should change the key during update with --changeKeyValue'); + // it('Should deploy and execute with --execute', async () => { + // handler.setOptions({ execute: true }); + // // WHEN + // await handler.deploy('testInstance/testBU', ['query']); + // // THEN + // assert.equal( + // process.exitCode, + // false, + // 'deploy with --execute should not have thrown an error' + // ); + // // confirm updated item + // assert.deepEqual( + // await testUtils.getActualJson('testExisting_query', 'query'), + // await testUtils.getExpectedJson('9999999', 'query', 'patch'), + // 'returned metadata was not equal expected for insert query' + // ); + // expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.equal( + // file(testUtils.getExpectedFile('9999999', 'query', 'patch', 'sql')) + // ); + // // check number of API calls + // assert.equal( + // testUtils.getAPIHistoryLength(), + // 12, + // 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + // ); + // return; + // }); + }); describe('Templating ================', () => { it('Should create a query template via retrieveAsTemplate and build it', async () => { // GIVEN there is a template From d26dfff65fd5a0d95a7ad7c5a97fb0dab164d9ab Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Wed, 12 Jul 2023 12:11:00 +0200 Subject: [PATCH 096/208] #38: exit the function if there are no keys to update --- lib/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index aec68dd85..99d2ab52a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1107,8 +1107,12 @@ class Mcdev { }); Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; properties.directories.deploy = properties.directories.retrieve; + if (numItemsToUpdate < 1) { + Util.logger.info(`No items to update. Exiting`); + return true; + } deployed = await Deployer._deployBU(cred, bu, properties, type, toDeploy, true); - this._retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); + this.#retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } From 9f546ac67088f581f405ad04d55c5e13e1d662f2 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Wed, 12 Jul 2023 12:48:27 +0200 Subject: [PATCH 097/208] #38: redundant variable removed --- lib/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/index.js b/lib/index.js index 99d2ab52a..397fbbd6f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1054,7 +1054,6 @@ class Mcdev { */ static async _fixKeysBU(cred, bu, type, keyArr) { const properties = await config.getProperties(); - let counter_success = 0; let numItemsToUpdate = 0; let deployed; const toDeploy = []; @@ -1092,7 +1091,6 @@ class Mcdev { if (item != null) { if (item.name != item.key && !MetadataTypeDefinitions[type].keyIsFixed) { toDeploy.push(item.key); - counter_success++; Util.logger.info(`Updating key for query ${item.key}`); } else { numItemsToUpdate--; From aa09038c81953e8d18fae980cd7c1752ff322846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 12 Jul 2023 14:04:03 +0200 Subject: [PATCH 098/208] #711: remove not supported create method --- docs/dist/documentation.md | 72 ----------------------------- lib/metadataTypes/AttributeGroup.js | 9 ---- 2 files changed, 81 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index f3fdcfac8..bb35e5913 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -17,9 +17,6 @@ Source and target business units are also compared before the deployment to appl
AttributeGroupMetadataType

AttributeGroup MetadataType

-
AttributeRelationshipMetadataType
-

AttributeRelationship MetadataType

-
AttributeSetMetadataType

AttributeSet MetadataType

@@ -1222,7 +1219,6 @@ AttributeGroup MetadataType * [AttributeGroup](#AttributeGroup) ⇐ [MetadataType](#MetadataType) * [.retrieve(retrieveDir, [_], [__], [key])](#AttributeGroup.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveForCache()](#AttributeGroup.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> - * [.create(metadata)](#AttributeGroup.create) ⇒ Promise * [.postRetrieveTasks(metadata)](#AttributeGroup.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem * [.preDeployTasks(metadata)](#AttributeGroup.preDeployTasks) ⇒ TYPE.MetadataTypeItem @@ -1248,18 +1244,6 @@ Retrieves Metadata of schema attribute groups for caching. **Kind**: static method of [AttributeGroup](#AttributeGroup) **Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of metadata - - -### AttributeGroup.create(metadata) ⇒ Promise -Creates a single item - -**Kind**: static method of [AttributeGroup](#AttributeGroup) -**Returns**: Promise - Promise - -| Param | Type | Description | -| --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single item | - ### AttributeGroup.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem @@ -1284,62 +1268,6 @@ prepares for deployment | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single item | - - -## AttributeRelationship ⇐ [MetadataType](#MetadataType) -AttributeRelationship MetadataType - -**Kind**: global class -**Extends**: [MetadataType](#MetadataType) - -* [AttributeRelationship](#AttributeRelationship) ⇐ [MetadataType](#MetadataType) - * [.retrieve(retrieveDir, [_], [__], [relationshipID], attributeSetId)](#AttributeRelationship.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> - * [.retrieveForCache(_, __, attributeSetId, relationshipID)](#AttributeRelationship.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> - * [.postRetrieveTasks(metadata)](#AttributeRelationship.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem - - - -### AttributeRelationship.retrieve(retrieveDir, [_], [__], [relationshipID], attributeSetId) ⇒ Promise.<TYPE.MetadataTypeMapObj> -Retrieves Metadata of schema attribute groups. - -**Kind**: static method of [AttributeRelationship](#AttributeRelationship) -**Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of metadata - -| Param | Type | Description | -| --- | --- | --- | -| retrieveDir | string | Directory where retrieved metadata directory will be saved | -| [_] | void | unused parameter | -| [__] | void | unused parameter | -| [relationshipID] | string | customer key of single item to retrieve | -| attributeSetId | string | CUSTOM: Id of the attribute set for which these relationships are defined | - - - -### AttributeRelationship.retrieveForCache(_, __, attributeSetId, relationshipID) ⇒ Promise.<TYPE.MetadataTypeMapObj> -Retrieves Metadata of schema attribute groups for caching. - -**Kind**: static method of [AttributeRelationship](#AttributeRelationship) -**Returns**: Promise.<TYPE.MetadataTypeMapObj> - Promise of metadata - -| Param | Type | Description | -| --- | --- | --- | -| _ | void | unused parameter | -| __ | void | unused parameter | -| attributeSetId | string | CUSTOM: Id of the attribute set for which these relationships are defined | -| relationshipID | string | CUSTOM: customer key of single item to retrieve | - - - -### AttributeRelationship.postRetrieveTasks(metadata) ⇒ TYPE.MetadataTypeItem -manages post retrieve steps - -**Kind**: static method of [AttributeRelationship](#AttributeRelationship) -**Returns**: TYPE.MetadataTypeItem - metadata - -| Param | Type | Description | -| --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single metadata | - ## AttributeSet ⇐ [MetadataType](#MetadataType) diff --git a/lib/metadataTypes/AttributeGroup.js b/lib/metadataTypes/AttributeGroup.js index 97ddd595f..cf4804bcd 100644 --- a/lib/metadataTypes/AttributeGroup.js +++ b/lib/metadataTypes/AttributeGroup.js @@ -36,15 +36,6 @@ class AttributeGroup extends MetadataType { static retrieveForCache() { return super.retrieveREST(null, '/hub/v1/contacts/schema/attributeGroups'); } - /** - * Creates a single item - * - * @param {TYPE.MetadataTypeItem} metadata a single item - * @returns {Promise} Promise - */ - static create(metadata) { - return super.createREST(metadata, '/hub/v1/contacts/schema/attributeGroups'); - } /** * manages post retrieve steps From 621774a8699b54ad6dc7c2ce34f4e5c9f1b0d6b0 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Wed, 12 Jul 2023 14:25:50 +0200 Subject: [PATCH 099/208] #38: missing await --- lib/index.js | 2 +- test/type.query.test.js | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/index.js b/lib/index.js index 397fbbd6f..fa23181a9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1110,7 +1110,7 @@ class Mcdev { return true; } deployed = await Deployer._deployBU(cred, bu, properties, type, toDeploy, true); - this.#retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); + await this.#retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } diff --git a/test/type.query.test.js b/test/type.query.test.js index 34f9cb9d3..5ef17726c 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -267,16 +267,21 @@ describe('type: query', () => { }); it('Should fixKeys and deploy', async () => { // WHEN - await handler.fixKeys('testInstance/testBU', ['query'], ['testExisting_query_fixKeys']); + const resultFixKeys = await handler.fixKeys( + 'testInstance/testBU', + ['query'], + ['testExisting_query_fixKeys'] + ); // THEN assert.equal(process.exitCode, false, 'fixKeys should not have thrown an error'); + assert.equal(resultFixKeys, true, 'fixKeys should not have thrown an error'); // get results from cache - const result = cache.getCache(); - assert.equal( - result.query ? Object.keys(result.query).length : 0, - 4, - 'four queries expected in cache' - ); + // const result = cache.getCache(); + // assert.equal( + // result.query ? Object.keys(result.query).length : 0, + // 4, + // 'four queries expected in cache' + // ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKey', 'query'), From 4bc60d58d91bd4643d6b19b769c6c7cbd308d295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 12 Jul 2023 14:33:06 +0200 Subject: [PATCH 100/208] #711: add setDefinition to list of renamed types --- lib/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/index.js b/lib/index.js index 775364b0a..323f087f4 100644 --- a/lib/index.js +++ b/lib/index.js @@ -265,6 +265,7 @@ class Mcdev { // clean up old folders after types were renamed // TODO: Remove renamedTypes-logic 6 months after version 5 release const renamedTypes = { + attributeSet: 'setDefinition', emailSend: 'emailSendDefinition', event: 'eventDefinition', fileLocation: 'ftpLocation', From 5568a1bf2570acfc50f6d75e20286570721a2ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 12 Jul 2023 15:47:09 +0200 Subject: [PATCH 101/208] #38: refactoring --- docs/dist/documentation.md | 42 +++++++++++++++++ lib/index.js | 77 +++++++++++++------------------ lib/metadataTypes/MetadataType.js | 40 ++++++++++++++++ test/type.query.test.js | 21 +-------- 4 files changed, 114 insertions(+), 66 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 8869a8e2e..968513df6 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -518,6 +518,8 @@ main class * [.getFilesToCommit(businessUnit, selectedType, keyArr)](#Mcdev.getFilesToCommit) ⇒ Promise.<Array.<string>> * [.execute(businessUnit, [selectedType], [keys])](#Mcdev.execute) ⇒ Promise.<boolean> * [.pause(businessUnit, [selectedType], [keys])](#Mcdev.pause) ⇒ Promise.<boolean> + * [.fixKeys(businessUnit, type, [keys])](#Mcdev.fixKeys) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> + * [._fixKeysBU(cred, bu, type, [keyArr])](#Mcdev._fixKeysBU) ⇒ Promise.<boolean> @@ -798,6 +800,35 @@ pause an item | [selectedType] | TYPE.SupportedMetadataTypes | limit to given metadata types | | [keys] | Array.<string> | customerkey of the metadata | + + +### Mcdev.fixKeys(businessUnit, type, [keys]) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> +Updates the key to match the name field + +**Kind**: static method of [Mcdev](#Mcdev) +**Returns**: Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> - deployed metadata per BU (first key: bu name, second key: metadata type) + +| Param | Type | Description | +| --- | --- | --- | +| businessUnit | string | name of BU | +| type | TYPE.SupportedMetadataTypes | limit execution to given metadata type | +| [keys] | Array.<string> | customerkey of the metadata | + + + +### Mcdev.\_fixKeysBU(cred, bu, type, [keyArr]) ⇒ Promise.<boolean> +helper for [fixKeys](#Mcdev.fixKeys) + +**Kind**: static method of [Mcdev](#Mcdev) +**Returns**: Promise.<boolean> - true if all successfully, false if not + +| Param | Type | Description | +| --- | --- | --- | +| cred | string | name of Credential | +| bu | string | name of BU | +| type | TYPE.SupportedMetadataTypes | limit execution to given metadata type | +| [keyArr] | Array.<string> | customerkey of the metadata | + ## Asset ⇐ [MetadataType](#MetadataType) @@ -3254,6 +3285,7 @@ Provides default functionality that can be overwritten by child metadata type cl * [.deleteByKeyREST(url, key, [handleOutside])](#MetadataType.deleteByKeyREST) ⇒ boolean * [.readBUMetadataForType(readDir, [listBadKeys], [buMetadata])](#MetadataType.readBUMetadataForType) ⇒ object * [.getFilesToCommit(keyArr)](#MetadataType.getFilesToCommit) ⇒ Promise.<Array.<string>> + * [.getKeysForFixing(metadataMap)](#MetadataType.getKeysForFixing) ⇒ Array.<string> @@ -4059,6 +4091,16 @@ additionally, the documentation for dataExtension and automation should be retur | --- | --- | --- | | keyArr | Array.<string> | customerkey of the metadata | + + +### MetadataType.getKeysForFixing(metadataMap) ⇒ Array.<string> +**Kind**: static method of [MetadataType](#MetadataType) +**Returns**: Array.<string> - list of keys + +| Param | Type | Description | +| --- | --- | --- | +| metadataMap | TYPE.MetadataTypeMap | metadata mapped by their keyField | + ## MobileCode ⇐ [MetadataType](#MetadataType) diff --git a/lib/index.js b/lib/index.js index fa23181a9..ff148613d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -980,9 +980,9 @@ class Mcdev { /** * Updates the key to match the name field * - * @param {string} bu name of BU - * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit execution to given metadata type - * @param {string[]} keyArr customerkey of the metadata + * @param {string} businessUnit name of BU + * @param {TYPE.SupportedMetadataTypes} type limit execution to given metadata type + * @param {string[]} [keys] customerkey of the metadata * @returns {Promise.>} deployed metadata per BU (first key: bu name, second key: metadata type) */ static async fixKeys(businessUnit, type, keys) { @@ -995,17 +995,10 @@ class Mcdev { // return null here to avoid seeing 2 error messages for the same issue return null; } - if (type) { - for (const selectedType of Array.isArray(type) ? type : Object.keys(type)) { - if (!Util._isValidType(selectedType)) { - return; - } - } - } - if (Array.isArray(type) && type.length > 1) { - Util.logger.error('fixKeys expects a single type to be deployed'); - return null; + if (!type || !Util._isValidType(type)) { + return; } + if (MetadataTypeDefinitions[type].keyField === MetadataTypeDefinitions[type].idField) { Util.logger.error(`Key cannot be updated for this type`); return null; @@ -1044,19 +1037,18 @@ class Mcdev { } /** - * helper for {@link fixKeys} + * helper for {@link Mcdev.fixKeys} * * @param {string} cred name of Credential * @param {string} bu name of BU - * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit execution to given metadata type - * @param {string[]} keyArr customerkey of the metadata + * @param {TYPE.SupportedMetadataTypes} type limit execution to given metadata type + * @param {string[]} [keyArr] customerkey of the metadata * @returns {Promise.} true if all successfully, false if not */ static async _fixKeysBU(cred, bu, type, keyArr) { const properties = await config.getProperties(); - let numItemsToUpdate = 0; + let numItemsToUpdate; let deployed; - const toDeploy = []; const buObject = await Cli.getCredentialObject( properties, cred === null ? null : cred + '/' + bu, @@ -1078,39 +1070,32 @@ class Mcdev { } Util.logger.info(`First retrieve ${type}`); const retriever = new Retriever(properties, buObject); - const retrieved = await retriever.retrieve(type, keyArr, null, false); - Object.keys(retrieved).forEach((key) => { - for (const item of Object.values(retrieved[key][0])) { - if (item.name.length > MetadataTypeDefinitions[type].maxKeyLength) { - Util.logger.warn( - `Name of the item ${item.key} is too long for a key. Consider renaming your item. Key will be equal first ${MetadataTypeDefinitions[type].maxKeyLength} characters of the name` - ); - item.name = item.name.slice(0, MetadataTypeDefinitions[type].maxKeyLength); - } - numItemsToUpdate = Object.values(retrieved[key][0]).length; - if (item != null) { - if (item.name != item.key && !MetadataTypeDefinitions[type].keyIsFixed) { - toDeploy.push(item.key); - Util.logger.info(`Updating key for query ${item.key}`); - } else { - numItemsToUpdate--; - Util.logger.info( - ` ☇ skipping query ${item.key} - key does not need to be updated` - ); - } - } else { - Util.logger.error(`${item.key} not found on server.`); - } + const retrieved = await retriever.retrieve([type], keyArr, null, false); + + const typeArr = Object.values(retrieved)[0]; + // merge results if multiple keys were provided + if (keyArr?.length > 1) { + const base = typeArr[0]; + for (let i = 1; i < typeArr.length; i++) { + // merge all items into the first array + Object.assign(base, typeArr[i]); } - }); - Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; - properties.directories.deploy = properties.directories.retrieve; + // kick out all but first entry + typeArr.length = 1; + } + const keysForDeploy = MetadataTypeInfo[type].getKeysForFixing(typeArr[0], type); + numItemsToUpdate = keysForDeploy.length; if (numItemsToUpdate < 1) { Util.logger.info(`No items to update. Exiting`); return true; } - deployed = await Deployer._deployBU(cred, bu, properties, type, toDeploy, true); - await this.#retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); + Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; + properties.directories.deploy = properties.directories.retrieve; + deployed = await Deployer._deployBU(cred, bu, properties, [type], keysForDeploy, true); + + // TODO find types that are dependent on this type by iterating over THEIR dependencies + // await this.#retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); + // TODO update other types that are dependent on this type. } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index d18f75848..d882ef2d1 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -2007,6 +2007,46 @@ class MetadataType { const fileList = keyArr.map((key) => File.normalizePath([path, key + typeExtension])); return fileList; } + + /** + * + * @param {TYPE.MetadataTypeMap} metadataMap metadata mapped by their keyField + * @returns {string[]} list of keys + */ + static getKeysForFixing(metadataMap) { + const keysForDeploy = []; + + for (const item of Object.values(metadataMap)) { + if (item[this.definition.nameField].length > this.definition.maxKeyLength) { + Util.logger.warn( + `Name of the item ${ + item[this.definition.keyField] + } is too long for a key. Consider renaming your item. Key will be equal first ${ + this.definition.maxKeyLength + } characters of the name` + ); + item[this.definition.nameField] = item[this.definition.nameField].slice( + 0, + this.definition.maxKeyLength + ); + } + + if ( + item[this.definition.nameField] != item[this.definition.keyField] && + !this.definition.keyIsFixed + ) { + keysForDeploy.push(item[this.definition.keyField]); + Util.logger.info(`Updating key for query ${item[this.definition.keyField]}`); + } else { + Util.logger.info( + ` ☇ skipping query ${ + item[this.definition.keyField] + } - key does not need to be updated` + ); + } + } + return keysForDeploy; + } } MetadataType.definition = { diff --git a/test/type.query.test.js b/test/type.query.test.js index 5ef17726c..c38fe7d6f 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -158,7 +158,6 @@ describe('type: query', () => { ); // get results from cache const result = cache.getCache(); - console.log(result.query); assert.equal( result.query ? Object.keys(result.query).length : 0, 4, @@ -229,7 +228,7 @@ describe('type: query', () => { }); it('Should not fixKeys and deploy', async () => { // WHEN - await handler.fixKeys('testInstance/testBU', ['query'], ['testExisting_query']); + await handler.fixKeys('testInstance/testBU', 'query', ['testExisting_query']); // THEN assert.equal(process.exitCode, false, 'fixKeys should not have thrown an error'); // get results from cache @@ -239,24 +238,6 @@ describe('type: query', () => { 1, 'one query expected' ); - // confirm created item - // assert.deepEqual( - // await testUtils.getActualJson('testNew_query', 'query'), - // await testUtils.getExpectedJson('9999999', 'query', 'post'), - // 'returned metadata was not equal expected for insert query' - // ); - // expect(file(testUtils.getActualFile('testNew_query', 'query', 'sql'))).to.equal( - // file(testUtils.getExpectedFile('9999999', 'query', 'post', 'sql')) - // ); - // // confirm updated item - // assert.deepEqual( - // await testUtils.getActualJson('testExisting_query', 'query'), - // await testUtils.getExpectedJson('9999999', 'query', 'patch'), - // 'returned metadata was not equal expected for insert query' - // ); - // expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.equal( - // file(testUtils.getExpectedFile('9999999', 'query', 'patch', 'sql')) - // ); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), From 56de12805e4262b826775b756b09d330a7970905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Wed, 12 Jul 2023 15:49:42 +0200 Subject: [PATCH 102/208] #38: fixing first part of test for fixKeys --- lib/cli.js | 2 +- .../testExisting_query_fixKeys.query-meta.json | 2 +- .../get-response.json | 2 +- .../automation/v1/queries/get-response.json | 2 +- test/type.query.test.js | 17 ++++++++--------- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index d27d1b0ab..d5b36ccb7 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -490,7 +490,7 @@ yargs }, handler: (argv) => { Mcdev.setOptions(argv); - Mcdev.fixKeys(argv.BU, csvToArray(argv.TYPE), csvToArray(argv.KEY)); + Mcdev.fixKeys(argv.BU, argv.TYPE, csvToArray(argv.KEY)); }, }) .command({ diff --git a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json index ef7ff4fbe..5455fe2ca 100644 --- a/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json +++ b/test/mockRoot/deploy/testInstance/testBU/query/testExisting_query_fixKeys.query-meta.json @@ -1,5 +1,5 @@ { - "name": "testExisting_query_fixedKey", + "name": "testExisting_query_fixedKeys", "key": "testExisting_query_fixKeys", "description": "updated on deploy", "targetKey": "testExisting_dataExtension", diff --git a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json index 75b81ceeb..5f481344a 100644 --- a/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json +++ b/test/resources/9999999/automation/v1/queries/549f0568-607c-4940-afef-437965094dat_fixKeys/get-response.json @@ -1,6 +1,6 @@ { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat_fixKeys", - "name": "testExisting_query_fixedKey", + "name": "testExisting_query_fixedKeys", "key": "testExisting_query_fixKeys", "description": "bla bla", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", diff --git a/test/resources/9999999/automation/v1/queries/get-response.json b/test/resources/9999999/automation/v1/queries/get-response.json index 416c68479..834827ed3 100644 --- a/test/resources/9999999/automation/v1/queries/get-response.json +++ b/test/resources/9999999/automation/v1/queries/get-response.json @@ -39,7 +39,7 @@ }, { "queryDefinitionId": "549f0568-607c-4940-afef-437965094dat_fixKeys", - "name": "testExisting_query_fixedKey", + "name": "testExisting_query_fixedKeys", "key": "testExisting_query_fixKeys", "description": "bla bla", "queryText": "SELECT\n SubscriberKey as testField\nFROM\n _Subscribers\nWHERE\n country IN ('test')\n", diff --git a/test/type.query.test.js b/test/type.query.test.js index c38fe7d6f..29bf05dd2 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -248,11 +248,10 @@ describe('type: query', () => { }); it('Should fixKeys and deploy', async () => { // WHEN - const resultFixKeys = await handler.fixKeys( - 'testInstance/testBU', - ['query'], - ['testExisting_query_fixKeys'] - ); + const resultFixKeys = await handler.fixKeys('testInstance/testBU', 'query', [ + 'testExisting_query_fixKeys', + 'testExisting_query', + ]); // THEN assert.equal(process.exitCode, false, 'fixKeys should not have thrown an error'); assert.equal(resultFixKeys, true, 'fixKeys should not have thrown an error'); @@ -265,13 +264,13 @@ describe('type: query', () => { // ); // confirm updated item assert.deepEqual( - await testUtils.getActualJson('testExisting_query_fixedKey', 'query'), - await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKey'), + await testUtils.getActualJson('testExisting_query_fixedKeys', 'query'), + await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKeys'), 'returned metadata was not equal expected for insert query' ); expect( - file(testUtils.getActualFile('testExisting_query_fixedKey', 'query', 'sql')) - ).to.equal(file(testUtils.getExpectedFile('9999999', 'query', 'patch_fixKey', 'sql'))); + file(testUtils.getActualFile('testExisting_query_fixedKeys', 'query', 'sql')) + ).to.equal(file(testUtils.getExpectedFile('9999999', 'query', 'patch_fixKeys', 'sql'))); // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), From 8de76eaee615f7487c769b8d68ff5342896fb5c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 13 Jul 2023 15:16:19 +0200 Subject: [PATCH 103/208] #711: ensure retrieve() always returns proper values --- docs/dist/documentation.md | 26 -------------------------- lib/index.js | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index bb35e5913..c8cc127b9 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -1220,7 +1220,6 @@ AttributeGroup MetadataType * [.retrieve(retrieveDir, [_], [__], [key])](#AttributeGroup.retrieve) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveForCache()](#AttributeGroup.retrieveForCache) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.postRetrieveTasks(metadata)](#AttributeGroup.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem - * [.preDeployTasks(metadata)](#AttributeGroup.preDeployTasks) ⇒ TYPE.MetadataTypeItem @@ -1256,18 +1255,6 @@ manages post retrieve steps | --- | --- | --- | | metadata | TYPE.MetadataTypeItem | a single metadata | - - -### AttributeGroup.preDeployTasks(metadata) ⇒ TYPE.MetadataTypeItem -prepares for deployment - -**Kind**: static method of [AttributeGroup](#AttributeGroup) -**Returns**: TYPE.MetadataTypeItem - Promise - -| Param | Type | Description | -| --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single item | - ## AttributeSet ⇐ [MetadataType](#MetadataType) @@ -1282,7 +1269,6 @@ AttributeSet MetadataType * [.parseResponseBody(body, [singleRetrieve])](#AttributeSet.parseResponseBody) ⇒ TYPE.MetadataTypeMap * [.postRetrieveTasks(metadata)](#AttributeSet.postRetrieveTasks) ⇒ TYPE.MetadataTypeItem * [._getSystemValueDefinitions()](#AttributeSet._getSystemValueDefinitions) ⇒ Array.<object> - * [.preDeployTasks(metadata)](#AttributeSet.preDeployTasks) ⇒ TYPE.MetadataTypeItem @@ -1338,18 +1324,6 @@ helper for [postRetrieveTasks](#AttributeSet.postRetrieveTasks) **Kind**: static method of [AttributeSet](#AttributeSet) **Returns**: Array.<object> - all system value definitions - - -### AttributeSet.preDeployTasks(metadata) ⇒ TYPE.MetadataTypeItem -prepares for deployment - -**Kind**: static method of [AttributeSet](#AttributeSet) -**Returns**: TYPE.MetadataTypeItem - Promise - -| Param | Type | Description | -| --- | --- | --- | -| metadata | TYPE.MetadataTypeItem | a single item | - ## Automation ⇐ [MetadataType](#MetadataType) diff --git a/lib/index.js b/lib/index.js index 323f087f4..4c836dafc 100644 --- a/lib/index.js +++ b/lib/index.js @@ -173,7 +173,7 @@ class Mcdev { } } } - + const resultsObj = {}; if (businessUnit === '*') { Util.logger.info(':: Retrieving all BUs for all credentials'); let counter_credTotal = 0; @@ -181,7 +181,12 @@ class Mcdev { Util.logger.info(`:: Retrieving all BUs for ${cred}`); let counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { - await this.#retrieveBU(cred, bu, selectedTypesArr, keys); + resultsObj[`${cred}/${bu}`] = await this.#retrieveBU( + cred, + bu, + selectedTypesArr, + keys + ); counter_credBu++; Util.startLogger(true); } @@ -215,7 +220,12 @@ class Mcdev { Util.logger.info(`:: Retrieving all BUs for ${cred}`); let counter_credBu = 0; for (const bu in properties.credentials[cred].businessUnits) { - await this.#retrieveBU(cred, bu, selectedTypesArr, keys); + resultsObj[`${cred}/${bu}`] = await this.#retrieveBU( + cred, + bu, + selectedTypesArr, + keys + ); counter_credBu++; Util.startLogger(true); } @@ -231,10 +241,27 @@ class Mcdev { ); if (changelogOnly) { return retrieveChangelog; + } else { + resultsObj[`${cred}/${bu}`] = retrieveChangelog; } Util.logger.info(`:: Done\n`); } } + + // merge all results into one object + for (const credBu in resultsObj) { + for (const type in resultsObj[credBu]) { + const base = resultsObj[credBu][type][0]; + + for (let i = 1; i < resultsObj[credBu][type].length; i++) { + // merge all items into the first array + Object.assign(base, resultsObj[credBu][type][i]); + } + resultsObj[credBu][type] = resultsObj[credBu][type][0]; + } + } + + return resultsObj; } /** * helper for {@link Mcdev.retrieve} @@ -340,9 +367,7 @@ class Mcdev { null, changelogOnly ); - if (changelogOnly) { - return retrieveChangelog; - } + return retrieveChangelog; } catch (ex) { Util.logger.errorStack(ex, 'mcdev.retrieve failed'); } From 650731a2dbe4ef02691201cfe663dd7fecbd55f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 13 Jul 2023 15:18:59 +0200 Subject: [PATCH 104/208] #711: remove preDeployTasks as upsert is not supported by API --- lib/metadataTypes/AttributeGroup.js | 49 ------- lib/metadataTypes/AttributeSet.js | 192 ---------------------------- 2 files changed, 241 deletions(-) diff --git a/lib/metadataTypes/AttributeGroup.js b/lib/metadataTypes/AttributeGroup.js index cf4804bcd..086ffd845 100644 --- a/lib/metadataTypes/AttributeGroup.js +++ b/lib/metadataTypes/AttributeGroup.js @@ -108,55 +108,6 @@ class AttributeGroup extends MetadataType { * @param {TYPE.MetadataTypeItem} metadata a single item * @returns {TYPE.MetadataTypeItem} Promise */ - static async preDeployTasks(metadata) { - // Member ID - set to ID of deployment target automatically - metadata.mID = this.buObject.mid; - - // attributeSet - metadata.attributeSetIdentifiers = metadata.attributeSetIdentifiers.map((key) => { - const as = cache.getByKey('attributeSet', key); - return { - definitionKey: key, - definitionID: as.definitionID, - definitionName: as.definitionName, - connectingID: as.connectingID, - }; - }); - - // requiredRelationships - // TODO: implement - - // description is not returned by API when empty. Remove it before deployment if empty - if (metadata.description === '') { - delete metadata.description; - } - - // filter system defined attribute groups - if (metadata.isSystemDefined) { - throw new Error( - ` ☇ skipping ${this.definition.type} ${metadata[this.definition.keyField]} / ${ - metadata[this.definition.nameField] - }: Cannot deploy system defined attribute groups (isSystemDefined: true)` - ); - } - - // connectingID.identifierType seems to be always set to 'FullyQualifiedName' - we remove it during retrieve and auto-set it here again - if (!metadata.connectingID?.identifierType) { - metadata.connectingID = { - identifierType: 'FullyQualifiedName', - }; - } - - // fullyQualifiedName is equal to definitionName.value and needs to be auto-populated for deploy - metadata.fullyQualifiedName = metadata.definitionName?.value; - - // containsSchemaAttributes is only true for system generated attribute groups and otherwise it's false which is why we remove it during retrieve and auto-set it here again - if (!metadata.containsSchemaAttributes) { - metadata.containsSchemaAttributes = false; - } - - return metadata; - } } // Assign definition to static attributes diff --git a/lib/metadataTypes/AttributeSet.js b/lib/metadataTypes/AttributeSet.js index a0f22faa3..1f9d82984 100644 --- a/lib/metadataTypes/AttributeSet.js +++ b/lib/metadataTypes/AttributeSet.js @@ -252,198 +252,6 @@ class AttributeSet extends MetadataType { } return this.systemValueDefinitions; } - /** - * prepares for deployment - * - * @param {TYPE.MetadataTypeItem} metadata a single item - * @returns {TYPE.MetadataTypeItem} Promise - */ - static async preDeployTasks(metadata) { - // folder - if (metadata.storageLogicalType) { - // attributeSet created for Group Connect do not have a folder - super.setFolderId(metadata); - } - - // source - switch (metadata.storageLogicalType) { - case 'ExactTargetSchema': // synced / shared DEs - case 'DataExtension': { - // local DEs - try { - const de = cache.getByKey( - 'dataExtension', - metadata.r__dataExtension_CustomerKey - ); - - metadata.storageReferenceID = { - value: de.ObjectID, - }; - metadata.storageName = de.Name; - if (metadata.storageLogicalType === 'ExactTargetSchema') { - metadata.storageObjectInformation = { - externalObjectAPIName: de.Name.split('_Salesforce')[0], - }; - } - - // TODO: check if fields in metadata.sendAttributeStorageName exist in data extension --> error - // TODO: check if fields in data extension exist in metadata.sendAttributeStorageName --> warn - } catch (ex) { - Util.logger.warn( - ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ - ex.message - }` - ); - } - break; - } - case 'MobileAttributes': { - // TODO: implement - // "storageName": "_MobileAddress", - - break; - } - case 'EnterpriseAttributes': { - // TODO: implement - // "storageName": "_EnterpriseAttribute", - - break; - } - case 'PushAttributes': { - // TODO: implement - // "storageName": "_PushAddress", - - break; - } - } - - // attributeGroups - // relationships to attributeGroups & AttributeSet - if (Array.isArray(metadata.relationships)) { - for (const relationship of metadata.relationships) { - try { - relationship.leftItem.identifier = cache.searchForField( - 'attributeGroup', - relationship.leftItem.r__attributeGroup_definitionKey, - 'definitionKey', - 'definitionID' - ); - delete relationship.leftItem.r__attributeGroup_definitionKey; - } catch (ex) { - Util.logger.warn( - ` - ${this.definition.type} ${metadata[this.definition.keyField]}: ${ - ex.message - }` - ); - } - } - for (const relationship of metadata.relationships) { - for (const type of ['left', 'right']) { - relationship[type + 'Item'].connectingID = relationship[type + 'Item'] - .connectingID || { - identifierType: 'FullyQualifiedName', - }; - switch (relationship[type + 'Item'].relationshipType) { - case 'AttributeGroup': { - relationship[type + 'Item'].identifier = cache.searchForField( - 'attributeGroup', - relationship[type + 'Item']?.r__attributeGroup_definitionKey, - 'definitionKey', - 'definitionID' - ); - - // get relationship fieldnames - // resolve field values - for (const attr of relationship.relationshipAttributes) { - const relationshipObj = cache.getByKey( - 'attributeSet', - attr['c__' + type + 'FullyQualifiedName'].split('.')[0] - ); - attr[type + 'AttributeID'] = relationshipObj.valueDefinitions.find( - (item) => - item.fullyQualifiedName === - attr['c__' + type + 'FullyQualifiedName'] - ).valueDefinitionID; - attr[type + 'ConnectingID'] = attr[type + 'ConnectingID'] || { - identifierType: 'FullyQualifiedName', - }; - - delete attr['c__' + type + 'FullyQualifiedName']; - } - - // cleanup - delete relationship[type + 'Item']?.r__attributeGroup_definitionKey; - break; - } - case 'AttributeSet': { - try { - relationship[type + 'Item'].identifier = cache.searchForField( - 'attributeSet', - relationship[type + 'Item']?.r__attributeSet_definitionKey, - 'definitionID', - 'definitionKey' - ); - - // get relationship fieldnames - // check if its a self-reference to metadata.valueDefinitions or if it's a reference to another attributeSet - const relationshipObj = - relationship[type + 'Item'].r__attributeSet_definitionKey === - metadata.definitionKey - ? metadata - : cache.getByKey( - 'attributeSet', - relationship[type + 'Item'] - .r__attributeSet_definitionKey - ); - // resolve field values - for (const attr of relationship.relationshipAttributes) { - attr[type + 'AttributeID'] = - relationshipObj.valueDefinitions.find( - (item) => - item.fullyQualifiedName === - attr['c__' + type + 'FullyQualifiedName'] - ).valueDefinitionID; - attr[type + 'ConnectingID'] = attr[type + 'ConnectingID'] || { - identifierType: 'FullyQualifiedName', - }; - - delete attr['c__' + type + 'FullyQualifiedName']; - } - - // cleanup - delete relationship[type + 'Item']?.r__attributeSet_definitionKey; - } catch (ex) { - Util.logger.warn( - ` - ${this.definition.type} ${ - metadata[this.definition.keyField] - }: ${ex.message}` - ); - } - break; - } - } - } - } - } - - // Member ID - set to ID of deployment target automatically - metadata.customObjectOwnerMID = this.buObject.mid; - - // connectingID.identifierType seems to be always set to 'FullyQualifiedName' - we remove it during retrieve and auto-set it here again - if (!metadata.connectingID?.identifierType) { - metadata.connectingID = { - identifierType: 'FullyQualifiedName', - }; - } - - // fullyQualifiedName and definitionName.value are equal to 'name' and need to be auto-populated for deploy - metadata.fullyQualifiedName = metadata.name; - metadata.definitionName = { - value: metadata.name, - }; - - return metadata; - } } // Assign definition to static attributes From dffb5f348a6985603df8dfd752a365f0ffaa9821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 13 Jul 2023 15:20:32 +0200 Subject: [PATCH 105/208] #711: update field definitions --- .../definitions/AttributeSet.definition.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/metadataTypes/definitions/AttributeSet.definition.js b/lib/metadataTypes/definitions/AttributeSet.definition.js index 63a2b8e22..47e77cde4 100644 --- a/lib/metadataTypes/definitions/AttributeSet.definition.js +++ b/lib/metadataTypes/definitions/AttributeSet.definition.js @@ -445,6 +445,18 @@ module.exports = { retrieving: true, template: null, }, + 'relationships[].relationshipAttributes[].c__leftFullyQualifiedName': { + isCreateable: null, + isUpdateable: null, + retrieving: true, + template: null, + }, + 'relationships[].relationshipAttributes[].c__rightFullyQualifiedName': { + isCreateable: null, + isUpdateable: null, + retrieving: true, + template: null, + }, 'relationships[].relationshipID': { isCreateable: null, isUpdateable: null, @@ -841,5 +853,11 @@ module.exports = { retrieving: true, template: null, }, + r__folder_Path: { + isCreateable: null, + isUpdateable: null, + retrieving: true, + template: null, + }, }, }; From 51dfbd0def27765b22139777e7dc717300f3756c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 13 Jul 2023 15:24:08 +0200 Subject: [PATCH 106/208] #711: test for type attributeSet --- .../attributeSet/retrieve-expected.json | 167 + .../9999999/dataFolder/retrieve-response.xml | 23 + .../schema/attributeGroups/get-response.json | 585 + .../schema/setDefinitions/get-response.json | 19807 ++++++++++++++++ test/type.attributeSet.test.js | 54 + 5 files changed, 20636 insertions(+) create mode 100644 test/resources/9999999/attributeSet/retrieve-expected.json create mode 100644 test/resources/9999999/hub/v1/contacts/schema/attributeGroups/get-response.json create mode 100644 test/resources/9999999/hub/v1/contacts/schema/setDefinitions/get-response.json create mode 100644 test/type.attributeSet.test.js diff --git a/test/resources/9999999/attributeSet/retrieve-expected.json b/test/resources/9999999/attributeSet/retrieve-expected.json new file mode 100644 index 000000000..fd1214b50 --- /dev/null +++ b/test/resources/9999999/attributeSet/retrieve-expected.json @@ -0,0 +1,167 @@ +{ + "applicationID": "ce703ed3-e01f-4f5f-900d-76a95b363e29", + "applicationKey": "com.exacttarget.contacts", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "createDate": "2017-01-24T06:33:00", + "createdBy": -1000, + "definitionKey": "Contact", + "isCustomObjectBacked": false, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isSystemDefined": true, + "localizedDescription": {}, + "name": "Contact", + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 1, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isGroupToSetRelationship": true, + "isHidden": false, + "isSystemDefined": false, + "leftItem": { + "cardinality": "One", + "r__attributeGroup_definitionKey": "ETSystem", + "relationshipType": "AttributeGroup" + }, + "leftRelationshipIDs": [ + { + "type": "int16", + "value": "2" + } + ], + "leftRelationshipReferenceType": "CustomerData", + "relationshipAttributes": [ + { + "c__leftFullyQualifiedName": "Contact.Contact ID", + "c__rightFullyQualifiedName": "Contact.Contact ID" + } + ], + "relationshipID": "9893dc39-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "One", + "r__attributeSet_definitionKey": "Contact", + "relationshipType": "AttributeSet" + } + } + ], + "setDefinitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "Contact", + "storageObjectIDs": ["2ba72136-9f31-4a79-ab62-4ba5d19cd759"], + "valueDefinitions": [ + { + "baseType": "Numeric", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "customerDataID": 2, + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Number", + "definitionID": "9293dc39-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ContactID", + "definitionName": { + "value": "Contact ID" + }, + "description": "", + "fullyQualifiedName": "Contact.Contact ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "localizedDescription": { + "value": "" + }, + "name": "Contact ID", + "parentType": "Set", + "setDefinitionName": { + "value": "Contact" + }, + "storageName": "SubscriberID", + "valueDefinitionID": "9293dc39-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ContactID" + }, + { + "baseType": "Text", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "customerDataID": 3, + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Text", + "definitionID": "9393dc39-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ContactKey", + "definitionName": { + "value": "Contact Key" + }, + "description": "", + "fullyQualifiedName": "Contact.Contact Key", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": -1, + "localizedDescription": { + "value": "" + }, + "name": "Contact Key", + "parentType": "Set", + "setDefinitionName": { + "value": "Contact" + }, + "storageName": "SubscriberKey", + "valueDefinitionID": "9393dc39-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ContactKey" + }, + { + "baseType": "Numeric", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "customerDataID": 1, + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Number", + "definitionID": "9193dc39-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "BusinessUnitID", + "definitionName": { + "value": "Business Unit ID" + }, + "description": "", + "fullyQualifiedName": "Contact.Business Unit ID", + "isHidden": true, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "localizedDescription": { + "value": "" + }, + "name": "Business Unit ID", + "parentType": "Set", + "setDefinitionName": { + "value": "Contact" + }, + "storageName": "ClientID", + "valueDefinitionID": "9193dc39-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "BusinessUnitID" + } + ] +} diff --git a/test/resources/9999999/dataFolder/retrieve-response.xml b/test/resources/9999999/dataFolder/retrieve-response.xml index 29b1d38a8..f203f327c 100644 --- a/test/resources/9999999/dataFolder/retrieve-response.xml +++ b/test/resources/9999999/dataFolder/retrieve-response.xml @@ -197,6 +197,29 @@ true true + + + 9999999 + + + 2017-02-08T10:19:37.123 + 2017-02-08T10:19:37.123 + 386 + + + + + 2 + + dataextension_default + + Einstein + + dataextension + true + true + true + diff --git a/test/resources/9999999/hub/v1/contacts/schema/attributeGroups/get-response.json b/test/resources/9999999/hub/v1/contacts/schema/attributeGroups/get-response.json new file mode 100644 index 000000000..078668f80 --- /dev/null +++ b/test/resources/9999999/hub/v1/contacts/schema/attributeGroups/get-response.json @@ -0,0 +1,585 @@ +{ + "attributeGroupDefinitions": [ + { + "mID": 1111111, + "objectState": "Created", + "attributeSetIdentifiers": [ + { + "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Email Addresses" + }, + "definitionKey": "EmailAddresses", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Contact" + }, + "definitionKey": "Contact", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + } + ], + "isOwner": true, + "isPrimary": false, + "isSystemDefined": true, + "isHidden": false, + "canAddProperties": false, + "canAddRelationships": false, + "containsSchemaAttributes": true, + "canRemove": false, + "canChangeProperties": false, + "displayOrder": 0, + "requiredRelationships": [ + "0e51de3f-31e2-e611-80cc-1402ec7222b4", + "1451de3f-31e2-e611-80cc-1402ec7222b4", + "9893dc39-31e2-e611-80cc-1402ec7222b4" + ], + "applicationID": "ce703ed3-e01f-4f5f-900d-76a95b363e29", + "canModify": false, + "applicationKey": "com.exacttarget.contacts", + "attributeGroupIconKey": "People", + "fullyQualifiedName": "System Data", + "attributeGroupType": "Standard", + "localizedDescription": {}, + "attributeCount": 7, + "definitionID": "8f93dc39-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "System Data" + }, + "definitionKey": "ETSystem", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "mID": 1111111, + "objectState": "Created", + "attributeSetIdentifiers": [ + { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionName": { + "value": "Chat Message Demographics" + }, + "definitionKey": "ChatMessageDemographics", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "definitionKey": "ChatMessageSubscriptions", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + } + ], + "isOwner": true, + "isPrimary": false, + "isSystemDefined": true, + "isHidden": false, + "canAddProperties": true, + "canAddRelationships": true, + "containsSchemaAttributes": false, + "canRemove": false, + "canChangeProperties": true, + "displayOrder": 1, + "requiredRelationships": [ + "9a42dcad-ae72-4cde-9937-193e17485ad6", + "04ea847d-696d-eb11-b81e-48df37d1df5a" + ], + "canModify": true, + "fullyQualifiedName": "Chat Message Data", + "attributeGroupType": "Standard", + "localizedDescription": {}, + "attributeCount": 37, + "definitionID": "cae9847d-696d-eb11-b81e-48df37d1df5a", + "definitionName": { + "value": "Chat Message Data" + }, + "definitionKey": "ETChatMessage", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "mID": 1111111, + "objectState": "Created", + "attributeSetIdentifiers": [ + { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Email Demographics" + }, + "definitionKey": "EmailDemographics", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + } + ], + "isOwner": true, + "isPrimary": false, + "isSystemDefined": true, + "isHidden": false, + "canAddProperties": false, + "canAddRelationships": true, + "containsSchemaAttributes": false, + "canRemove": false, + "canChangeProperties": false, + "displayOrder": 2, + "requiredRelationships": ["b751de3f-31e2-e611-80cc-1402ec7222b4"], + "applicationID": "b2ca1f50-3cc4-4fd7-a3a3-88bf09fb59fa", + "canModify": false, + "applicationKey": "com.exacttarget.email", + "attributeGroupIconKey": "Email", + "fullyQualifiedName": "Email Data", + "attributeGroupType": "Standard", + "localizedDescription": {}, + "attributeCount": 16, + "definitionID": "b451de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Email Data" + }, + "definitionKey": "ETEmail", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "mID": 1111111, + "objectState": "Created", + "attributeSetIdentifiers": [ + { + "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionName": { + "value": "GroupConnect LINE Addresses" + }, + "definitionKey": "GroupConnectLineAddress", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "GroupConnect LINE Demographics" + }, + "definitionKey": "GroupConnectLineDemographics", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "definitionKey": "GroupConnectLineSubscriptions", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + } + ], + "isOwner": true, + "isPrimary": false, + "isSystemDefined": true, + "isHidden": false, + "canAddProperties": false, + "canAddRelationships": true, + "containsSchemaAttributes": false, + "canRemove": false, + "canChangeProperties": false, + "displayOrder": 3, + "requiredRelationships": [ + "8686d247-3045-ea11-a2e0-1402ec94ec41", + "a686d247-3045-ea11-a2e0-1402ec94ec41", + "9386d247-3045-ea11-a2e0-1402ec94ec41" + ], + "applicationID": "4e9519db-ad21-483a-a3fc-8ab4557eded1", + "canModify": false, + "applicationKey": "com.exacttarget.GroupConnect", + "attributeGroupIconKey": "Mobile", + "fullyQualifiedName": "GroupConnect LINE Data", + "attributeGroupType": "Standard", + "localizedDescription": {}, + "attributeCount": 23, + "definitionID": "ab51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "GroupConnect LINE Data" + }, + "definitionKey": "ETGroupConnectLine", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "mID": 1111111, + "objectState": "Created", + "attributeSetIdentifiers": [ + { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "definitionKey": "MobileDemographics", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "definitionKey": "MobileSubscriptions", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + } + ], + "isOwner": true, + "isPrimary": false, + "isSystemDefined": true, + "isHidden": false, + "canAddProperties": false, + "canAddRelationships": true, + "containsSchemaAttributes": false, + "canRemove": false, + "canChangeProperties": false, + "displayOrder": 4, + "requiredRelationships": [ + "4651de3f-31e2-e611-80cc-1402ec7222b4", + "4352de3f-31e2-e611-80cc-1402ec7222b4" + ], + "applicationID": "e25893f9-08f3-480f-8def-7f8ab0583611", + "canModify": false, + "applicationKey": "com.exacttarget.mobileconnect", + "attributeGroupIconKey": "Mobile", + "fullyQualifiedName": "MobileConnect Data", + "attributeGroupType": "Standard", + "localizedDescription": {}, + "attributeCount": 37, + "definitionID": "4351de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "MobileConnect Data" + }, + "definitionKey": "ETMobileConnect", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "mID": 1111111, + "objectState": "Created", + "attributeSetIdentifiers": [ + { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "MobilePush Demographics" + }, + "definitionKey": "PushDemographics", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "MobilePush Subscriptions" + }, + "definitionKey": "PushSubscriptions", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "MobilePush Tags" + }, + "definitionKey": "PushTags", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + } + ], + "isOwner": true, + "isPrimary": false, + "isSystemDefined": true, + "isHidden": false, + "canAddProperties": false, + "canAddRelationships": true, + "containsSchemaAttributes": false, + "canRemove": false, + "canChangeProperties": false, + "displayOrder": 5, + "requiredRelationships": [ + "9651de3f-31e2-e611-80cc-1402ec7222b4", + "d052de3f-31e2-e611-80cc-1402ec7222b4", + "bc52de3f-31e2-e611-80cc-1402ec7222b4" + ], + "applicationID": "2051892d-5de2-4ecf-98af-8ca9a40d2c9c", + "canModify": false, + "applicationKey": "com.exacttarget.mobilepush", + "attributeGroupIconKey": "Mobile", + "fullyQualifiedName": "MobilePush Data", + "attributeGroupType": "Standard", + "localizedDescription": {}, + "attributeCount": 65, + "definitionID": "9351de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "MobilePush Data" + }, + "definitionKey": "ETMobilePush", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "mID": 1111111, + "objectState": "Created", + "attributeSetIdentifiers": [ + { + "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "definitionKey": "PredictiveIntelProductSessions", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence Content Views" + }, + "definitionKey": "PredictiveIntelContentViews", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence Content" + }, + "definitionKey": "PredictiveIntelContent", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "definitionKey": "PredictiveIntelContentAttribs", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "definitionKey": "PredictiveIntelAbandonedCartEvents", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "definitionKey": "PredictiveIntelAbandonedCartItems", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "definitionKey": "PredictiveIntelSessionEnds", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "definitionKey": "EinsteinMCPredictiveScores", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Scores" + }, + "definitionKey": "PredictiveIntelScores", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence Product Views" + }, + "definitionKey": "PredictiveIntelProductViews", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence Products" + }, + "definitionKey": "PredictiveIntelProducts", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "definitionKey": "PredictiveIntelProductAttribs", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "definitionKey": "PredictiveIntelProductPurchases", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + }, + { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "definitionKey": "PredictiveIntelProfiles", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + } + ], + "isOwner": true, + "isPrimary": false, + "isSystemDefined": true, + "isHidden": false, + "canAddProperties": true, + "canAddRelationships": false, + "containsSchemaAttributes": false, + "canRemove": false, + "canChangeProperties": true, + "displayOrder": 7, + "requiredRelationships": [ + "1586d645-31e2-e611-80cc-1402ec7222b4", + "2686d645-31e2-e611-80cc-1402ec7222b4", + "3586d645-31e2-e611-80cc-1402ec7222b4", + "4686d645-31e2-e611-80cc-1402ec7222b4", + "5d86d645-31e2-e611-80cc-1402ec7222b4", + "6c86d645-31e2-e611-80cc-1402ec7222b4", + "7887d645-31e2-e611-80cc-1402ec7222b4", + "7d86d645-31e2-e611-80cc-1402ec7222b4", + "c80f6472-c416-ec11-b839-48df37d1dc79", + "a985d645-31e2-e611-80cc-1402ec7222b4", + "ba85d645-31e2-e611-80cc-1402ec7222b4", + "cd85d645-31e2-e611-80cc-1402ec7222b4", + "0086d645-31e2-e611-80cc-1402ec7222b4", + "de85d645-31e2-e611-80cc-1402ec7222b4", + "fd85d645-31e2-e611-80cc-1402ec7222b4", + "9885d645-31e2-e611-80cc-1402ec7222b4" + ], + "applicationID": "aed181bc-d7b7-465e-a3dd-9cdfb13943e2", + "canModify": false, + "applicationKey": "com.sfmc-einstein.Einstein Engagement Scoring", + "attributeGroupIconKey": "PredictiveIntel", + "fullyQualifiedName": "Predictive Intelligence Data", + "attributeGroupType": "Standard", + "description": "Attribute Group for Einstein Engagement Scoring", + "localizedDescription": { + "resourceSetKey": "ContactsMeta.SystemAttributeGroupDescriptions", + "resourceValueKey": "ATTR_GROUP_DESC_ETPredictiveIntel", + "value": "Attribute Group for Einstein Engagement Scoring" + }, + "attributeCount": 112, + "definitionID": "e152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionName": { + "value": "Predictive Intelligence Data" + }, + "definitionKey": "ETPredictiveIntel", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "namespace": "" + } + ], + "responseContext": { + "operationStatus": "OK", + "schemaType": "Contacts", + "populateInternalProperties": false + }, + "requestServiceMessageID": "9dac2279-40db-4e67-a862-d6ecbadf109a", + "responseDateTime": "2023-07-12T09:17:31.8837381-06:00", + "resultMessages": [], + "serviceMessageID": "92930c00-cacf-41e1-ba8d-04ad4d903f65" +} diff --git a/test/resources/9999999/hub/v1/contacts/schema/setDefinitions/get-response.json b/test/resources/9999999/hub/v1/contacts/schema/setDefinitions/get-response.json new file mode 100644 index 000000000..8e5dc97ff --- /dev/null +++ b/test/resources/9999999/hub/v1/contacts/schema/setDefinitions/get-response.json @@ -0,0 +1,19807 @@ +{ + "setDefinition": [ + { + "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductSessions", + "definitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "1386d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence Product Sessions.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductSessions", + "definitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "1386d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductSessions", + "setDefinitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "session_id", + "localizedDescription": { + "value": "session_id" + }, + "definitionID": "1086d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "session_id", + "definitionName": { + "value": "Session ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence Product Sessions.Session ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "1086d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductSessions", + "definitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "session_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "1ca32e3d-4f4e-4771-8d99-057f8bad3733" + }, + "valueDefinitionID": "1086d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "session_id", + "name": "Session ID", + "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductSessions", + "setDefinitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "user_id", + "localizedDescription": { + "value": "user_id" + }, + "definitionID": "1286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "User_ID", + "definitionName": { + "value": "User ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence Product Sessions.User ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "1286d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductSessions", + "definitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "user_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "f2e9ddf5-e18d-43db-ad52-cc754c929811" + }, + "valueDefinitionID": "1286d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "User_ID", + "name": "User ID", + "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductSessions", + "setDefinitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "Batch_ID", + "localizedDescription": { + "value": "Batch_ID" + }, + "definitionID": "0c86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Batch_ID", + "definitionName": { + "value": "Batch ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence Product Sessions.Batch ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "0c86d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductSessions", + "definitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Batch_ID", + "storageFieldReferenceID": { + "type": "guid", + "value": "fed66cad-7da4-469c-b49c-79e8c82ae37f" + }, + "valueDefinitionID": "0c86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Batch_ID", + "name": "Batch ID", + "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductSessions", + "setDefinitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "List_ID", + "localizedDescription": { + "value": "List_ID" + }, + "definitionID": "0f86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "List_ID", + "definitionName": { + "value": "List ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence Product Sessions.List ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "0f86d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductSessions", + "definitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "List_ID", + "storageFieldReferenceID": { + "type": "guid", + "value": "39471713-05c1-43d5-ac0f-9ecb66bae213" + }, + "valueDefinitionID": "0f86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "List_ID", + "name": "List ID", + "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductSessions", + "setDefinitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "Job_ID", + "localizedDescription": { + "value": "Job_ID" + }, + "definitionID": "0d86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Job_ID", + "definitionName": { + "value": "Job ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Predictive Intelligence Product Sessions.Job ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "0d86d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductSessions", + "definitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Job_ID", + "storageFieldReferenceID": { + "type": "guid", + "value": "5c73cf1c-8fbd-4275-bca1-5a232c5ebb35" + }, + "valueDefinitionID": "0d86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Job_ID", + "name": "Job ID", + "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductSessions", + "setDefinitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "Landing_URL_ID", + "localizedDescription": { + "value": "Landing_URL_ID" + }, + "definitionID": "0e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Landing_URL_ID", + "definitionName": { + "value": "Landing URL ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "Predictive Intelligence Product Sessions.Landing URL ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "0e86d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 7, + "parentDefinition": { + "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductSessions", + "definitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Landing_URL_ID", + "storageFieldReferenceID": { + "type": "guid", + "value": "60fd37ce-3306-4197-a0e2-7c1b51b46d3a" + }, + "valueDefinitionID": "0e86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Landing_URL_ID", + "name": "Landing URL ID", + "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductSessions", + "setDefinitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "Subscriber_ID", + "localizedDescription": { + "value": "Subscriber_ID" + }, + "definitionID": "1186d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Subscriber_ID", + "definitionName": { + "value": "Subscriber_ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 8, + "fullyQualifiedName": "Predictive Intelligence Product Sessions.Subscriber_ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "1186d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 8, + "parentDefinition": { + "definitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductSessions", + "definitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Subscriber_ID", + "storageFieldReferenceID": { + "type": "guid", + "value": "f239f3c3-3ecc-4ec4-a4c9-de258fdefdea" + }, + "valueDefinitionID": "1186d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Subscriber_ID", + "name": "Subscriber_ID", + "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductSessions", + "setDefinitionName": { + "value": "Predictive Intelligence Product Sessions" + }, + "parentIdentifier": "0b86d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence Product Sessions", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 0, + "storageLogicalType": "DataExtension", + "storageName": "PI_SESSIONS", + "storageObjectIDs": ["0286d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "dd52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductSessions", + "name": "Predictive Intelligence Product Sessions" + }, + { + "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailAddresses", + "definitionName": { + "value": "Email Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": true, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "8f93dc39-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeGroup" + }, + "leftRelationshipIDs": [ + { + "type": "int16", + "value": "4" + } + ], + "leftRelationshipReferenceType": "CustomerData", + "relationshipAttributes": [ + { + "leftAttributeID": "1151de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "1151de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "1451de3f-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Number", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "1251de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ListID", + "definitionName": { + "value": "List ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 0, + "fullyQualifiedName": "Email Addresses.List ID", + "isHidden": true, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 0, + "parentDefinition": { + "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailAddresses", + "definitionName": { + "value": "Email Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ListID", + "valueDefinitionID": "1251de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ListID", + "name": "List ID", + "setDefinitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailAddresses", + "setDefinitionName": { + "value": "Email Addresses" + }, + "parentIdentifier": "1051de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Number", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "1351de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MemberID", + "definitionName": { + "value": "Member ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 0, + "fullyQualifiedName": "Email Addresses.Member ID", + "isHidden": true, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 0, + "parentDefinition": { + "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailAddresses", + "definitionName": { + "value": "Email Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "MemberID_", + "valueDefinitionID": "1351de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "MemberID", + "name": "Member ID", + "setDefinitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailAddresses", + "setDefinitionName": { + "value": "Email Addresses" + }, + "parentIdentifier": "1051de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "customerDataID": 4, + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "EmailAddress", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "1151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailAddress", + "definitionName": { + "value": "Email Address" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Email Addresses.Email Address", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailAddresses", + "definitionName": { + "value": "Email Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "EmailAddr_", + "valueDefinitionID": "1151de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "EmailAddress", + "name": "Email Address", + "setDefinitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailAddresses", + "setDefinitionName": { + "value": "Email Addresses" + }, + "parentIdentifier": "1051de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Boolean", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Boolean", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b951de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "HTMLEnabled", + "definitionName": { + "value": "HTML Enabled" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Email Addresses.HTML Enabled", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 2, + "parentDefinition": { + "definitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailAddresses", + "definitionName": { + "value": "Email Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "IsHTMLEnabled", + "valueDefinitionID": "b951de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "HTMLEnabled", + "name": "HTML Enabled", + "setDefinitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailAddresses", + "setDefinitionName": { + "value": "Email Addresses" + }, + "parentIdentifier": "1051de3f-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "b2ca1f50-3cc4-4fd7-a3a3-88bf09fb59fa", + "applicationKey": "com.exacttarget.email", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "localizedDescription": {}, + "fullyQualifiedName": "Email Addresses", + "isCustomObjectBacked": false, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isSystemDefined": true, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 1, + "storageObjectIDs": [ + "92492fc1-7a08-4c96-8536-0344719009e1", + "c336765a-f24f-49b2-8a1f-b54f903def2a" + ], + "setDefinitionID": "1051de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailAddresses", + "name": "Email Addresses" + }, + { + "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentViews", + "definitionName": { + "value": "Predictive Intelligence Content Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "1f86d645-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "3086d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "3586d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "2486d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence Content Views.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentViews", + "definitionName": { + "value": "Predictive Intelligence Content Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "2486d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentViews", + "setDefinitionName": { + "value": "Predictive Intelligence Content Views" + }, + "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "content_id", + "localizedDescription": { + "value": "content_id" + }, + "definitionID": "1f86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Content_ID", + "definitionName": { + "value": "Content ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence Content Views.Content ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "1f86d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentViews", + "definitionName": { + "value": "Predictive Intelligence Content Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "content_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "1abf7b9d-1222-469f-9df9-7835829ec41f" + }, + "valueDefinitionID": "1f86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Content_ID", + "name": "Content ID", + "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentViews", + "setDefinitionName": { + "value": "Predictive Intelligence Content Views" + }, + "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "user_Id", + "localizedDescription": { + "value": "user_Id" + }, + "definitionID": "2386d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "User_ID", + "definitionName": { + "value": "User ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence Content Views.User ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "2386d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentViews", + "definitionName": { + "value": "Predictive Intelligence Content Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "user_Id", + "storageFieldReferenceID": { + "type": "guid", + "value": "a6c60012-6673-4402-8262-c6f06e1b0d13" + }, + "valueDefinitionID": "2386d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "User_ID", + "name": "User ID", + "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentViews", + "setDefinitionName": { + "value": "Predictive Intelligence Content Views" + }, + "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "session_id", + "localizedDescription": { + "value": "session_id" + }, + "definitionID": "2186d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Session_ID", + "definitionName": { + "value": "Session ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence Content Views.Session ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "2186d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentViews", + "definitionName": { + "value": "Predictive Intelligence Content Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "session_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "78820841-1579-42dd-8300-3cfe4eec96cc" + }, + "valueDefinitionID": "2186d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Session_ID", + "name": "Session ID", + "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentViews", + "setDefinitionName": { + "value": "Predictive Intelligence Content Views" + }, + "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Search", + "localizedDescription": { + "value": "Search" + }, + "definitionID": "2086d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Search", + "definitionName": { + "value": "Search" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence Content Views.Search", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 1000, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "2086d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentViews", + "definitionName": { + "value": "Predictive Intelligence Content Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Search", + "storageFieldReferenceID": { + "type": "guid", + "value": "f1ecc397-6be7-4a53-8792-0fdbaff63505" + }, + "valueDefinitionID": "2086d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Search", + "name": "Search", + "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentViews", + "setDefinitionName": { + "value": "Predictive Intelligence Content Views" + }, + "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Date", + "description": "Timestamp", + "localizedDescription": { + "value": "Timestamp" + }, + "definitionID": "2286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Timestamp", + "definitionName": { + "value": "Timestamp" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Predictive Intelligence Content Views.Timestamp", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "2286d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentViews", + "definitionName": { + "value": "Predictive Intelligence Content Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Timestamp", + "storageFieldReferenceID": { + "type": "guid", + "value": "e5c8ef5d-f2df-464d-b0ba-aa06536ac934" + }, + "valueDefinitionID": "2286d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Timestamp", + "name": "Timestamp", + "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentViews", + "setDefinitionName": { + "value": "Predictive Intelligence Content Views" + }, + "parentIdentifier": "1e86d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence Content Views", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 1, + "storageLogicalType": "DataExtension", + "storageName": "PI_CONTENTVIEWS", + "storageObjectIDs": ["1786d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "da52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentViews", + "name": "Predictive Intelligence Content Views" + }, + { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": true, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "4351de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeGroup" + }, + "leftRelationshipIDs": [ + { + "type": "int16", + "value": "2" + } + ], + "leftRelationshipReferenceType": "CustomerData", + "relationshipAttributes": [ + { + "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "2f51de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "4651de3f-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "3651de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "3452de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "4352de3f-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "2c51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CarrierID", + "definitionName": { + "value": "Carrier ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "MobileConnect Demographics.Carrier ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "2c51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 1, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CarrierID", + "storageFieldReferenceID": { + "type": "guid", + "value": "3fdc8842-cc0f-407c-a3ec-930d7a027d1d" + }, + "valueDefinitionID": "2c51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CarrierID", + "name": "Carrier ID", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "2d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Channel", + "definitionName": { + "value": "Channel" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "MobileConnect Demographics.Channel", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 20, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "2d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_Channel", + "storageFieldReferenceID": { + "type": "guid", + "value": "ef36ded9-67b2-4daf-899f-6862af8e5ee7" + }, + "valueDefinitionID": "2d51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Channel", + "name": "Channel", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "2e51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "City", + "definitionName": { + "value": "City" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "MobileConnect Demographics.City", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "2e51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_City", + "storageFieldReferenceID": { + "type": "guid", + "value": "be7b4554-bf03-4a80-9101-3e396b2e345f" + }, + "valueDefinitionID": "2e51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "City", + "name": "City", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "2f51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ContactID", + "definitionName": { + "value": "Contact ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "MobileConnect Demographics.Contact ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "2f51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ContactID", + "storageFieldReferenceID": { + "type": "guid", + "value": "b0e31883-cae8-4bc5-aa24-88565d375a18" + }, + "valueDefinitionID": "2f51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ContactID", + "name": "Contact ID", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedBy", + "definitionName": { + "value": "Created By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "MobileConnect Demographics.Created By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3151de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedBy", + "storageFieldReferenceID": { + "type": "guid", + "value": "1671a32a-8eb0-4dc5-b30d-8ad16e55a601" + }, + "valueDefinitionID": "3151de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedBy", + "name": "Created By", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3251de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedDate", + "definitionName": { + "value": "Created Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "MobileConnect Demographics.Created Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3251de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "de543ca5-5920-4309-adb9-33472144defe" + }, + "valueDefinitionID": "3251de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedDate", + "name": "Created Date", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3351de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "FirstName", + "definitionName": { + "value": "First Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "MobileConnect Demographics.First Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3351de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 9, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_FirstName", + "storageFieldReferenceID": { + "type": "guid", + "value": "125f7c91-2f11-44bd-9687-f22cf2461496" + }, + "valueDefinitionID": "3351de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "FirstName", + "name": "First Name", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Boolean", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Boolean", + "defaultValue": "False", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3451de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "IsHonorDST", + "definitionName": { + "value": "Is Honor DST" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "MobileConnect Demographics.Is Honor DST", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3451de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 10, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_IsHonorDST", + "storageFieldReferenceID": { + "type": "guid", + "value": "17abe00a-4306-43c5-b27f-a81f015d6dfb" + }, + "valueDefinitionID": "3451de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "IsHonorDST", + "name": "Is Honor DST", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "LastName", + "definitionName": { + "value": "Last Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 11, + "fullyQualifiedName": "MobileConnect Demographics.Last Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3551de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 11, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_LastName", + "storageFieldReferenceID": { + "type": "guid", + "value": "e31f18f4-5422-410b-adcc-1b60f61cce5f" + }, + "valueDefinitionID": "3551de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "LastName", + "name": "Last Name", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3051de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CountryCode", + "definitionName": { + "value": "Locale" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 12, + "fullyQualifiedName": "MobileConnect Demographics.Locale", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": 2, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3051de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 12, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CountryCode", + "storageFieldReferenceID": { + "type": "guid", + "value": "4b5fda70-47cb-4f4b-8ba6-f5cac53ee344" + }, + "valueDefinitionID": "3051de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CountryCode", + "name": "Locale", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "2ddd5f89-bca1-ed11-b852-48df37d1df5b", + "definitionKey": "MobileID", + "definitionName": { + "value": "Mobile ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 13, + "fullyQualifiedName": "MobileConnect Demographics.Mobile ID", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 13, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_MobileId", + "valueDefinitionID": "2ddd5f89-bca1-ed11-b852-48df37d1df5b", + "valueDefinitionKey": "MobileID", + "name": "Mobile ID", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "customerDataID": 5, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Phone", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3651de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileNumber", + "definitionName": { + "value": "Mobile Number" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 14, + "fullyQualifiedName": "MobileConnect Demographics.Mobile Number", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": 15, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3651de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 14, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_MobileNumber", + "storageFieldReferenceID": { + "type": "guid", + "value": "e31a7e3b-e943-440e-9be6-77224a4928fe" + }, + "valueDefinitionID": "3651de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "MobileNumber", + "name": "Mobile Number", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3751de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedBy", + "definitionName": { + "value": "Modified By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 15, + "fullyQualifiedName": "MobileConnect Demographics.Modified By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3751de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 15, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedBy", + "storageFieldReferenceID": { + "type": "guid", + "value": "a9be58ef-884d-44f4-9926-d73ebe587847" + }, + "valueDefinitionID": "3751de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedBy", + "name": "Modified By", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3851de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedDate", + "definitionName": { + "value": "Modified Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 16, + "fullyQualifiedName": "MobileConnect Demographics.Modified Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3851de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 16, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "216659c1-9512-47de-a9ee-822f48148514" + }, + "valueDefinitionID": "3851de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedDate", + "name": "Modified Date", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3951de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Priority", + "definitionName": { + "value": "Priority" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 17, + "fullyQualifiedName": "MobileConnect Demographics.Priority", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3951de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 17, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_Priority", + "storageFieldReferenceID": { + "type": "guid", + "value": "71153ee5-a33f-4cf6-a963-0c3a893d9348" + }, + "valueDefinitionID": "3951de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Priority", + "name": "Priority", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3a51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Source", + "definitionName": { + "value": "Source" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 18, + "fullyQualifiedName": "MobileConnect Demographics.Source", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3a51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 18, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 5, + "storageName": "_Source", + "storageFieldReferenceID": { + "type": "guid", + "value": "f6bafdfb-86bf-45e8-9b76-b878c904d6c5" + }, + "valueDefinitionID": "3a51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Source", + "name": "Source", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "SourceObjectID", + "definitionName": { + "value": "Source Object ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 19, + "fullyQualifiedName": "MobileConnect Demographics.Source Object ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 19, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_SourceObjectId", + "storageFieldReferenceID": { + "type": "guid", + "value": "c67a7922-44e5-4c4b-a4c8-2ac3550a5f07" + }, + "valueDefinitionID": "3b51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "SourceObjectID", + "name": "Source Object ID", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 4, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "67ace0e3-8563-e811-80d4-1402ec721f75", + "definitionKey": "SFContactID", + "definitionName": { + "value": "SFContactID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 19, + "fullyQualifiedName": "MobileConnect Demographics.SFContactID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 50, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "67ace0e3-8563-e811-80d4-1402ec721f75" + }, + "ordinal": 19, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "SFContactID", + "storageFieldReferenceID": { + "type": "guid", + "value": "ce5a90ea-88eb-4683-9a1a-5c776b5763ce" + }, + "valueDefinitionID": "67ace0e3-8563-e811-80d4-1402ec721f75", + "valueDefinitionKey": "SFContactID", + "name": "SFContactID", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3c51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "State", + "definitionName": { + "value": "State" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 20, + "fullyQualifiedName": "MobileConnect Demographics.State", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3c51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 20, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_State", + "storageFieldReferenceID": { + "type": "guid", + "value": "c0ea1fac-d939-4dde-b45a-16586f661924" + }, + "valueDefinitionID": "3c51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "State", + "name": "State", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Status", + "definitionName": { + "value": "Status" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 21, + "fullyQualifiedName": "MobileConnect Demographics.Status", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 21, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 6, + "storageName": "_Status", + "storageFieldReferenceID": { + "type": "guid", + "value": "fafff407-c055-411c-81ec-78907f5dbd58" + }, + "valueDefinitionID": "3d51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Status", + "name": "Status", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Decimal", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3e51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "UTCOffset", + "definitionName": { + "value": "UTC Offset" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 22, + "fullyQualifiedName": "MobileConnect Demographics.UTC Offset", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": 4, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3e51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 22, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 2, + "storageName": "_UTCOffset", + "storageFieldReferenceID": { + "type": "guid", + "value": "84d29656-a348-43c2-ac2f-8c7ec5b18a3e" + }, + "valueDefinitionID": "3e51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "UTCOffset", + "name": "UTC Offset", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3f51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ZipCode", + "definitionName": { + "value": "Zip Code" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 23, + "fullyQualifiedName": "MobileConnect Demographics.Zip Code", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 20, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3f51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 23, + "parentDefinition": { + "definitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileDemographics", + "definitionName": { + "value": "MobileConnect Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ZipCode", + "storageFieldReferenceID": { + "type": "guid", + "value": "11ce9d05-a1e3-47ba-9077-11097e0b4c8d" + }, + "valueDefinitionID": "3f51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ZipCode", + "name": "Zip Code", + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "setDefinitionName": { + "value": "MobileConnect Demographics" + }, + "parentIdentifier": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "e25893f9-08f3-480f-8def-7f8ab0583611", + "applicationKey": "com.exacttarget.mobileconnect", + "attributeCount": 0, + "canAddValues": true, + "canChangeValues": true, + "canModify": false, + "canRemove": false, + "categoryID": 2, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "MobileConnect Demographics", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": false, + "isRoot": false, + "isSendable": true, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 2, + "sendAttributeStorageName": "_ContactID", + "sendContactKeyStorageName": "_SubscriberID", + "storageLogicalType": "MobileAttributes", + "storageName": "_MobileAddress", + "storageObjectIDs": ["1651de3f-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "7693dc39-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "2b51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileDemographics", + "name": "MobileConnect Demographics" + }, + { + "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContent", + "definitionName": { + "value": "Predictive Intelligence Content" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "3086d645-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "4286d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "4686d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3386d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence Content.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContent", + "definitionName": { + "value": "Predictive Intelligence Content" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "3386d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContent", + "setDefinitionName": { + "value": "Predictive Intelligence Content" + }, + "parentIdentifier": "2e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "content_id", + "localizedDescription": { + "value": "content_id" + }, + "definitionID": "3086d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Content_ID", + "definitionName": { + "value": "Content ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence Content.Content ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3086d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContent", + "definitionName": { + "value": "Predictive Intelligence Content" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "content_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "9fd67d4d-cae5-4230-8cf1-f19cd230a233" + }, + "valueDefinitionID": "3086d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Content_ID", + "name": "Content ID", + "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContent", + "setDefinitionName": { + "value": "Predictive Intelligence Content" + }, + "parentIdentifier": "2e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Boolean", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Boolean", + "description": "availability", + "localizedDescription": { + "value": "availability" + }, + "definitionID": "2f86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Availability", + "definitionName": { + "value": "Availability" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence Content.Availability", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "2f86d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContent", + "definitionName": { + "value": "Predictive Intelligence Content" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "availability", + "storageFieldReferenceID": { + "type": "guid", + "value": "d32b9706-78a0-40fd-aae5-e345b1f217a6" + }, + "valueDefinitionID": "2f86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Availability", + "name": "Availability", + "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContent", + "setDefinitionName": { + "value": "Predictive Intelligence Content" + }, + "parentIdentifier": "2e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "title", + "localizedDescription": { + "value": "title" + }, + "definitionID": "3186d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Title", + "definitionName": { + "value": "Title" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence Content.Title", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 1000, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3186d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContent", + "definitionName": { + "value": "Predictive Intelligence Content" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "title", + "storageFieldReferenceID": { + "type": "guid", + "value": "93497a91-7e2d-4c5f-8546-fd035fea3e92" + }, + "valueDefinitionID": "3186d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Title", + "name": "Title", + "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContent", + "setDefinitionName": { + "value": "Predictive Intelligence Content" + }, + "parentIdentifier": "2e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "uuid", + "localizedDescription": { + "value": "uuid" + }, + "definitionID": "3286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "UUID", + "definitionName": { + "value": "UUID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence Content.UUID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3286d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContent", + "definitionName": { + "value": "Predictive Intelligence Content" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "uuid", + "storageFieldReferenceID": { + "type": "guid", + "value": "d42586c8-bb5b-46a1-ac88-32fc232dbcc7" + }, + "valueDefinitionID": "3286d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "UUID", + "name": "UUID", + "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContent", + "setDefinitionName": { + "value": "Predictive Intelligence Content" + }, + "parentIdentifier": "2e86d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence Content", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 1, + "storageLogicalType": "DataExtension", + "storageName": "PI_CONTENT", + "storageObjectIDs": ["2886d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "db52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "2e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContent", + "name": "Predictive Intelligence Content" + }, + { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3252de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedBy", + "definitionName": { + "value": "Created By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "MobileConnect Subscriptions.Created By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3252de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 1, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedBy", + "storageFieldReferenceID": { + "type": "guid", + "value": "a64a3ed9-b8fd-46cc-a10b-1d5fdf074ce6" + }, + "valueDefinitionID": "3252de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedBy", + "name": "Created By", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedDate", + "definitionName": { + "value": "Created Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "MobileConnect Subscriptions.Created Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3352de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "dfc3f6fb-a250-4ef8-93ed-bb079ced468d" + }, + "valueDefinitionID": "3352de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedDate", + "name": "Created Date", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3f52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "SubscriptionDefinitionID", + "definitionName": { + "value": "Keyword" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "MobileConnect Subscriptions.Keyword", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3f52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 7, + "storageName": "_SubscriptionDefinitionID", + "storageFieldReferenceID": { + "type": "guid", + "value": "c13ab46d-6e65-475a-990d-291bd43e5063" + }, + "valueDefinitionID": "3f52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "SubscriptionDefinitionID", + "name": "Keyword", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Phone", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileNumber", + "definitionName": { + "value": "Mobile Number" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "MobileConnect Subscriptions.Mobile Number", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 15, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3452de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_MobileNumber", + "storageFieldReferenceID": { + "type": "guid", + "value": "ead8a6d2-bc6c-4768-a6e3-c3cc749bfc1d" + }, + "valueDefinitionID": "3452de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "MobileNumber", + "name": "Mobile Number", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "53dd5f89-bca1-ed11-b852-48df37d1df5b", + "definitionKey": "MobileSubscriptionID", + "definitionName": { + "value": "Mobile Subscription ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "MobileConnect Subscriptions.Mobile Subscription ID", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 5, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_MobileSubscriptionID", + "valueDefinitionID": "53dd5f89-bca1-ed11-b852-48df37d1df5b", + "valueDefinitionKey": "MobileSubscriptionID", + "name": "Mobile Subscription ID", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3552de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedBy", + "definitionName": { + "value": "Modified By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "MobileConnect Subscriptions.Modified By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3552de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedBy", + "storageFieldReferenceID": { + "type": "guid", + "value": "30d7ec39-85d1-46dc-9888-771f11ffe10d" + }, + "valueDefinitionID": "3552de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedBy", + "name": "Modified By", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedDate", + "definitionName": { + "value": "Modified Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "MobileConnect Subscriptions.Modified Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3652de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 7, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "b68155cc-e483-4949-82f9-fb47cbd59764" + }, + "valueDefinitionID": "3652de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedDate", + "name": "Modified Date", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3752de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInDate", + "definitionName": { + "value": "Opt In Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 8, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt In Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3752de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 8, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptInDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "8da557ee-7ba7-44f4-99ba-0681cbeb1ba1" + }, + "valueDefinitionID": "3752de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInDate", + "name": "Opt In Date", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3852de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInMethodID", + "definitionName": { + "value": "Opt In Method" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt In Method", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3852de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 9, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 2, + "storageName": "_OptInMethodID", + "storageFieldReferenceID": { + "type": "guid", + "value": "da2713ab-a802-4cd6-9e05-0a7444d62388" + }, + "valueDefinitionID": "3852de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInMethodID", + "name": "Opt In Method", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3952de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInStatusID", + "definitionName": { + "value": "Opt In Status" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt In Status", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3952de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 10, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 1, + "storageName": "_OptInStatusID", + "storageFieldReferenceID": { + "type": "guid", + "value": "c733b80d-2ed5-4fb6-94a3-9c996cbae558" + }, + "valueDefinitionID": "3952de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInStatusID", + "name": "Opt In Status", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3a52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptOutDate", + "definitionName": { + "value": "Opt Out Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 11, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt Out Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3a52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 11, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptOutDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "27c3ccec-47ad-4578-9051-a41f85178049" + }, + "valueDefinitionID": "3a52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptOutDate", + "name": "Opt Out Date", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3b52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptOutMethodID", + "definitionName": { + "value": "Opt Out Method" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 12, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt Out Method", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3b52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 12, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 4, + "storageName": "_OptOutMethodID", + "storageFieldReferenceID": { + "type": "guid", + "value": "089b96fc-bfc6-402e-a481-1e18d3e18a8d" + }, + "valueDefinitionID": "3b52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptOutMethodID", + "name": "Opt Out Method", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3c52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptOutStatusID", + "definitionName": { + "value": "Opt Out Status" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 13, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt Out Status", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3c52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 13, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 3, + "storageName": "_OptOutStatusID", + "storageFieldReferenceID": { + "type": "guid", + "value": "67194503-acd8-4c1c-b042-9dfb3f3ebd44" + }, + "valueDefinitionID": "3c52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptOutStatusID", + "name": "Opt Out Status", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3d52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Source", + "definitionName": { + "value": "Source" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 14, + "fullyQualifiedName": "MobileConnect Subscriptions.Source", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3d52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 14, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 5, + "storageName": "_Source", + "storageFieldReferenceID": { + "type": "guid", + "value": "2e903257-43e8-4a7b-8ed4-757ca772ddbb" + }, + "valueDefinitionID": "3d52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Source", + "name": "Source", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "3e52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "SourceObjectID", + "definitionName": { + "value": "Source Object ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 15, + "fullyQualifiedName": "MobileConnect Subscriptions.Source Object ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3e52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 15, + "parentDefinition": { + "definitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileSubscriptions", + "definitionName": { + "value": "MobileConnect Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_SourceObjectId", + "storageFieldReferenceID": { + "type": "guid", + "value": "1d4f26f5-ec91-46de-9fc1-d819832f07e7" + }, + "valueDefinitionID": "3e52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "SourceObjectID", + "name": "Source Object ID", + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "parentIdentifier": "3152de3f-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "e25893f9-08f3-480f-8def-7f8ab0583611", + "applicationKey": "com.exacttarget.mobileconnect", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 2, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "MobileConnect Subscriptions", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": false, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 0, + "storageLogicalType": "DataExtension", + "storageName": "_MobileSubscription", + "storageObjectIDs": ["2252de3f-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "7793dc39-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "name": "MobileConnect Subscriptions" + }, + { + "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentAttribs", + "definitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "4486d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence Content Attributes.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentAttribs", + "definitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "4486d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "content_id", + "localizedDescription": { + "value": "content_id" + }, + "definitionID": "4286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Content_ID", + "definitionName": { + "value": "Content ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence Content Attributes.Content ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "4286d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentAttribs", + "definitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "content_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "d1abd045-4670-41f2-a368-9e0a6f732146" + }, + "valueDefinitionID": "4286d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Content_ID", + "name": "Content ID", + "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "AttribName", + "localizedDescription": { + "value": "AttribName" + }, + "definitionID": "3f86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Attribute_Name", + "definitionName": { + "value": "Attribute Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence Content Attributes.Attribute Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 1000, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "3f86d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentAttribs", + "definitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "AttribName", + "storageFieldReferenceID": { + "type": "guid", + "value": "a55251d7-c1c5-49b3-bdc1-8ebdbf7cb517" + }, + "valueDefinitionID": "3f86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Attribute_Name", + "name": "Attribute Name", + "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "AttribValue", + "localizedDescription": { + "value": "AttribValue" + }, + "definitionID": "4186d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Attribute_Value", + "definitionName": { + "value": "Attribute Value" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence Content Attributes.Attribute Value", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 1000, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "4186d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentAttribs", + "definitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "AttribValue", + "storageFieldReferenceID": { + "type": "guid", + "value": "1742dd68-39af-4da9-ace4-0ad50ae08f05" + }, + "valueDefinitionID": "4186d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Attribute_Value", + "name": "Attribute Value", + "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Date", + "description": "updated_at", + "localizedDescription": { + "value": "updated_at" + }, + "definitionID": "4386d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Updated_At", + "definitionName": { + "value": "Updated At" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence Content Attributes.Updated At", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "4386d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentAttribs", + "definitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "updated_at", + "storageFieldReferenceID": { + "type": "guid", + "value": "4ad58eb4-5e13-4064-ae43-71ab9786be00" + }, + "valueDefinitionID": "4386d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Updated_At", + "name": "Updated At", + "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Number", + "description": "attributeValueIndex", + "localizedDescription": { + "value": "attributeValueIndex" + }, + "definitionID": "4086d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Attribute_Value_Index", + "definitionName": { + "value": "Attribute Value Index" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Predictive Intelligence Content Attributes.Attribute Value Index", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "4086d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelContentAttribs", + "definitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "attributeValueIndex", + "storageFieldReferenceID": { + "type": "guid", + "value": "3635848d-5e04-4fed-95ed-d487202a80b8" + }, + "valueDefinitionID": "4086d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Attribute_Value_Index", + "name": "Attribute Value Index", + "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Content Attributes" + }, + "parentIdentifier": "3e86d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence Content Attributes", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 0, + "storageLogicalType": "DataExtension", + "storageName": "PI_CONTENTATTRIBS", + "storageObjectIDs": ["3786d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "dc52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "3e86d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelContentAttribs", + "name": "Predictive Intelligence Content Attributes" + }, + { + "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartEvents", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "5286d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "5386d645-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "6686d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "6c86d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "6586d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "5b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Custom_Object_Key", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartEvents", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "5b86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Custom_Object_Key", + "name": "Custom Object Key", + "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "user_id", + "localizedDescription": { + "value": "user_id" + }, + "definitionID": "5a86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "user_id", + "definitionName": { + "value": "user_id" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.user_id", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "5a86d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartEvents", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "user_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "e6f01b13-78b2-4cf7-956a-7a9a5db31a82" + }, + "valueDefinitionID": "5a86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "user_id", + "name": "user_id", + "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "cart_id", + "localizedDescription": { + "value": "cart_id" + }, + "definitionID": "5386d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Cart_ID", + "definitionName": { + "value": "Cart ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Cart ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "5386d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartEvents", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "cart_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "3f7d9be8-3af9-425b-9537-442a9e389582" + }, + "valueDefinitionID": "5386d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Cart_ID", + "name": "Cart ID", + "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "contact_key", + "localizedDescription": { + "value": "contact_key" + }, + "definitionID": "5586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Contact_Key", + "definitionName": { + "value": "Contact Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Contact Key", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "5586d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartEvents", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "contact_key", + "storageFieldReferenceID": { + "type": "guid", + "value": "7a8eb4a3-5270-4e28-9562-96067a13a6fd" + }, + "valueDefinitionID": "5586d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Contact_Key", + "name": "Contact Key", + "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "currency_type", + "localizedDescription": { + "value": "currency_type" + }, + "definitionID": "5686d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Currency_Type", + "definitionName": { + "value": "Currency Type" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Currency Type", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "5686d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartEvents", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "currency_type", + "storageFieldReferenceID": { + "type": "guid", + "value": "32d910c3-7e8e-4cf6-af31-596b395246f0" + }, + "valueDefinitionID": "5686d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Currency_Type", + "name": "Currency Type", + "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Number", + "description": "no_items_cart", + "localizedDescription": { + "value": "no_items_cart" + }, + "definitionID": "5886d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "No_Items_Cart", + "definitionName": { + "value": "No Items Cart" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.No Items Cart", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "5886d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartEvents", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "no_items_cart", + "storageFieldReferenceID": { + "type": "guid", + "value": "74f890d4-eb4b-46c1-9cd5-f2f89702825d" + }, + "valueDefinitionID": "5886d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "No_Items_Cart", + "name": "No Items Cart", + "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Decimal", + "description": "cart_value", + "localizedDescription": { + "value": "cart_value" + }, + "definitionID": "5486d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Cart_Value", + "definitionName": { + "value": "Cart Value" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Cart Value", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "5486d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 7, + "parentDefinition": { + "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartEvents", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 2, + "storageName": "cart_value", + "storageFieldReferenceID": { + "type": "guid", + "value": "dc3238a5-1546-47b1-95ac-cfebae4bb4b6" + }, + "valueDefinitionID": "5486d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Cart_Value", + "name": "Cart Value", + "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "getdate()", + "description": "timestamp", + "localizedDescription": { + "value": "timestamp" + }, + "definitionID": "5986d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Time_Stamp", + "definitionName": { + "value": "Time Stamp" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 8, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.Time Stamp", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "5986d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 8, + "parentDefinition": { + "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartEvents", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "timestamp", + "storageFieldReferenceID": { + "type": "guid", + "value": "e8051d08-f6e2-492b-9476-db03d0b4e71b" + }, + "valueDefinitionID": "5986d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Time_Stamp", + "name": "Time Stamp", + "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "email_address", + "localizedDescription": { + "value": "email_address" + }, + "definitionID": "5786d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "email_address", + "definitionName": { + "value": "email_address" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents.email_address", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "5786d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 9, + "parentDefinition": { + "definitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartEvents", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "email_address", + "storageFieldReferenceID": { + "type": "guid", + "value": "1a242f2d-4161-4713-b7b1-6426f26f5157" + }, + "valueDefinitionID": "5786d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "email_address", + "name": "email_address", + "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartEvents" + }, + "parentIdentifier": "5286d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartEvents", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 1, + "storageLogicalType": "DataExtension", + "storageName": "PI_ABANDONED_CART_EVENT", + "storageObjectIDs": ["4886d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "df52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "5286d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartEvents", + "name": "Predictive Intelligence AbandonedCartEvents" + }, + { + "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartItems", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "6586d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "6686d645-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "6686d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "7887d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "6586d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "6a86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Custom_Object_Key", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartItems", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "6a86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Custom_Object_Key", + "name": "Custom Object Key", + "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartItems", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "parentIdentifier": "6586d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "sku", + "localizedDescription": { + "value": "sku" + }, + "definitionID": "6986d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "sku", + "definitionName": { + "value": "sku" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems.sku", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "6986d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartItems", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "sku", + "storageFieldReferenceID": { + "type": "guid", + "value": "85feb2dd-3ea4-4e33-93ca-a0b2e129342f" + }, + "valueDefinitionID": "6986d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "sku", + "name": "sku", + "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartItems", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "parentIdentifier": "6586d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "cart_id", + "localizedDescription": { + "value": "cart_id" + }, + "definitionID": "6686d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "cart_id", + "definitionName": { + "value": "Cart ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems.Cart ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "6686d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartItems", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "cart_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "686a5045-b1b9-497f-9226-9e43b5b09906" + }, + "valueDefinitionID": "6686d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "cart_id", + "name": "Cart ID", + "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartItems", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "parentIdentifier": "6586d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Decimal", + "description": "price", + "localizedDescription": { + "value": "price" + }, + "definitionID": "6786d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Price", + "definitionName": { + "value": "Price" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems.Price", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "6786d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartItems", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 2, + "storageName": "price", + "storageFieldReferenceID": { + "type": "guid", + "value": "9a62ef64-4993-4876-a16c-9786eae6fd53" + }, + "valueDefinitionID": "6786d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Price", + "name": "Price", + "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartItems", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "parentIdentifier": "6586d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Number", + "description": "quantity", + "localizedDescription": { + "value": "quantity" + }, + "definitionID": "6886d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Quantity", + "definitionName": { + "value": "Quantity" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems.Quantity", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "6886d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelAbandonedCartItems", + "definitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "quantity", + "storageFieldReferenceID": { + "type": "guid", + "value": "20d85be0-e56d-4888-b66e-bb8b6466d07c" + }, + "valueDefinitionID": "6886d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Quantity", + "name": "Quantity", + "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartItems", + "setDefinitionName": { + "value": "Predictive Intelligence AbandonedCartItems" + }, + "parentIdentifier": "6586d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence AbandonedCartItems", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 1, + "storageLogicalType": "DataExtension", + "storageName": "PI_ABANDONED_CART_ITEMS", + "storageObjectIDs": ["5f86d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "e052de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "6586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelAbandonedCartItems", + "name": "Predictive Intelligence AbandonedCartItems" + }, + { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": true, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "9351de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeGroup" + }, + "leftRelationshipIDs": [ + { + "type": "int16", + "value": "2" + } + ], + "leftRelationshipReferenceType": "CustomerData", + "relationshipAttributes": [ + { + "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "7351de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "9651de3f-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "6f51de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "b452de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + }, + { + "leftAttributeID": "7751de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "b552de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "bc52de3f-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "6f51de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "c752de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + }, + { + "leftAttributeID": "7751de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "ca52de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "d052de3f-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "6e51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Alias", + "definitionName": { + "value": "Alias" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "MobilePush Demographics.Alias", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "6e51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 1, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_Alias", + "storageFieldReferenceID": { + "type": "guid", + "value": "dcef58d9-dcaa-4a68-9ecf-6c663a57fb33" + }, + "valueDefinitionID": "6e51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Alias", + "name": "Alias", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "customerDataID": 7, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "6f51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushAppID", + "definitionName": { + "value": "Application" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "MobilePush Demographics.Application", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 38, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "6f51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 11, + "storageName": "_APID", + "storageFieldReferenceID": { + "type": "guid", + "value": "4e82734e-ff8a-4868-a786-20e9596a94d2" + }, + "valueDefinitionID": "6f51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "PushAppID", + "name": "Application", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Number", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7051de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Badge", + "definitionName": { + "value": "Badge" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "MobilePush Demographics.Badge", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7051de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_Badge", + "storageFieldReferenceID": { + "type": "guid", + "value": "ae73cf07-6b58-4ae4-a75e-ccd1d4bdb98f" + }, + "valueDefinitionID": "7051de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Badge", + "name": "Badge", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Channel", + "definitionName": { + "value": "Channel" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "MobilePush Demographics.Channel", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 20, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7151de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_Channel", + "storageFieldReferenceID": { + "type": "guid", + "value": "84490d74-3c83-46b1-8a0b-b073dc45c208" + }, + "valueDefinitionID": "7151de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Channel", + "name": "Channel", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7251de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "City", + "definitionName": { + "value": "City" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "MobilePush Demographics.City", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7251de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_City", + "storageFieldReferenceID": { + "type": "guid", + "value": "905b7a96-ba4e-4265-a271-6b8d32fdf56e" + }, + "valueDefinitionID": "7251de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "City", + "name": "City", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7351de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ContactID", + "definitionName": { + "value": "Contact ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "MobilePush Demographics.Contact ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7351de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ContactID", + "storageFieldReferenceID": { + "type": "guid", + "value": "f5c616a4-6ba4-4c3f-a55b-85d12dd41932" + }, + "valueDefinitionID": "7351de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ContactID", + "name": "Contact ID", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7451de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedBy", + "definitionName": { + "value": "Created By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "MobilePush Demographics.Created By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7451de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 7, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedBy", + "storageFieldReferenceID": { + "type": "guid", + "value": "bf010c22-fd43-4303-a732-aff2510133f8" + }, + "valueDefinitionID": "7451de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedBy", + "name": "Created By", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedDate", + "definitionName": { + "value": "Created Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 8, + "fullyQualifiedName": "MobilePush Demographics.Created Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7551de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 8, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "1b450c10-bd4e-448e-ae6f-583ac616cc46" + }, + "valueDefinitionID": "7551de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedDate", + "name": "Created Date", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "9151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "MobilePush Demographics.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 9, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "9151de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7651de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Device", + "definitionName": { + "value": "Device" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "MobilePush Demographics.Device", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7651de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 10, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_Device", + "storageFieldReferenceID": { + "type": "guid", + "value": "1aa7b10f-f32a-4620-af79-4210aeacf996" + }, + "valueDefinitionID": "7651de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Device", + "name": "Device", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "customerDataID": 6, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7751de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDeviceID", + "definitionName": { + "value": "Device ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 11, + "fullyQualifiedName": "MobilePush Demographics.Device ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7751de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 11, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_DeviceID", + "storageFieldReferenceID": { + "type": "guid", + "value": "9d8db1d4-c00e-49bc-98d9-e30d2e3ed7cf" + }, + "valueDefinitionID": "7751de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "PushDeviceID", + "name": "Device ID", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7851de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "DeviceType", + "definitionName": { + "value": "Device Type" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 12, + "fullyQualifiedName": "MobilePush Demographics.Device Type", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 20, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7851de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 12, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_DeviceType", + "storageFieldReferenceID": { + "type": "guid", + "value": "75f38dcd-559f-4663-8e84-a5f85abc3e0a" + }, + "valueDefinitionID": "7851de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "DeviceType", + "name": "Device Type", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7951de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "FirstName", + "definitionName": { + "value": "First Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 13, + "fullyQualifiedName": "MobilePush Demographics.First Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7951de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 13, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_FirstName", + "storageFieldReferenceID": { + "type": "guid", + "value": "cf0e8f08-bba3-4ca3-b05c-e1360897f0f6" + }, + "valueDefinitionID": "7951de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "FirstName", + "name": "First Name", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7a51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "HardwareID", + "definitionName": { + "value": "Hardware ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 14, + "fullyQualifiedName": "MobilePush Demographics.Hardware ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7a51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 14, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_HardwareId", + "storageFieldReferenceID": { + "type": "guid", + "value": "a7c7ac11-c93d-4512-ae1b-25e9debbdddc" + }, + "valueDefinitionID": "7a51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "HardwareID", + "name": "Hardware ID", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Boolean", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Boolean", + "defaultValue": "False", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "IsHonorDST", + "definitionName": { + "value": "Is Honor DST" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 15, + "fullyQualifiedName": "MobilePush Demographics.Is Honor DST", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 15, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_IsHonorDST", + "storageFieldReferenceID": { + "type": "guid", + "value": "e5d1a20d-ec5a-40a2-a474-64513204cbac" + }, + "valueDefinitionID": "7b51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "IsHonorDST", + "name": "Is Honor DST", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7c51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "LastName", + "definitionName": { + "value": "Last Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 16, + "fullyQualifiedName": "MobilePush Demographics.Last Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7c51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 16, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_LastName", + "storageFieldReferenceID": { + "type": "guid", + "value": "92c01cad-907d-48c0-ac6a-691c12d62358" + }, + "valueDefinitionID": "7c51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "LastName", + "name": "Last Name", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Boolean", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Boolean", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "LocationEnabled", + "definitionName": { + "value": "Location Enabled" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 17, + "fullyQualifiedName": "MobilePush Demographics.Location Enabled", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 17, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_LocationEnabled", + "storageFieldReferenceID": { + "type": "guid", + "value": "30b5144d-9b73-4804-b17b-fbf4d2d03bfe" + }, + "valueDefinitionID": "7d51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "LocationEnabled", + "name": "Location Enabled", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7e51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedBy", + "definitionName": { + "value": "Modified By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 18, + "fullyQualifiedName": "MobilePush Demographics.Modified By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7e51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 18, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedBy", + "storageFieldReferenceID": { + "type": "guid", + "value": "46975e48-0dbb-4ec4-91e9-9823aa2a5d0a" + }, + "valueDefinitionID": "7e51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedBy", + "name": "Modified By", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7f51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedDate", + "definitionName": { + "value": "Modified Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 19, + "fullyQualifiedName": "MobilePush Demographics.Modified Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7f51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 19, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "4602d692-06de-4974-84e4-e8facfa25be9" + }, + "valueDefinitionID": "7f51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedDate", + "name": "Modified Date", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8051de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInDate", + "definitionName": { + "value": "Opt In Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 20, + "fullyQualifiedName": "MobilePush Demographics.Opt In Date", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8051de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 20, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptInDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "68c6681d-6f0f-4ec2-9407-55c5eb19fc19" + }, + "valueDefinitionID": "8051de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInDate", + "name": "Opt In Date", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInMethodID", + "definitionName": { + "value": "Opt In Method" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 21, + "fullyQualifiedName": "MobilePush Demographics.Opt In Method", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8151de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 21, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 9, + "storageName": "_OptInMethodID", + "storageFieldReferenceID": { + "type": "guid", + "value": "8b821a18-6cee-4204-9ef9-18d94112e84f" + }, + "valueDefinitionID": "8151de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInMethodID", + "name": "Opt In Method", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8251de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInStatusID", + "definitionName": { + "value": "Opt In Status" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 22, + "fullyQualifiedName": "MobilePush Demographics.Opt In Status", + "isHidden": true, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8251de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 22, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 8, + "storageName": "_OptInStatusID", + "storageFieldReferenceID": { + "type": "guid", + "value": "673470b8-8503-4c4c-b9ae-9bf554d0a235" + }, + "valueDefinitionID": "8251de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInStatusID", + "name": "Opt In Status", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8351de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptOutDate", + "definitionName": { + "value": "Opt Out Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 23, + "fullyQualifiedName": "MobilePush Demographics.Opt Out Date", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8351de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 23, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptOutDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "8424262e-6904-4915-a4b3-2957b044b3ee" + }, + "valueDefinitionID": "8351de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptOutDate", + "name": "Opt Out Date", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8451de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptOutMethodID", + "definitionName": { + "value": "Opt Out Method" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 24, + "fullyQualifiedName": "MobilePush Demographics.Opt Out Method", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8451de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 24, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 10, + "storageName": "_OptOutMethodID", + "storageFieldReferenceID": { + "type": "guid", + "value": "3919bba5-e953-435d-8874-66be31cb1821" + }, + "valueDefinitionID": "8451de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptOutMethodID", + "name": "Opt Out Method", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptOutStatusID", + "definitionName": { + "value": "Opt Out Status" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 25, + "fullyQualifiedName": "MobilePush Demographics.Opt Out Status", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8551de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 25, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptOutStatusID", + "storageFieldReferenceID": { + "type": "guid", + "value": "df789a9d-cfbc-4ed9-8a2b-e6427a631e28" + }, + "valueDefinitionID": "8551de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptOutStatusID", + "name": "Opt Out Status", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8651de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Platform", + "definitionName": { + "value": "Platform" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 26, + "fullyQualifiedName": "MobilePush Demographics.Platform", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8651de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 26, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_Platform", + "storageFieldReferenceID": { + "type": "guid", + "value": "353dc3ed-7578-4ee1-a1c1-e843f8b487f5" + }, + "valueDefinitionID": "8651de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Platform", + "name": "Platform", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8751de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PlatformVersion", + "definitionName": { + "value": "Platform Version" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 27, + "fullyQualifiedName": "MobilePush Demographics.Platform Version", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8751de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 27, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_PlatformVersion", + "storageFieldReferenceID": { + "type": "guid", + "value": "99c03236-d908-498f-936a-6b7e110ef76a" + }, + "valueDefinitionID": "8751de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "PlatformVersion", + "name": "Platform Version", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8851de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ProviderToken", + "definitionName": { + "value": "Provider Token" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 28, + "fullyQualifiedName": "MobilePush Demographics.Provider Token", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8851de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 28, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ProviderToken", + "storageFieldReferenceID": { + "type": "guid", + "value": "03b1ac7c-3cc4-4b82-b3db-7e6b43cefd7c" + }, + "valueDefinitionID": "8851de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ProviderToken", + "name": "Provider Token", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8951de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Source", + "definitionName": { + "value": "Source" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 29, + "fullyQualifiedName": "MobilePush Demographics.Source", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8951de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 29, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 12, + "storageName": "_Source", + "storageFieldReferenceID": { + "type": "guid", + "value": "a0c5a9fe-d72b-41dd-9307-77db3da0b9f4" + }, + "valueDefinitionID": "8951de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Source", + "name": "Source", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8a51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "SourceObjectID", + "definitionName": { + "value": "Source Object ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 30, + "fullyQualifiedName": "MobilePush Demographics.Source Object ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8a51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 30, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_SourceObjectId", + "storageFieldReferenceID": { + "type": "guid", + "value": "020d90c4-4c9c-4a00-b661-5b75ec0c9b88" + }, + "valueDefinitionID": "8a51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "SourceObjectID", + "name": "Source Object ID", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8b51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "State", + "definitionName": { + "value": "State" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 31, + "fullyQualifiedName": "MobilePush Demographics.State", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8b51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 31, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_State", + "storageFieldReferenceID": { + "type": "guid", + "value": "e65c52fd-e623-45cc-bb7a-1842617c5491" + }, + "valueDefinitionID": "8b51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "State", + "name": "State", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8c51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Status", + "definitionName": { + "value": "Status" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 32, + "fullyQualifiedName": "MobilePush Demographics.Status", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8c51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 32, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 13, + "storageName": "_Status", + "storageFieldReferenceID": { + "type": "guid", + "value": "a1c13a7c-566e-487f-8cc9-439064b6bfb4" + }, + "valueDefinitionID": "8c51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Status", + "name": "Status", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "SystemToken", + "definitionName": { + "value": "System Token" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 33, + "fullyQualifiedName": "MobilePush Demographics.System Token", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 4000, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 33, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_SystemToken", + "storageFieldReferenceID": { + "type": "guid", + "value": "d7e80e54-124c-4260-986b-b32b58b8c0ee" + }, + "valueDefinitionID": "8d51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "SystemToken", + "name": "System Token", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8e51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "TimeZone", + "definitionName": { + "value": "Time Zone" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 34, + "fullyQualifiedName": "MobilePush Demographics.Time Zone", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 50, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8e51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 34, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_TimeZone", + "storageFieldReferenceID": { + "type": "guid", + "value": "980d0010-a443-4044-9ca1-5d1cfeaedec7" + }, + "valueDefinitionID": "8e51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "TimeZone", + "name": "Time Zone", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Decimal", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8f51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "UTCOffset", + "definitionName": { + "value": "UTC Offset" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 35, + "fullyQualifiedName": "MobilePush Demographics.UTC Offset", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": 4, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8f51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 35, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 2, + "storageName": "_UTCOffset", + "storageFieldReferenceID": { + "type": "guid", + "value": "5c7c2a61-80da-4233-b895-54fd7e957e48" + }, + "valueDefinitionID": "8f51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "UTCOffset", + "name": "UTC Offset", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "9051de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ZipCode", + "definitionName": { + "value": "Zip Code" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 36, + "fullyQualifiedName": "MobilePush Demographics.Zip Code", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 20, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "9051de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 36, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ZipCode", + "storageFieldReferenceID": { + "type": "guid", + "value": "ac282849-4bc1-4373-8412-16a5d9ab31e4" + }, + "valueDefinitionID": "9051de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ZipCode", + "name": "Zip Code", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Number", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "08b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "PushAddressExtensionID", + "definitionName": { + "value": "Push Address Extension ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 37, + "fullyQualifiedName": "MobilePush Demographics.Push Address Extension ID", + "isHidden": true, + "isIdentityValue": true, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 37, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "PushAddressExtensionId", + "valueDefinitionID": "08b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "PushAddressExtensionID", + "name": "Push Address Extension ID", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "09b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "DeviceLanguage", + "definitionName": { + "value": "Device Language" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 38, + "fullyQualifiedName": "MobilePush Demographics.Device Language", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": -1, + "ordinal": 38, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "DeviceLanguage", + "valueDefinitionID": "09b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "DeviceLanguage", + "name": "Device Language", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "0ab0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "GcmSenderId", + "definitionName": { + "value": "GCM Sender ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 39, + "fullyQualifiedName": "MobilePush Demographics.GCM Sender ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": -1, + "ordinal": 39, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "GcmSenderId", + "valueDefinitionID": "0ab0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "GcmSenderId", + "name": "GCM Sender ID", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "0bb0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "AppVersion", + "definitionName": { + "value": "Application Version" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 40, + "fullyQualifiedName": "MobilePush Demographics.Application Version", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": -1, + "ordinal": 40, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "AppVersion", + "valueDefinitionID": "0bb0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "AppVersion", + "name": "Application Version", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "0cb0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "SdkVersion", + "definitionName": { + "value": "SDK Version" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 41, + "fullyQualifiedName": "MobilePush Demographics.SDK Version", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": -1, + "ordinal": 41, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "SdkVersion", + "valueDefinitionID": "0cb0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "SdkVersion", + "name": "SDK Version", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "0db0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "LastAppOpen", + "definitionName": { + "value": "Last Application Open" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 42, + "fullyQualifiedName": "MobilePush Demographics.Last Application Open", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 42, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "LastAppOpen", + "valueDefinitionID": "0db0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "LastAppOpen", + "name": "Last Application Open", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "0eb0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "LastMessageOpen", + "definitionName": { + "value": "Last Message Open" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 43, + "fullyQualifiedName": "MobilePush Demographics.Last Message Open", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 43, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "LastMessageOpen", + "valueDefinitionID": "0eb0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "LastMessageOpen", + "name": "Last Message Open", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "0fb0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "LastSend", + "definitionName": { + "value": "Last Send" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 44, + "fullyQualifiedName": "MobilePush Demographics.Last Send", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 44, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "LastSend", + "valueDefinitionID": "0fb0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "LastSend", + "name": "Last Send", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Number", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "10b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "SendCount", + "definitionName": { + "value": "Send Count" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 45, + "fullyQualifiedName": "MobilePush Demographics.Send Count", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 45, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "SendCount", + "valueDefinitionID": "10b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "SendCount", + "name": "Send Count", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Number", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "11b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "MessageOpenCount", + "definitionName": { + "value": "Message Open Count" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 46, + "fullyQualifiedName": "MobilePush Demographics.Message Open Count", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 46, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "MessageOpenCount", + "valueDefinitionID": "11b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "MessageOpenCount", + "name": "Message Open Count", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Boolean", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Boolean", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "12b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "ProximityEnabled", + "definitionName": { + "value": "Proximity Enabled" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 47, + "fullyQualifiedName": "MobilePush Demographics.Proximity Enabled", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 47, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ProximityEnabled", + "valueDefinitionID": "12b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "ProximityEnabled", + "name": "Proximity Enabled", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Boolean", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Boolean", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "13b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "BackgroundRefreshEnabled", + "definitionName": { + "value": "Background Refresh Enabled" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 48, + "fullyQualifiedName": "MobilePush Demographics.Background Refresh Enabled", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 48, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "BackgroundRefreshEnabled", + "valueDefinitionID": "13b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "BackgroundRefreshEnabled", + "name": "Background Refresh Enabled", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Boolean", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Boolean", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "14b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "definitionKey": "QuietPushEnabled", + "definitionName": { + "value": "Quiet Push Enabled" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 49, + "fullyQualifiedName": "MobilePush Demographics.Quiet Push Enabled", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 49, + "parentDefinition": { + "definitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDemographics", + "definitionName": { + "value": "MobilePush Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "QuietPushEnabled", + "valueDefinitionID": "14b0ae24-ee46-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "QuietPushEnabled", + "name": "Quiet Push Enabled", + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "setDefinitionName": { + "value": "MobilePush Demographics" + }, + "parentIdentifier": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "2051892d-5de2-4ecf-98af-8ca9a40d2c9c", + "applicationKey": "com.exacttarget.mobilepush", + "attributeCount": 0, + "canAddValues": true, + "canChangeValues": true, + "canModify": false, + "canRemove": false, + "categoryID": 2, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "MobilePush Demographics", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": false, + "isRoot": false, + "isSendable": true, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 3, + "sendAttributeStorageName": "_ContactID", + "sendContactKeyStorageName": "_SubscriberID", + "storageLogicalType": "PushAttributes", + "storageName": "_PushAddress", + "storageObjectIDs": [ + "4851de3f-31e2-e611-80cc-1402ec7222b4", + "9552de3f-31e2-e611-80cc-1402ec7222b4" + ], + "storageReferenceID": { + "type": "guid", + "value": "7893dc39-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "6d51de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushDemographics", + "name": "MobilePush Demographics" + }, + { + "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelSessionEnds", + "definitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7b86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Custom_Object_Key", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence Session Ends.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelSessionEnds", + "definitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "7b86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Custom_Object_Key", + "name": "Custom Object Key", + "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelSessionEnds", + "setDefinitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "user_id", + "localizedDescription": { + "value": "user_id" + }, + "definitionID": "7a86d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "user_id", + "definitionName": { + "value": "User Id" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence Session Ends.User Id", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7a86d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelSessionEnds", + "definitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "user_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "037a4978-3ce8-4311-95c3-b59d2e3f1a7f" + }, + "valueDefinitionID": "7a86d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "user_id", + "name": "User Id", + "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelSessionEnds", + "setDefinitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "session_id", + "localizedDescription": { + "value": "session_id" + }, + "definitionID": "7886d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "session_id", + "definitionName": { + "value": "Session Id" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence Session Ends.Session Id", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7886d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelSessionEnds", + "definitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "session_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "67b9fcff-4136-4b07-b5f6-e86d616e4136" + }, + "valueDefinitionID": "7886d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "session_id", + "name": "Session Id", + "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelSessionEnds", + "setDefinitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "email_address", + "localizedDescription": { + "value": "email_address" + }, + "definitionID": "7786d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "email_address", + "definitionName": { + "value": "Email Address" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence Session Ends.Email Address", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7786d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelSessionEnds", + "definitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "email_address", + "storageFieldReferenceID": { + "type": "guid", + "value": "8f1bc9c8-32a3-4b54-83aa-ffb6e56ec709" + }, + "valueDefinitionID": "7786d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "email_address", + "name": "Email Address", + "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelSessionEnds", + "setDefinitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "contact_key", + "localizedDescription": { + "value": "contact_key" + }, + "definitionID": "7686d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "contact_key", + "definitionName": { + "value": "Contact Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence Session Ends.Contact Key", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7686d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelSessionEnds", + "definitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "contact_key", + "storageFieldReferenceID": { + "type": "guid", + "value": "0dc0b53e-ce26-4508-89b2-f9cb0ab8404a" + }, + "valueDefinitionID": "7686d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "contact_key", + "name": "Contact Key", + "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelSessionEnds", + "setDefinitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "getdate()", + "description": "timestamp", + "localizedDescription": { + "value": "timestamp" + }, + "definitionID": "7986d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "timestamp", + "definitionName": { + "value": "Time stamp" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Predictive Intelligence Session Ends.Time stamp", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "7986d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelSessionEnds", + "definitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "timestamp", + "storageFieldReferenceID": { + "type": "guid", + "value": "0c87ce00-c3f1-4c88-b652-ba8dfc3cc10f" + }, + "valueDefinitionID": "7986d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "timestamp", + "name": "Time stamp", + "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelSessionEnds", + "setDefinitionName": { + "value": "Predictive Intelligence Session Ends" + }, + "parentIdentifier": "7586d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence Session Ends", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 0, + "storageLogicalType": "DataExtension", + "storageName": "PI_SESSION_ENDS", + "storageObjectIDs": ["6e86d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "d652de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "7586d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelSessionEnds", + "name": "Predictive Intelligence Session Ends" + }, + { + "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "GroupConnectLineAddress", + "definitionName": { + "value": "GroupConnect LINE Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": true, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "ab51de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeGroup" + }, + "leftRelationshipIDs": [ + { + "type": "int16", + "value": "2" + } + ], + "leftRelationshipReferenceType": "CustomerData", + "relationshipAttributes": [ + { + "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "7c86d247-3045-ea11-a2e0-1402ec94ec41", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "8686d247-3045-ea11-a2e0-1402ec94ec41", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "7b86d247-3045-ea11-a2e0-1402ec94ec41", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "a251de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "9386d247-3045-ea11-a2e0-1402ec94ec41", + "rightItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "7b86d247-3045-ea11-a2e0-1402ec94ec41", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "e651de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "a686d247-3045-ea11-a2e0-1402ec94ec41", + "rightItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Text", + "customerDataID": 8, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7b86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "AddressID", + "definitionName": { + "value": "Address ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "GroupConnect LINE Addresses.Address ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": 100, + "ordinal": 1, + "parentDefinition": { + "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "GroupConnectLineAddress", + "definitionName": { + "value": "GroupConnect LINE Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "AddressId", + "valueDefinitionID": "7b86d247-3045-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "AddressID", + "name": "Address ID", + "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "setDefinitionKey": "GroupConnectLineAddress", + "setDefinitionName": { + "value": "GroupConnect LINE Addresses" + }, + "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7c86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "ContactID", + "definitionName": { + "value": "Contact ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "GroupConnect LINE Addresses.Contact ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 2, + "parentDefinition": { + "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "GroupConnectLineAddress", + "definitionName": { + "value": "GroupConnect LINE Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ContactId", + "valueDefinitionID": "7c86d247-3045-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "ContactID", + "name": "Contact ID", + "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "setDefinitionKey": "GroupConnectLineAddress", + "setDefinitionName": { + "value": "GroupConnect LINE Addresses" + }, + "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7d86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "ContactKey", + "definitionName": { + "value": "Contact Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "GroupConnect LINE Addresses.Contact Key", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 100, + "ordinal": 3, + "parentDefinition": { + "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "GroupConnectLineAddress", + "definitionName": { + "value": "GroupConnect LINE Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ContactKey", + "valueDefinitionID": "7d86d247-3045-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "ContactKey", + "name": "Contact Key", + "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "setDefinitionKey": "GroupConnectLineAddress", + "setDefinitionName": { + "value": "GroupConnect LINE Addresses" + }, + "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" + }, + { + "baseType": "Boolean", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Boolean", + "defaultValue": "True", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7e86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "IsActive", + "definitionName": { + "value": "Is Active" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "GroupConnect LINE Addresses.Is Active", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 7, + "parentDefinition": { + "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "GroupConnectLineAddress", + "definitionName": { + "value": "GroupConnect LINE Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "IsActive", + "valueDefinitionID": "7e86d247-3045-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "IsActive", + "name": "Is Active", + "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "setDefinitionKey": "GroupConnectLineAddress", + "setDefinitionName": { + "value": "GroupConnect LINE Addresses" + }, + "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "7f86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "CreatedDate", + "definitionName": { + "value": "Created Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 8, + "fullyQualifiedName": "GroupConnect LINE Addresses.Created Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 8, + "parentDefinition": { + "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "GroupConnectLineAddress", + "definitionName": { + "value": "GroupConnect LINE Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "CreatedDate", + "valueDefinitionID": "7f86d247-3045-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "CreatedDate", + "name": "Created Date", + "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "setDefinitionKey": "GroupConnectLineAddress", + "setDefinitionName": { + "value": "GroupConnect LINE Addresses" + }, + "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8086d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "CreatedBy", + "definitionName": { + "value": "Created By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "GroupConnect LINE Addresses.Created By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 9, + "parentDefinition": { + "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "GroupConnectLineAddress", + "definitionName": { + "value": "GroupConnect LINE Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "CreatedBy", + "valueDefinitionID": "8086d247-3045-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "CreatedBy", + "name": "Created By", + "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "setDefinitionKey": "GroupConnectLineAddress", + "setDefinitionName": { + "value": "GroupConnect LINE Addresses" + }, + "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8186d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "ModifiedDate", + "definitionName": { + "value": "Modified Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "GroupConnect LINE Addresses.Modified Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 10, + "parentDefinition": { + "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "GroupConnectLineAddress", + "definitionName": { + "value": "GroupConnect LINE Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ModifiedDate", + "valueDefinitionID": "8186d247-3045-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "ModifiedDate", + "name": "Modified Date", + "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "setDefinitionKey": "GroupConnectLineAddress", + "setDefinitionName": { + "value": "GroupConnect LINE Addresses" + }, + "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8286d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "ModifiedBy", + "definitionName": { + "value": "Modified By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 11, + "fullyQualifiedName": "GroupConnect LINE Addresses.Modified By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 11, + "parentDefinition": { + "definitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "definitionKey": "GroupConnectLineAddress", + "definitionName": { + "value": "GroupConnect LINE Addresses" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ModifiedBy", + "valueDefinitionID": "8286d247-3045-ea11-a2e0-1402ec94ec41", + "valueDefinitionKey": "ModifiedBy", + "name": "Modified By", + "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "setDefinitionKey": "GroupConnectLineAddress", + "setDefinitionName": { + "value": "GroupConnect LINE Addresses" + }, + "parentIdentifier": "7a86d247-3045-ea11-a2e0-1402ec94ec41" + } + ], + "applicationID": "4e9519db-ad21-483a-a3fc-8ab4557eded1", + "applicationKey": "com.exacttarget.GroupConnect", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "createDate": "2020-02-01T14:20:00", + "localizedDescription": {}, + "fullyQualifiedName": "GroupConnect LINE Addresses", + "isCustomObjectBacked": false, + "isEvent": false, + "isHidden": false, + "isReadOnly": false, + "isRoot": false, + "isSendable": false, + "isSystemDefined": true, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 3, + "storageObjectIDs": ["9851de3f-31e2-e611-80cc-1402ec7222b4"], + "setDefinitionID": "7a86d247-3045-ea11-a2e0-1402ec94ec41", + "setDefinitionKey": "GroupConnectLineAddress", + "name": "GroupConnect LINE Addresses" + }, + { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": true, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "e152de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeGroup" + }, + "leftRelationshipIDs": [ + { + "type": "int16", + "value": "4" + } + ], + "leftRelationshipReferenceType": "CustomerData", + "relationshipAttributes": [ + { + "leftAttributeID": "1151de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "9174266c-c416-ec11-b839-48df37d1dc79", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "c80f6472-c416-ec11-b839-48df37d1dc79", + "rightItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "8574266c-c416-ec11-b839-48df37d1dc79", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "9274266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "_CustomObjectKey" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "fullyQualifiedName": "Einstein MC Predictive Scores._CustomObjectKey", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": false, + "isUpdateable": false, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "9274266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "CustomObjectKey", + "name": "_CustomObjectKey", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Text", + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "9174266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "Email Address", + "definitionName": { + "value": "Email Address" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 0, + "fullyQualifiedName": "Einstein MC Predictive Scores.Email Address", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "9174266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 0, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "email_address", + "storageFieldReferenceID": { + "type": "guid", + "value": "29554274-39da-460d-b721-15badcd533e0" + }, + "valueDefinitionID": "9174266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "Email Address", + "name": "Email Address", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Text", + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8b74266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "Email Open Likelihood", + "definitionName": { + "value": "Email Open Likelihood" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Einstein MC Predictive Scores.Email Open Likelihood", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8b74266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "EmailOpenLikelihood", + "storageFieldReferenceID": { + "type": "guid", + "value": "6a64b510-d27a-4d35-9bb4-23760adaa1f4" + }, + "valueDefinitionID": "8b74266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "Email Open Likelihood", + "name": "Email Open Likelihood", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Text", + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8d74266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "Email Click Likelihood", + "definitionName": { + "value": "Email Click Likelihood" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Einstein MC Predictive Scores.Email Click Likelihood", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8d74266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "EmailClickLikelihood", + "storageFieldReferenceID": { + "type": "guid", + "value": "6602de48-581e-497a-afae-2f97434db9b4" + }, + "valueDefinitionID": "8d74266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "Email Click Likelihood", + "name": "Email Click Likelihood", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Numeric", + "dataSourceName": {}, + "dataType": "Decimal", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8f74266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "Email Open Score", + "definitionName": { + "value": "Email Open Score" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Einstein MC Predictive Scores.Email Open Score", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8f74266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 4, + "storageName": "EmailOpenScore", + "storageFieldReferenceID": { + "type": "guid", + "value": "5e315b7d-7135-4ffc-8520-8c9ec91e33fa" + }, + "valueDefinitionID": "8f74266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "Email Open Score", + "name": "Email Open Score", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Text", + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8774266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "Email Subscribe Likelihood", + "definitionName": { + "value": "Email Subscribe Likelihood" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Einstein MC Predictive Scores.Email Subscribe Likelihood", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8774266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "EmailSubscribeLikelihood", + "storageFieldReferenceID": { + "type": "guid", + "value": "be9bdd26-6875-4c1d-b9cc-64667e9155aa" + }, + "valueDefinitionID": "8774266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "Email Subscribe Likelihood", + "name": "Email Subscribe Likelihood", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Numeric", + "dataSourceName": {}, + "dataType": "Decimal", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8e74266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EmailClickScore", + "definitionName": { + "value": "EmailClickScore" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Einstein MC Predictive Scores.EmailClickScore", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8e74266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 4, + "storageName": "EmailClickScore", + "storageFieldReferenceID": { + "type": "guid", + "value": "64515ffd-067d-4abe-9a4e-c72eb303db0b" + }, + "valueDefinitionID": "8e74266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "EmailClickScore", + "name": "EmailClickScore", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Numeric", + "dataSourceName": {}, + "dataType": "Decimal", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8674266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "Email Subscribe Score", + "definitionName": { + "value": "Email Subscribe Score" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Einstein MC Predictive Scores.Email Subscribe Score", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8674266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 4, + "storageName": "EmailSubscribeScore", + "storageFieldReferenceID": { + "type": "guid", + "value": "d392d512-6c6e-40dd-8bbf-a50c36321372" + }, + "valueDefinitionID": "8674266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "Email Subscribe Score", + "name": "Email Subscribe Score", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Text", + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8c74266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EmailEngagementPersona", + "definitionName": { + "value": "EmailEngagementPersona" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "Einstein MC Predictive Scores.EmailEngagementPersona", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8c74266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 7, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "EmailEngagementPersona", + "storageFieldReferenceID": { + "type": "guid", + "value": "67b5a098-1374-4d0a-9ffa-ad9a465eac66" + }, + "valueDefinitionID": "8c74266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "EmailEngagementPersona", + "name": "EmailEngagementPersona", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Text", + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8974266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "Conversion Likelihood", + "definitionName": { + "value": "Conversion Likelihood" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 8, + "fullyQualifiedName": "Einstein MC Predictive Scores.Conversion Likelihood", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8974266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 8, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ConversionLikelihood", + "storageFieldReferenceID": { + "type": "guid", + "value": "a293ae7a-dc35-462d-8909-32eccc22fc58" + }, + "valueDefinitionID": "8974266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "Conversion Likelihood", + "name": "Conversion Likelihood", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Numeric", + "dataSourceName": {}, + "dataType": "Decimal", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8a74266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "Conversion Score", + "definitionName": { + "value": "Conversion Score" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "Einstein MC Predictive Scores.Conversion Score", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8a74266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 9, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 4, + "storageName": "ConversionScore", + "storageFieldReferenceID": { + "type": "guid", + "value": "75a99602-df46-4fcc-a731-1b56c0d24d0e" + }, + "valueDefinitionID": "8a74266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "Conversion Score", + "name": "Conversion Score", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Date", + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "getdate()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "9074266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "Updated Date", + "definitionName": { + "value": "Updated Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "Einstein MC Predictive Scores.Updated Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "9074266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 10, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 4, + "storageName": "UpdatedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "4457d74f-2c14-4a3f-baf2-2cc34cf8858b" + }, + "valueDefinitionID": "9074266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "Updated Date", + "name": "Updated Date", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + { + "baseType": "Date", + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "getdate()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8874266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "Created Date", + "definitionName": { + "value": "Created Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 11, + "fullyQualifiedName": "Einstein MC Predictive Scores.Created Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8874266c-c416-ec11-b839-48df37d1dc79" + }, + "ordinal": 11, + "parentDefinition": { + "definitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "definitionKey": "EinsteinMCPredictiveScores", + "definitionName": { + "value": "Einstein MC Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 4, + "storageName": "CreatedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "a4852a5f-2952-4648-911a-452533298dab" + }, + "valueDefinitionID": "8874266c-c416-ec11-b839-48df37d1dc79", + "valueDefinitionKey": "Created Date", + "name": "Created Date", + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "setDefinitionName": { + "value": "Einstein MC Predictive Scores" + }, + "parentIdentifier": "8574266c-c416-ec11-b839-48df37d1dc79" + } + ], + "applicationID": "aed181bc-d7b7-465e-a3dd-9cdfb13943e2", + "applicationKey": "com.sfmc-einstein.Einstein Engagement Scoring", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 2, + "createdBy": -1000, + "createDate": "2021-09-16T02:03:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Einstein MC Predictive Scores", + "isCustomObjectBacked": false, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 1, + "storageLogicalType": "ExactTargetSchema", + "storageName": "Einstein_MC_Predictive_Scores", + "storageObjectIDs": ["c90f6472-c416-ec11-b839-48df37d1dc79"], + "storageReferenceID": { + "type": "guid", + "value": "e5ca7d21-aba6-e811-a2bf-1402ec94ecf1" + }, + "setDefinitionID": "8574266c-c416-ec11-b839-48df37d1dc79", + "setDefinitionKey": "EinsteinMCPredictiveScores", + "name": "Einstein MC Predictive Scores" + }, + { + "definitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Contact", + "definitionName": { + "value": "Contact" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": true, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "8f93dc39-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeGroup" + }, + "leftRelationshipIDs": [ + { + "type": "int16", + "value": "2" + } + ], + "leftRelationshipReferenceType": "CustomerData", + "relationshipAttributes": [ + { + "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "9893dc39-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "9093dc39-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "customerDataID": 2, + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Number", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "9293dc39-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ContactID", + "definitionName": { + "value": "Contact ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "fullyQualifiedName": "Contact.Contact ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "parentDefinition": { + "definitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Contact", + "definitionName": { + "value": "Contact" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "SubscriberID", + "valueDefinitionID": "9293dc39-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ContactID", + "name": "Contact ID", + "setDefinitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "Contact", + "setDefinitionName": { + "value": "Contact" + }, + "parentIdentifier": "9093dc39-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "customerDataID": 3, + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "9393dc39-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ContactKey", + "definitionName": { + "value": "Contact Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "fullyQualifiedName": "Contact.Contact Key", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": -1, + "parentDefinition": { + "definitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Contact", + "definitionName": { + "value": "Contact" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "SubscriberKey", + "valueDefinitionID": "9393dc39-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ContactKey", + "name": "Contact Key", + "setDefinitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "Contact", + "setDefinitionName": { + "value": "Contact" + }, + "parentIdentifier": "9093dc39-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "customerDataID": 1, + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Number", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "9193dc39-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "BusinessUnitID", + "definitionName": { + "value": "Business Unit ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "fullyQualifiedName": "Contact.Business Unit ID", + "isHidden": true, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "parentDefinition": { + "definitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Contact", + "definitionName": { + "value": "Contact" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ClientID", + "valueDefinitionID": "9193dc39-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "BusinessUnitID", + "name": "Business Unit ID", + "setDefinitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "Contact", + "setDefinitionName": { + "value": "Contact" + }, + "parentIdentifier": "9093dc39-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "ce703ed3-e01f-4f5f-900d-76a95b363e29", + "applicationKey": "com.exacttarget.contacts", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "localizedDescription": {}, + "fullyQualifiedName": "Contact", + "isCustomObjectBacked": false, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isSystemDefined": true, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 1, + "storageObjectIDs": ["2ba72136-9f31-4a79-ab62-4ba5d19cd759"], + "setDefinitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "Contact", + "name": "Contact" + }, + { + "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineDemographics", + "definitionName": { + "value": "GroupConnect LINE Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "valueDefinitions": [ + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "a251de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "AddressID", + "definitionName": { + "value": "Address ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "GroupConnect LINE Demographics.Address ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": 100, + "ordinal": 1, + "parentDefinition": { + "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineDemographics", + "definitionName": { + "value": "GroupConnect LINE Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "AddressId", + "valueDefinitionID": "a251de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "AddressID", + "name": "Address ID", + "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineDemographics", + "setDefinitionName": { + "value": "GroupConnect LINE Demographics" + }, + "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "da51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "DisplayName", + "definitionName": { + "value": "Display Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "GroupConnect LINE Demographics.Display Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "ordinal": 2, + "parentDefinition": { + "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineDemographics", + "definitionName": { + "value": "GroupConnect LINE Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "DisplayName", + "valueDefinitionID": "da51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "DisplayName", + "name": "Display Name", + "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineDemographics", + "setDefinitionName": { + "value": "GroupConnect LINE Demographics" + }, + "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "db51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PictureUrl", + "definitionName": { + "value": "Picture Url" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "GroupConnect LINE Demographics.Picture Url", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "ordinal": 3, + "parentDefinition": { + "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineDemographics", + "definitionName": { + "value": "GroupConnect LINE Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "PictureUrl", + "valueDefinitionID": "db51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "PictureUrl", + "name": "Picture Url", + "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineDemographics", + "setDefinitionName": { + "value": "GroupConnect LINE Demographics" + }, + "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "dc51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "StatusMessage", + "definitionName": { + "value": "Status Message" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "GroupConnect LINE Demographics.Status Message", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "ordinal": 4, + "parentDefinition": { + "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineDemographics", + "definitionName": { + "value": "GroupConnect LINE Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "StatusMessage", + "valueDefinitionID": "dc51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "StatusMessage", + "name": "Status Message", + "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineDemographics", + "setDefinitionName": { + "value": "GroupConnect LINE Demographics" + }, + "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "a651de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedDate", + "definitionName": { + "value": "Created Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 8, + "fullyQualifiedName": "GroupConnect LINE Demographics.Created Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 8, + "parentDefinition": { + "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineDemographics", + "definitionName": { + "value": "GroupConnect LINE Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "CreatedDate", + "valueDefinitionID": "a651de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedDate", + "name": "Created Date", + "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineDemographics", + "setDefinitionName": { + "value": "GroupConnect LINE Demographics" + }, + "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "a751de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedBy", + "definitionName": { + "value": "Created By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "GroupConnect LINE Demographics.Created By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 9, + "parentDefinition": { + "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineDemographics", + "definitionName": { + "value": "GroupConnect LINE Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "CreatedBy", + "valueDefinitionID": "a751de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedBy", + "name": "Created By", + "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineDemographics", + "setDefinitionName": { + "value": "GroupConnect LINE Demographics" + }, + "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "a851de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedDate", + "definitionName": { + "value": "Modified Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "GroupConnect LINE Demographics.Modified Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 10, + "parentDefinition": { + "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineDemographics", + "definitionName": { + "value": "GroupConnect LINE Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ModifiedDate", + "valueDefinitionID": "a851de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedDate", + "name": "Modified Date", + "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineDemographics", + "setDefinitionName": { + "value": "GroupConnect LINE Demographics" + }, + "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "a951de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedBy", + "definitionName": { + "value": "Modified By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 11, + "fullyQualifiedName": "GroupConnect LINE Demographics.Modified By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 11, + "parentDefinition": { + "definitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineDemographics", + "definitionName": { + "value": "GroupConnect LINE Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ModifiedBy", + "valueDefinitionID": "a951de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedBy", + "name": "Modified By", + "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineDemographics", + "setDefinitionName": { + "value": "GroupConnect LINE Demographics" + }, + "parentIdentifier": "a151de3f-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "4e9519db-ad21-483a-a3fc-8ab4557eded1", + "applicationKey": "com.exacttarget.GroupConnect", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "localizedDescription": {}, + "fullyQualifiedName": "GroupConnect LINE Demographics", + "isCustomObjectBacked": false, + "isEvent": false, + "isHidden": false, + "isReadOnly": false, + "isRoot": false, + "isSendable": false, + "isSystemDefined": true, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 0, + "storageObjectIDs": [ + "9851de3f-31e2-e611-80cc-1402ec7222b4", + "d351de3f-31e2-e611-80cc-1402ec7222b4" + ], + "setDefinitionID": "a151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineDemographics", + "name": "GroupConnect LINE Demographics" + }, + { + "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelScores", + "definitionName": { + "value": "Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": true, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "e152de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeGroup" + }, + "leftRelationshipIDs": [ + { + "type": "int16", + "value": "3" + } + ], + "leftRelationshipReferenceType": "CustomerData", + "relationshipAttributes": [ + { + "leftAttributeID": "9393dc39-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "a585d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "a985d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "a185d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "a785d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Scores.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelScores", + "definitionName": { + "value": "Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "a785d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelScores", + "setDefinitionName": { + "value": "Predictive Scores" + }, + "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "subscriber_key", + "localizedDescription": { + "value": "subscriber_key" + }, + "definitionID": "a585d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Subscriber Key", + "definitionName": { + "value": "Subscriber Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Scores.Subscriber Key", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "a585d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelScores", + "definitionName": { + "value": "Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "subscriber_key", + "storageFieldReferenceID": { + "type": "guid", + "value": "f6ce2639-bfff-40c0-835c-9fa89e627592" + }, + "valueDefinitionID": "a585d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Subscriber Key", + "name": "Subscriber Key", + "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelScores", + "setDefinitionName": { + "value": "Predictive Scores" + }, + "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "goal_name", + "localizedDescription": { + "value": "goal_name" + }, + "definitionID": "a285d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Goal Name", + "definitionName": { + "value": "Goal Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Scores.Goal Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "a285d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelScores", + "definitionName": { + "value": "Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "goal_name", + "storageFieldReferenceID": { + "type": "guid", + "value": "62f73dda-4116-4fdd-ae38-a5cb74fafc6b" + }, + "valueDefinitionID": "a285d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Goal Name", + "name": "Goal Name", + "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelScores", + "setDefinitionName": { + "value": "Predictive Scores" + }, + "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "goal_name_key", + "localizedDescription": { + "value": "goal_name_key" + }, + "definitionID": "a385d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Goal Name Key", + "definitionName": { + "value": "Goal Name Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Scores.Goal Name Key", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "a385d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelScores", + "definitionName": { + "value": "Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "goal_name_key", + "storageFieldReferenceID": { + "type": "guid", + "value": "5c34b4cc-5d35-460e-a0b7-ba8e349d725b" + }, + "valueDefinitionID": "a385d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Goal Name Key", + "name": "Goal Name Key", + "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelScores", + "setDefinitionName": { + "value": "Predictive Scores" + }, + "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Decimal", + "description": "score", + "localizedDescription": { + "value": "score" + }, + "definitionID": "a485d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Score", + "definitionName": { + "value": "Score" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Scores.Score", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "a485d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelScores", + "definitionName": { + "value": "Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 4, + "storageName": "score", + "storageFieldReferenceID": { + "type": "guid", + "value": "8baf5deb-f215-4984-9d91-6e05b88c2f94" + }, + "valueDefinitionID": "a485d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Score", + "name": "Score", + "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelScores", + "setDefinitionName": { + "value": "Predictive Scores" + }, + "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Date", + "description": "updated_at", + "localizedDescription": { + "value": "updated_at" + }, + "definitionID": "a685d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Updated At", + "definitionName": { + "value": "Updated At" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Predictive Scores.Updated At", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "a685d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelScores", + "definitionName": { + "value": "Predictive Scores" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "updated_at", + "storageFieldReferenceID": { + "type": "guid", + "value": "d6fefe2f-e2d5-42bb-bee2-5dd8da16b8e4" + }, + "valueDefinitionID": "a685d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Updated At", + "name": "Updated At", + "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelScores", + "setDefinitionName": { + "value": "Predictive Scores" + }, + "parentIdentifier": "a185d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Scores", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 1, + "storageLogicalType": "DataExtension", + "storageName": "PREDICTIVE_SCORES", + "storageObjectIDs": ["9a85d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "de52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "a185d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelScores", + "name": "Predictive Scores" + }, + { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": true, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "b451de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeGroup" + }, + "leftRelationshipIDs": [ + { + "type": "int16", + "value": "2" + } + ], + "leftRelationshipReferenceType": "CustomerData", + "relationshipAttributes": [ + { + "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "b351de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "b751de3f-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b351de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ContactsID", + "definitionName": { + "value": "Contacts ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 0, + "fullyQualifiedName": "Email Demographics.Contacts ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": true, + "ordinal": 0, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_SubscriberID", + "valueDefinitionID": "b351de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ContactsID", + "name": "Contacts ID", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b4e96cfc-85f7-e611-80cc-1402ec7222b4", + "definitionKey": "First Name", + "definitionName": { + "value": "First Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Email Demographics.First Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b4e96cfc-85f7-e611-80cc-1402ec7222b4" + }, + "ordinal": 1, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "First Name", + "storageFieldReferenceID": { + "type": "guid", + "value": "eef81ae9-14e8-47b3-bede-5a691614c7c3" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10025" + }, + "valueDefinitionID": "b4e96cfc-85f7-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "First Name", + "name": "First Name", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b6e96cfc-85f7-e611-80cc-1402ec7222b4", + "definitionKey": "Last Name", + "definitionName": { + "value": "Last Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Email Demographics.Last Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b6e96cfc-85f7-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Last Name", + "storageFieldReferenceID": { + "type": "guid", + "value": "4434d534-4fb8-4ec4-9ffc-fe386781f8ef" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10026" + }, + "valueDefinitionID": "b6e96cfc-85f7-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Last Name", + "name": "Last Name", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b2e96cfc-85f7-e611-80cc-1402ec7222b4", + "definitionKey": "Language", + "definitionName": { + "value": "Language" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Email Demographics.Language", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 50, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b2e96cfc-85f7-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Language", + "storageFieldReferenceID": { + "type": "guid", + "value": "4b06d940-5f23-461f-859d-9c2aeee53525" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10027" + }, + "valueDefinitionID": "b2e96cfc-85f7-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Language", + "name": "Language", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "720e6c78-9709-e711-80cc-1402ec7222b4", + "definitionKey": "Transaction Points1", + "definitionName": { + "value": "Transaction Points" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Email Demographics.Transaction Points", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "720e6c78-9709-e711-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Transaction Points", + "storageFieldReferenceID": { + "type": "guid", + "value": "fdcb28a8-59fd-489a-bdce-b286bccc147e" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10033" + }, + "valueDefinitionID": "720e6c78-9709-e711-80cc-1402ec7222b4", + "valueDefinitionKey": "Transaction Points1", + "name": "Transaction Points", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "f05cc16f-8a14-e711-80cc-1402ec7222b4", + "definitionKey": "Market", + "definitionName": { + "value": "Market" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "Email Demographics.Market", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 50, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f05cc16f-8a14-e711-80cc-1402ec7222b4" + }, + "ordinal": 7, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Market", + "storageFieldReferenceID": { + "type": "guid", + "value": "d6f80d57-488f-401b-822b-1b556d631d1c" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10034" + }, + "valueDefinitionID": "f05cc16f-8a14-e711-80cc-1402ec7222b4", + "valueDefinitionKey": "Market", + "name": "Market", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "32c8b204-85ff-e711-80d0-1402ec7222b5", + "definitionKey": "SFOrg", + "definitionName": { + "value": "SFOrg" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 8, + "fullyQualifiedName": "Email Demographics.SFOrg", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 50, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "32c8b204-85ff-e711-80d0-1402ec7222b5" + }, + "ordinal": 8, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "SFOrg", + "storageFieldReferenceID": { + "type": "guid", + "value": "5d1032d3-5c92-4de4-bfb8-0e377f4483e2" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10081" + }, + "valueDefinitionID": "32c8b204-85ff-e711-80d0-1402ec7222b5", + "valueDefinitionKey": "SFOrg", + "name": "SFOrg", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "8775d770-e194-e911-a2cf-1402ec94ecf1", + "definitionKey": "Username", + "definitionName": { + "value": "Username" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "Email Demographics.Username", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 255, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "8775d770-e194-e911-a2cf-1402ec94ecf1" + }, + "ordinal": 9, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Username", + "storageFieldReferenceID": { + "type": "guid", + "value": "55ac244c-2afd-4134-8495-9c1c188debdc" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10299" + }, + "valueDefinitionID": "8775d770-e194-e911-a2cf-1402ec94ecf1", + "valueDefinitionKey": "Username", + "name": "Username", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "570dea88-6e94-ea11-a2e5-1402ec9386e5", + "definitionKey": "Account Id", + "definitionName": { + "value": "Account Id" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "Email Demographics.Account Id", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 50, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "570dea88-6e94-ea11-a2e5-1402ec9386e5" + }, + "ordinal": 10, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Account Id", + "storageFieldReferenceID": { + "type": "guid", + "value": "eb2f7e92-f7f8-435c-835a-3c24d5e003d5" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10334" + }, + "valueDefinitionID": "570dea88-6e94-ea11-a2e5-1402ec9386e5", + "valueDefinitionKey": "Account Id", + "name": "Account Id", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "74c1c047-9e94-ea11-a2e5-1402ec9386e5", + "definitionKey": "AccountId", + "definitionName": { + "value": "AccountId" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "Email Demographics.AccountId", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 50, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "74c1c047-9e94-ea11-a2e5-1402ec9386e5" + }, + "ordinal": 10, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Account Id", + "storageFieldReferenceID": { + "type": "guid", + "value": "eb2f7e92-f7f8-435c-835a-3c24d5e003d5" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10334" + }, + "valueDefinitionID": "74c1c047-9e94-ea11-a2e5-1402ec9386e5", + "valueDefinitionKey": "AccountId", + "name": "AccountId", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "560dea88-6e94-ea11-a2e5-1402ec9386e5", + "definitionKey": "Preferred language", + "definitionName": { + "value": "Preferred language" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 12, + "fullyQualifiedName": "Email Demographics.Preferred language", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 50, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "560dea88-6e94-ea11-a2e5-1402ec9386e5" + }, + "ordinal": 12, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Preferred language", + "storageFieldReferenceID": { + "type": "guid", + "value": "be1fac02-93ef-4c9e-b06d-22757e1aeda8" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10336" + }, + "valueDefinitionID": "560dea88-6e94-ea11-a2e5-1402ec9386e5", + "valueDefinitionKey": "Preferred language", + "name": "Preferred language", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "550dea88-6e94-ea11-a2e5-1402ec9386e5", + "definitionKey": "Flex Parameter 1", + "definitionName": { + "value": "Flex Parameter 1" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 13, + "fullyQualifiedName": "Email Demographics.Flex Parameter 1", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "550dea88-6e94-ea11-a2e5-1402ec9386e5" + }, + "ordinal": 13, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Flex Parameter 1", + "storageFieldReferenceID": { + "type": "guid", + "value": "96436704-494e-4bb1-914a-3ad6994bbf2d" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10337" + }, + "valueDefinitionID": "550dea88-6e94-ea11-a2e5-1402ec9386e5", + "valueDefinitionKey": "Flex Parameter 1", + "name": "Flex Parameter 1", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "866d4451-7d94-ea11-a2e5-1402ec9386e5", + "definitionKey": "Flex Parameter 2", + "definitionName": { + "value": "Flex Parameter 2" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 14, + "fullyQualifiedName": "Email Demographics.Flex Parameter 2", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "866d4451-7d94-ea11-a2e5-1402ec9386e5" + }, + "ordinal": 14, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Flex Parameter 2", + "storageFieldReferenceID": { + "type": "guid", + "value": "02a5b26c-05f6-426b-8735-de6033503f8f" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10338" + }, + "valueDefinitionID": "866d4451-7d94-ea11-a2e5-1402ec9386e5", + "valueDefinitionKey": "Flex Parameter 2", + "name": "Flex Parameter 2", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "876d4451-7d94-ea11-a2e5-1402ec9386e5", + "definitionKey": "Flex Parameter 3", + "definitionName": { + "value": "Flex Parameter 3" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 15, + "fullyQualifiedName": "Email Demographics.Flex Parameter 3", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "876d4451-7d94-ea11-a2e5-1402ec9386e5" + }, + "ordinal": 15, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Flex Parameter 3", + "storageFieldReferenceID": { + "type": "guid", + "value": "058f7489-c272-466c-88ce-b528b5b17955" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10339" + }, + "valueDefinitionID": "876d4451-7d94-ea11-a2e5-1402ec9386e5", + "valueDefinitionKey": "Flex Parameter 3", + "name": "Flex Parameter 3", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "886d4451-7d94-ea11-a2e5-1402ec9386e5", + "definitionKey": "Flex Parameter 4", + "definitionName": { + "value": "Flex Parameter 4" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 16, + "fullyQualifiedName": "Email Demographics.Flex Parameter 4", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "886d4451-7d94-ea11-a2e5-1402ec9386e5" + }, + "ordinal": 16, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Flex Parameter 4", + "storageFieldReferenceID": { + "type": "guid", + "value": "2702b318-539d-4fe3-9c52-c7ba3e32a949" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10340" + }, + "valueDefinitionID": "886d4451-7d94-ea11-a2e5-1402ec9386e5", + "valueDefinitionKey": "Flex Parameter 4", + "name": "Flex Parameter 4", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 2, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "1a4f88cd-a194-ea11-a2e5-1402ec9386e5", + "definitionKey": "Contact Role", + "definitionName": { + "value": "Contact Role" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 17, + "fullyQualifiedName": "Email Demographics.Contact Role", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "1a4f88cd-a194-ea11-a2e5-1402ec9386e5" + }, + "ordinal": 17, + "parentDefinition": { + "definitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "EmailDemographics", + "definitionName": { + "value": "Email Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Contact Role", + "storageFieldReferenceID": { + "type": "guid", + "value": "f3412d1f-bf50-4e3a-8db8-7e1bc15e019b" + }, + "storageFieldValueID": { + "type": "int32", + "value": "10341" + }, + "valueDefinitionID": "1a4f88cd-a194-ea11-a2e5-1402ec9386e5", + "valueDefinitionKey": "Contact Role", + "name": "Contact Role", + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "setDefinitionName": { + "value": "Email Demographics" + }, + "parentIdentifier": "b151de3f-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "b2ca1f50-3cc4-4fd7-a3a3-88bf09fb59fa", + "applicationKey": "com.exacttarget.email", + "attributeCount": 0, + "canAddValues": true, + "canChangeValues": true, + "canModify": false, + "canRemove": false, + "categoryID": 2, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 0, + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Email Demographics", + "isCustomObjectBacked": false, + "isEvent": false, + "isHidden": false, + "isReadOnly": false, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 1, + "storageLogicalType": "EnterpriseAttributes", + "storageName": "_EnterpriseAttribute", + "storageObjectIDs": ["b051de3f-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "1ba7e67d-2647-4537-beb3-b0c5bac65d3c" + }, + "setDefinitionID": "b151de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "EmailDemographics", + "name": "Email Demographics" + }, + { + "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductViews", + "definitionName": { + "value": "Predictive Intelligence Product Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "b285d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "b485d645-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "7886d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "7d86d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "7586d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "b285d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "b585d645-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "c885d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "cd85d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "c485d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b885d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence Product Views.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductViews", + "definitionName": { + "value": "Predictive Intelligence Product Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "b885d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductViews", + "setDefinitionName": { + "value": "Predictive Intelligence Product Views" + }, + "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "sku", + "localizedDescription": { + "value": "sku" + }, + "definitionID": "b585d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "SKU", + "definitionName": { + "value": "SKU" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence Product Views.SKU", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b585d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductViews", + "definitionName": { + "value": "Predictive Intelligence Product Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "sku", + "storageFieldReferenceID": { + "type": "guid", + "value": "f8553b64-8076-449d-aea0-450aed1a793c" + }, + "valueDefinitionID": "b585d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "SKU", + "name": "SKU", + "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductViews", + "setDefinitionName": { + "value": "Predictive Intelligence Product Views" + }, + "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "user_id", + "localizedDescription": { + "value": "user_id" + }, + "definitionID": "b785d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "User_ID", + "definitionName": { + "value": "User ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence Product Views.User ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b785d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductViews", + "definitionName": { + "value": "Predictive Intelligence Product Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "user_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "f8e9c116-3218-4064-92e4-dcccaf730a4f" + }, + "valueDefinitionID": "b785d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "User_ID", + "name": "User ID", + "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductViews", + "setDefinitionName": { + "value": "Predictive Intelligence Product Views" + }, + "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "session_id", + "localizedDescription": { + "value": "session_id" + }, + "definitionID": "b485d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Session_ID", + "definitionName": { + "value": "Session ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence Product Views.Session ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b485d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductViews", + "definitionName": { + "value": "Predictive Intelligence Product Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "session_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "bbca44f6-6353-464d-aba1-4285ae5072b6" + }, + "valueDefinitionID": "b485d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Session_ID", + "name": "Session ID", + "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductViews", + "setDefinitionName": { + "value": "Predictive Intelligence Product Views" + }, + "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Search", + "localizedDescription": { + "value": "Search" + }, + "definitionID": "b385d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Search", + "definitionName": { + "value": "Search" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence Product Views.Search", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 1000, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b385d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductViews", + "definitionName": { + "value": "Predictive Intelligence Product Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Search", + "storageFieldReferenceID": { + "type": "guid", + "value": "68949690-06d5-452d-b4c7-b8daab2f3681" + }, + "valueDefinitionID": "b385d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Search", + "name": "Search", + "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductViews", + "setDefinitionName": { + "value": "Predictive Intelligence Product Views" + }, + "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Date", + "description": "Timestamp", + "localizedDescription": { + "value": "Timestamp" + }, + "definitionID": "b685d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Timestamp", + "definitionName": { + "value": "Timestamp" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Predictive Intelligence Product Views.Timestamp", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b685d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductViews", + "definitionName": { + "value": "Predictive Intelligence Product Views" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Timestamp", + "storageFieldReferenceID": { + "type": "guid", + "value": "4fb7775d-277f-4f87-ba60-da24b120ba49" + }, + "valueDefinitionID": "b685d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Timestamp", + "name": "Timestamp", + "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductViews", + "setDefinitionName": { + "value": "Predictive Intelligence Product Views" + }, + "parentIdentifier": "b285d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence Product Views", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 2, + "storageLogicalType": "DataExtension", + "storageName": "IGO_VIEWS", + "storageObjectIDs": ["ab85d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "d552de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "b285d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductViews", + "name": "Predictive Intelligence Product Views" + }, + { + "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushSubscriptions", + "definitionName": { + "value": "MobilePush Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "valueDefinitions": [ + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushAppID", + "definitionName": { + "value": "Application" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "MobilePush Subscriptions.Application", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 38, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b452de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushSubscriptions", + "definitionName": { + "value": "MobilePush Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 11, + "storageName": "_APID", + "storageFieldReferenceID": { + "type": "guid", + "value": "4e82734e-ff8a-4868-a786-20e9596a94d2" + }, + "valueDefinitionID": "b452de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "PushAppID", + "name": "Application", + "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushSubscriptions", + "setDefinitionName": { + "value": "MobilePush Subscriptions" + }, + "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "bb52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "MobilePush Subscriptions.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 9, + "parentDefinition": { + "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushSubscriptions", + "definitionName": { + "value": "MobilePush Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "bb52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushSubscriptions", + "setDefinitionName": { + "value": "MobilePush Subscriptions" + }, + "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b552de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDeviceID", + "definitionName": { + "value": "Device ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 11, + "fullyQualifiedName": "MobilePush Subscriptions.Device ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b552de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 11, + "parentDefinition": { + "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushSubscriptions", + "definitionName": { + "value": "MobilePush Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_DeviceID", + "storageFieldReferenceID": { + "type": "guid", + "value": "9d8db1d4-c00e-49bc-98d9-e30d2e3ed7cf" + }, + "valueDefinitionID": "b552de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "PushDeviceID", + "name": "Device ID", + "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushSubscriptions", + "setDefinitionName": { + "value": "MobilePush Subscriptions" + }, + "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInDate", + "definitionName": { + "value": "Opt In Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 20, + "fullyQualifiedName": "MobilePush Subscriptions.Opt In Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b652de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 20, + "parentDefinition": { + "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushSubscriptions", + "definitionName": { + "value": "MobilePush Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptInDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "68c6681d-6f0f-4ec2-9407-55c5eb19fc19" + }, + "valueDefinitionID": "b652de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInDate", + "name": "Opt In Date", + "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushSubscriptions", + "setDefinitionName": { + "value": "MobilePush Subscriptions" + }, + "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b752de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInMethodID", + "definitionName": { + "value": "Opt In Method" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 21, + "fullyQualifiedName": "MobilePush Subscriptions.Opt In Method", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b752de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 21, + "parentDefinition": { + "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushSubscriptions", + "definitionName": { + "value": "MobilePush Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 9, + "storageName": "_OptInMethodID", + "storageFieldReferenceID": { + "type": "guid", + "value": "8b821a18-6cee-4204-9ef9-18d94112e84f" + }, + "valueDefinitionID": "b752de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInMethodID", + "name": "Opt In Method", + "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushSubscriptions", + "setDefinitionName": { + "value": "MobilePush Subscriptions" + }, + "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b852de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInStatusID", + "definitionName": { + "value": "Opt In Status" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 22, + "fullyQualifiedName": "MobilePush Subscriptions.Opt In Status", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b852de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 22, + "parentDefinition": { + "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushSubscriptions", + "definitionName": { + "value": "MobilePush Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 8, + "storageName": "_OptInStatusID", + "storageFieldReferenceID": { + "type": "guid", + "value": "673470b8-8503-4c4c-b9ae-9bf554d0a235" + }, + "valueDefinitionID": "b852de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInStatusID", + "name": "Opt In Status", + "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushSubscriptions", + "setDefinitionName": { + "value": "MobilePush Subscriptions" + }, + "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "b952de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptOutDate", + "definitionName": { + "value": "Opt Out Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 23, + "fullyQualifiedName": "MobilePush Subscriptions.Opt Out Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "b952de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 23, + "parentDefinition": { + "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushSubscriptions", + "definitionName": { + "value": "MobilePush Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptOutDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "8424262e-6904-4915-a4b3-2957b044b3ee" + }, + "valueDefinitionID": "b952de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptOutDate", + "name": "Opt Out Date", + "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushSubscriptions", + "setDefinitionName": { + "value": "MobilePush Subscriptions" + }, + "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "ba52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptOutMethodID", + "definitionName": { + "value": "Opt Out Method" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 24, + "fullyQualifiedName": "MobilePush Subscriptions.Opt Out Method", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "ba52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 24, + "parentDefinition": { + "definitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushSubscriptions", + "definitionName": { + "value": "MobilePush Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 10, + "storageName": "_OptOutMethodID", + "storageFieldReferenceID": { + "type": "guid", + "value": "3919bba5-e953-435d-8874-66be31cb1821" + }, + "valueDefinitionID": "ba52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptOutMethodID", + "name": "Opt Out Method", + "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushSubscriptions", + "setDefinitionName": { + "value": "MobilePush Subscriptions" + }, + "parentIdentifier": "b352de3f-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "2051892d-5de2-4ecf-98af-8ca9a40d2c9c", + "applicationKey": "com.exacttarget.mobilepush", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 2, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "MobilePush Subscriptions", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": false, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 0, + "sendAttributeStorageName": "_ContactID", + "sendContactKeyStorageName": "_SubscriberID", + "storageLogicalType": "PushAttributes", + "storageName": "_PushAddress", + "storageObjectIDs": ["4851de3f-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "7893dc39-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "b352de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushSubscriptions", + "name": "MobilePush Subscriptions" + }, + { + "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProducts", + "definitionName": { + "value": "Predictive Intelligence Products" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "c485d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "c885d645-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "da85d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "de85d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "d685d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "cb85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence Products.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProducts", + "definitionName": { + "value": "Predictive Intelligence Products" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "cb85d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProducts", + "setDefinitionName": { + "value": "Predictive Intelligence Products" + }, + "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "name", + "localizedDescription": { + "value": "name" + }, + "definitionID": "c585d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Name", + "definitionName": { + "value": "Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence Products.Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 1000, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "c585d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProducts", + "definitionName": { + "value": "Predictive Intelligence Products" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "name", + "storageFieldReferenceID": { + "type": "guid", + "value": "116f93a1-da7c-4b0a-876c-7f6f107881c5" + }, + "valueDefinitionID": "c585d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Name", + "name": "Name", + "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProducts", + "setDefinitionName": { + "value": "Predictive Intelligence Products" + }, + "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Decimal", + "description": "regPrice", + "localizedDescription": { + "value": "regPrice" + }, + "definitionID": "c685d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Regular_Price", + "definitionName": { + "value": "Regular Price" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence Products.Regular Price", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "c685d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProducts", + "definitionName": { + "value": "Predictive Intelligence Products" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 2, + "storageName": "regPrice", + "storageFieldReferenceID": { + "type": "guid", + "value": "d651f3d5-5b32-4fd7-907d-2d6caf42f827" + }, + "valueDefinitionID": "c685d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Regular_Price", + "name": "Regular Price", + "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProducts", + "setDefinitionName": { + "value": "Predictive Intelligence Products" + }, + "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Decimal", + "description": "salePrice", + "localizedDescription": { + "value": "salePrice" + }, + "definitionID": "c785d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Sale_Price", + "definitionName": { + "value": "Sale Price" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence Products.Sale Price", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "c785d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProducts", + "definitionName": { + "value": "Predictive Intelligence Products" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 2, + "storageName": "salePrice", + "storageFieldReferenceID": { + "type": "guid", + "value": "b10ebf49-6195-40c2-beaa-810d2c5b39d4" + }, + "valueDefinitionID": "c785d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Sale_Price", + "name": "Sale Price", + "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProducts", + "setDefinitionName": { + "value": "Predictive Intelligence Products" + }, + "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Uuid", + "localizedDescription": { + "value": "Uuid" + }, + "definitionID": "ca85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "UUID", + "definitionName": { + "value": "UUID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence Products.UUID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "ca85d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProducts", + "definitionName": { + "value": "Predictive Intelligence Products" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Uuid", + "storageFieldReferenceID": { + "type": "guid", + "value": "7fc0495c-f03d-496a-a74d-770a9e672518" + }, + "valueDefinitionID": "ca85d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "UUID", + "name": "UUID", + "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProducts", + "setDefinitionName": { + "value": "Predictive Intelligence Products" + }, + "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "sku", + "localizedDescription": { + "value": "sku" + }, + "definitionID": "c885d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "SKU", + "definitionName": { + "value": "SKU" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Predictive Intelligence Products.SKU", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "c885d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProducts", + "definitionName": { + "value": "Predictive Intelligence Products" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "sku", + "storageFieldReferenceID": { + "type": "guid", + "value": "603870ea-b2e0-4613-bb22-08f582f34a94" + }, + "valueDefinitionID": "c885d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "SKU", + "name": "SKU", + "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProducts", + "setDefinitionName": { + "value": "Predictive Intelligence Products" + }, + "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "type", + "localizedDescription": { + "value": "type" + }, + "definitionID": "c985d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Type", + "definitionName": { + "value": "Type" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "Predictive Intelligence Products.Type", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 50, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "c985d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 7, + "parentDefinition": { + "definitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProducts", + "definitionName": { + "value": "Predictive Intelligence Products" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "type", + "storageFieldReferenceID": { + "type": "guid", + "value": "9f3e8ffe-c631-4397-ab2e-8cbc50d7f6c1" + }, + "valueDefinitionID": "c985d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Type", + "name": "Type", + "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProducts", + "setDefinitionName": { + "value": "Predictive Intelligence Products" + }, + "parentIdentifier": "c485d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence Products", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 1, + "storageLogicalType": "DataExtension", + "storageName": "IGO_PRODUCTS", + "storageObjectIDs": ["bc85d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "d852de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "c485d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProducts", + "name": "Predictive Intelligence Products" + }, + { + "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushTags", + "definitionName": { + "value": "MobilePush Tags" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "valueDefinitions": [ + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "c752de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushAppID", + "definitionName": { + "value": "Application" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "MobilePush Tags.Application", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 38, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "c752de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 1, + "parentDefinition": { + "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushTags", + "definitionName": { + "value": "MobilePush Tags" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 11, + "storageName": "_APID", + "storageFieldReferenceID": { + "type": "guid", + "value": "7f711754-1b97-4c7d-86d8-507f9fcb877d" + }, + "valueDefinitionID": "c752de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "PushAppID", + "name": "Application", + "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushTags", + "setDefinitionName": { + "value": "MobilePush Tags" + }, + "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "ce52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "MobilePush Tags.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 2, + "parentDefinition": { + "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushTags", + "definitionName": { + "value": "MobilePush Tags" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "ce52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushTags", + "setDefinitionName": { + "value": "MobilePush Tags" + }, + "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "c852de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedBy", + "definitionName": { + "value": "Created By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "MobilePush Tags.Created By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "c852de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushTags", + "definitionName": { + "value": "MobilePush Tags" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedBy", + "storageFieldReferenceID": { + "type": "guid", + "value": "dbc7917c-95cd-4294-b116-eb215d1c5c0b" + }, + "valueDefinitionID": "c852de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedBy", + "name": "Created By", + "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushTags", + "setDefinitionName": { + "value": "MobilePush Tags" + }, + "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "c952de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedDate", + "definitionName": { + "value": "Created Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "MobilePush Tags.Created Date", + "isHidden": true, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "c952de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushTags", + "definitionName": { + "value": "MobilePush Tags" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "30e22e41-0415-4d8a-b817-c56b0bffa168" + }, + "valueDefinitionID": "c952de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedDate", + "name": "Created Date", + "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushTags", + "setDefinitionName": { + "value": "MobilePush Tags" + }, + "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "ca52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushDeviceID", + "definitionName": { + "value": "Device ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "MobilePush Tags.Device ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "ca52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushTags", + "definitionName": { + "value": "MobilePush Tags" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_DeviceID", + "storageFieldReferenceID": { + "type": "guid", + "value": "ee23b0fd-76ad-46b5-9e14-aef0e17ec28f" + }, + "valueDefinitionID": "ca52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "PushDeviceID", + "name": "Device ID", + "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushTags", + "setDefinitionName": { + "value": "MobilePush Tags" + }, + "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "cb52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedBy", + "definitionName": { + "value": "Modified By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "MobilePush Tags.Modified By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "cb52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushTags", + "definitionName": { + "value": "MobilePush Tags" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedBy", + "storageFieldReferenceID": { + "type": "guid", + "value": "36b8827e-6017-4cba-bd0f-ba2261480736" + }, + "valueDefinitionID": "cb52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedBy", + "name": "Modified By", + "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushTags", + "setDefinitionName": { + "value": "MobilePush Tags" + }, + "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "cc52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedDate", + "definitionName": { + "value": "Modified Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "MobilePush Tags.Modified Date", + "isHidden": true, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "cc52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 7, + "parentDefinition": { + "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushTags", + "definitionName": { + "value": "MobilePush Tags" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "685ea0db-0ecb-4111-8676-0a7c0a29c79f" + }, + "valueDefinitionID": "cc52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedDate", + "name": "Modified Date", + "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushTags", + "setDefinitionName": { + "value": "MobilePush Tags" + }, + "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "cd52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Value", + "definitionName": { + "value": "Value" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 8, + "fullyQualifiedName": "MobilePush Tags.Value", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 128, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "cd52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 8, + "parentDefinition": { + "definitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PushTags", + "definitionName": { + "value": "MobilePush Tags" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_Value", + "storageFieldReferenceID": { + "type": "guid", + "value": "cd7e2a3c-2551-4518-96c7-5c6b0d42423e" + }, + "valueDefinitionID": "cd52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Value", + "name": "Value", + "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushTags", + "setDefinitionName": { + "value": "MobilePush Tags" + }, + "parentIdentifier": "c652de3f-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "2051892d-5de2-4ecf-98af-8ca9a40d2c9c", + "applicationKey": "com.exacttarget.mobilepush", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 2, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "MobilePush Tags", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": false, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 0, + "storageLogicalType": "DataExtension", + "storageName": "_PushTag", + "storageObjectIDs": ["bd52de3f-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "7993dc39-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "c652de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PushTags", + "name": "MobilePush Tags" + }, + { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": true, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "cae9847d-696d-eb11-b81e-48df37d1df5a", + "relationshipType": "AttributeGroup" + }, + "leftRelationshipIDs": [ + { + "type": "int16", + "value": "2" + } + ], + "leftRelationshipReferenceType": "CustomerData", + "relationshipAttributes": [ + { + "leftAttributeID": "9293dc39-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "cee9847d-696d-eb11-b81e-48df37d1df5a", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "9a42dcad-ae72-4cde-9937-193e17485ad6", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "d5e9847d-696d-eb11-b81e-48df37d1df5a", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "f7e9847d-696d-eb11-b81e-48df37d1df5a", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "04ea847d-696d-eb11-b81e-48df37d1df5a", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "cbe9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "CarrierID", + "definitionName": { + "value": "Carrier ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Chat Message Demographics.Carrier ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "cbe9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 1, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CarrierID", + "storageFieldReferenceID": { + "type": "guid", + "value": "3fdc8842-cc0f-407c-a3ec-930d7a027d1d" + }, + "valueDefinitionID": "cbe9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "CarrierID", + "name": "Carrier ID", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "cce9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "Channel", + "definitionName": { + "value": "Channel" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Chat Message Demographics.Channel", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 20, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "cce9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_Channel", + "storageFieldReferenceID": { + "type": "guid", + "value": "ef36ded9-67b2-4daf-899f-6862af8e5ee7" + }, + "valueDefinitionID": "cce9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "Channel", + "name": "Channel", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "cde9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "City", + "definitionName": { + "value": "City" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Chat Message Demographics.City", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "cde9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_City", + "storageFieldReferenceID": { + "type": "guid", + "value": "be7b4554-bf03-4a80-9101-3e396b2e345f" + }, + "valueDefinitionID": "cde9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "City", + "name": "City", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "cee9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ContactID", + "definitionName": { + "value": "Contact ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Chat Message Demographics.Contact ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "cee9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ContactID", + "storageFieldReferenceID": { + "type": "guid", + "value": "b0e31883-cae8-4bc5-aa24-88565d375a18" + }, + "valueDefinitionID": "cee9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "ContactID", + "name": "Contact ID", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "d0e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "CreatedBy", + "definitionName": { + "value": "Created By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Chat Message Demographics.Created By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d0e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedBy", + "storageFieldReferenceID": { + "type": "guid", + "value": "1671a32a-8eb0-4dc5-b30d-8ad16e55a601" + }, + "valueDefinitionID": "d0e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "CreatedBy", + "name": "Created By", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "d1e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "CreatedDate", + "definitionName": { + "value": "Created Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Chat Message Demographics.Created Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d1e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "de543ca5-5920-4309-adb9-33472144defe" + }, + "valueDefinitionID": "d1e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "CreatedDate", + "name": "Created Date", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "d2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "FirstName", + "definitionName": { + "value": "First Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "Chat Message Demographics.First Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 9, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_FirstName", + "storageFieldReferenceID": { + "type": "guid", + "value": "125f7c91-2f11-44bd-9687-f22cf2461496" + }, + "valueDefinitionID": "d2e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "FirstName", + "name": "First Name", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Boolean", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Boolean", + "defaultValue": "False", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "d3e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "IsHonorDST", + "definitionName": { + "value": "Is Honor DST" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "Chat Message Demographics.Is Honor DST", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d3e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 10, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_IsHonorDST", + "storageFieldReferenceID": { + "type": "guid", + "value": "17abe00a-4306-43c5-b27f-a81f015d6dfb" + }, + "valueDefinitionID": "d3e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "IsHonorDST", + "name": "Is Honor DST", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "d4e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "LastName", + "definitionName": { + "value": "Last Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 11, + "fullyQualifiedName": "Chat Message Demographics.Last Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 100, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d4e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 11, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_LastName", + "storageFieldReferenceID": { + "type": "guid", + "value": "e31f18f4-5422-410b-adcc-1b60f61cce5f" + }, + "valueDefinitionID": "d4e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "LastName", + "name": "Last Name", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "cfe9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "CountryCode", + "definitionName": { + "value": "Locale" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 12, + "fullyQualifiedName": "Chat Message Demographics.Locale", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": 2, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "cfe9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 12, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CountryCode", + "storageFieldReferenceID": { + "type": "guid", + "value": "4b5fda70-47cb-4f4b-8ba6-f5cac53ee344" + }, + "valueDefinitionID": "cfe9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "CountryCode", + "name": "Locale", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Phone", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "d5e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "MobileNumber", + "definitionName": { + "value": "Mobile Number" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 14, + "fullyQualifiedName": "Chat Message Demographics.Mobile Number", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": 15, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d5e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 14, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_MobileNumber", + "storageFieldReferenceID": { + "type": "guid", + "value": "e31a7e3b-e943-440e-9be6-77224a4928fe" + }, + "valueDefinitionID": "d5e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "MobileNumber", + "name": "Mobile Number", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "d6e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ModifiedBy", + "definitionName": { + "value": "Modified By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 15, + "fullyQualifiedName": "Chat Message Demographics.Modified By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d6e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 15, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedBy", + "storageFieldReferenceID": { + "type": "guid", + "value": "a9be58ef-884d-44f4-9926-d73ebe587847" + }, + "valueDefinitionID": "d6e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "ModifiedBy", + "name": "Modified By", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "d7e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ModifiedDate", + "definitionName": { + "value": "Modified Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 16, + "fullyQualifiedName": "Chat Message Demographics.Modified Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d7e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 16, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "216659c1-9512-47de-a9ee-822f48148514" + }, + "valueDefinitionID": "d7e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "ModifiedDate", + "name": "Modified Date", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "d8e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "Priority", + "definitionName": { + "value": "Priority" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 17, + "fullyQualifiedName": "Chat Message Demographics.Priority", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d8e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 17, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_Priority", + "storageFieldReferenceID": { + "type": "guid", + "value": "71153ee5-a33f-4cf6-a963-0c3a893d9348" + }, + "valueDefinitionID": "d8e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "Priority", + "name": "Priority", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "d9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "Source", + "definitionName": { + "value": "Source" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 18, + "fullyQualifiedName": "Chat Message Demographics.Source", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 18, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 5, + "storageName": "_Source", + "storageFieldReferenceID": { + "type": "guid", + "value": "f6bafdfb-86bf-45e8-9b76-b878c904d6c5" + }, + "valueDefinitionID": "d9e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "Source", + "name": "Source", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "dae9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "SourceObjectID", + "definitionName": { + "value": "Source Object ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 19, + "fullyQualifiedName": "Chat Message Demographics.Source Object ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "dae9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 19, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_SourceObjectId", + "storageFieldReferenceID": { + "type": "guid", + "value": "c67a7922-44e5-4c4b-a4c8-2ac3550a5f07" + }, + "valueDefinitionID": "dae9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "SourceObjectID", + "name": "Source Object ID", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 4, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "dfe9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "SFContactID", + "definitionName": { + "value": "SFContactID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 19, + "fullyQualifiedName": "Chat Message Demographics.SFContactID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": true, + "length": 50, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "dfe9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 19, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "SFContactID", + "storageFieldReferenceID": { + "type": "guid", + "value": "ce5a90ea-88eb-4683-9a1a-5c776b5763ce" + }, + "valueDefinitionID": "dfe9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "SFContactID", + "name": "SFContactID", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "dbe9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "State", + "definitionName": { + "value": "State" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 20, + "fullyQualifiedName": "Chat Message Demographics.State", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 200, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "dbe9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 20, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_State", + "storageFieldReferenceID": { + "type": "guid", + "value": "c0ea1fac-d939-4dde-b45a-16586f661924" + }, + "valueDefinitionID": "dbe9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "State", + "name": "State", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "dce9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "Status", + "definitionName": { + "value": "Status" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 21, + "fullyQualifiedName": "Chat Message Demographics.Status", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "dce9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 21, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 6, + "storageName": "_Status", + "storageFieldReferenceID": { + "type": "guid", + "value": "fafff407-c055-411c-81ec-78907f5dbd58" + }, + "valueDefinitionID": "dce9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "Status", + "name": "Status", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Decimal", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "dde9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "UTCOffset", + "definitionName": { + "value": "UTC Offset" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 22, + "fullyQualifiedName": "Chat Message Demographics.UTC Offset", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": 4, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "dde9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 22, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 2, + "storageName": "_UTCOffset", + "storageFieldReferenceID": { + "type": "guid", + "value": "84d29656-a348-43c2-ac2f-8c7ec5b18a3e" + }, + "valueDefinitionID": "dde9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "UTCOffset", + "name": "UTC Offset", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "e0e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ZipCode", + "definitionName": { + "value": "Zip Code" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 23, + "fullyQualifiedName": "Chat Message Demographics.Zip Code", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": false, + "isUpdateable": false, + "length": 20, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "e0e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "ordinal": 23, + "parentDefinition": { + "definitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageDemographics", + "definitionName": { + "value": "Chat Message Demographics" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ZipCode", + "storageFieldReferenceID": { + "type": "guid", + "value": "11ce9d05-a1e3-47ba-9077-11097e0b4c8d" + }, + "valueDefinitionID": "e0e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "ZipCode", + "name": "Zip Code", + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "setDefinitionName": { + "value": "Chat Message Demographics" + }, + "parentIdentifier": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + } + ], + "applicationID": "e25893f9-08f3-480f-8def-7f8ab0583611", + "applicationKey": "com.exacttarget.mobileconnect", + "attributeCount": 0, + "canAddValues": true, + "canChangeValues": true, + "canModify": false, + "canRemove": false, + "categoryID": 2, + "createDate": "2021-02-12T13:36:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Chat Message Demographics", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": false, + "isRoot": false, + "isSendable": true, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 2, + "sendAttributeStorageName": "_ContactID", + "sendContactKeyStorageName": "_SubscriberID", + "storageLogicalType": "MobileAttributes", + "storageName": "_MobileAddress", + "storageObjectIDs": ["1651de3f-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "7693dc39-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "c9e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageDemographics", + "name": "Chat Message Demographics" + }, + { + "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductAttribs", + "definitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "dc85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence Product Attributes.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductAttribs", + "definitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "dc85d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "attribName", + "localizedDescription": { + "value": "attribName" + }, + "definitionID": "d785d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Attribute_Name", + "definitionName": { + "value": "Attribute Name" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence Product Attributes.Attribute Name", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 1000, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d785d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductAttribs", + "definitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "attribName", + "storageFieldReferenceID": { + "type": "guid", + "value": "a29facf4-9173-43b7-98d5-57bef44c832f" + }, + "valueDefinitionID": "d785d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Attribute_Name", + "name": "Attribute Name", + "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "attribValue", + "localizedDescription": { + "value": "attribValue" + }, + "definitionID": "d985d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Attribute_Value", + "definitionName": { + "value": "Attribute Value" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence Product Attributes.Attribute Value", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 1000, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d985d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductAttribs", + "definitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "attribValue", + "storageFieldReferenceID": { + "type": "guid", + "value": "b023eb98-10c7-481d-a809-38af6af65b17" + }, + "valueDefinitionID": "d985d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Attribute_Value", + "name": "Attribute Value", + "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "sku", + "localizedDescription": { + "value": "sku" + }, + "definitionID": "da85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "SKU", + "definitionName": { + "value": "SKU" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence Product Attributes.SKU", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "da85d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductAttribs", + "definitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "sku", + "storageFieldReferenceID": { + "type": "guid", + "value": "35919388-7813-48d0-a45f-2c0cf64d6e1e" + }, + "valueDefinitionID": "da85d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "SKU", + "name": "SKU", + "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Date", + "description": "updated_at", + "localizedDescription": { + "value": "updated_at" + }, + "definitionID": "db85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Updated_At", + "definitionName": { + "value": "Updated At" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence Product Attributes.Updated At", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "db85d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductAttribs", + "definitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "updated_at", + "storageFieldReferenceID": { + "type": "guid", + "value": "a8a96a08-576c-4b45-842c-fe6c36da6f41" + }, + "valueDefinitionID": "db85d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Updated_At", + "name": "Updated At", + "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Number", + "description": "attributeValueIndex", + "localizedDescription": { + "value": "attributeValueIndex" + }, + "definitionID": "d885d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Attribute_Value_Index", + "definitionName": { + "value": "Attribute Value Index" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Predictive Intelligence Product Attributes.Attribute Value Index", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "d885d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductAttribs", + "definitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "attributeValueIndex", + "storageFieldReferenceID": { + "type": "guid", + "value": "619fe747-d142-4522-91dd-4228546d282d" + }, + "valueDefinitionID": "d885d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Attribute_Value_Index", + "name": "Attribute Value Index", + "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductAttribs", + "setDefinitionName": { + "value": "Predictive Intelligence Product Attributes" + }, + "parentIdentifier": "d685d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence Product Attributes", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 0, + "storageLogicalType": "DataExtension", + "storageName": "IGO_PRODUCTATTRIBS", + "storageObjectIDs": ["cf85d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "d952de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "d685d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductAttribs", + "name": "Predictive Intelligence Product Attributes" + }, + { + "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineSubscriptions", + "definitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "valueDefinitions": [ + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "e651de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "AddressID", + "definitionName": { + "value": "Address ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "GroupConnect LINE Subscriptions.Address ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": -1, + "ordinal": 1, + "parentDefinition": { + "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineSubscriptions", + "definitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "AddressId", + "valueDefinitionID": "e651de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "AddressID", + "name": "Address ID", + "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineSubscriptions", + "setDefinitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "e751de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ChannelID", + "definitionName": { + "value": "Channel ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "GroupConnect LINE Subscriptions.Channel ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": -1, + "ordinal": 2, + "parentDefinition": { + "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineSubscriptions", + "definitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ChannelId", + "valueDefinitionID": "e751de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ChannelID", + "name": "Channel ID", + "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineSubscriptions", + "setDefinitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Boolean", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Boolean", + "defaultValue": "False", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "e851de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "IsSubscribed", + "definitionName": { + "value": "Is Subscribed" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "GroupConnect LINE Subscriptions.Is Subscribed", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 3, + "parentDefinition": { + "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineSubscriptions", + "definitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "IsSubscribed", + "valueDefinitionID": "e851de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "IsSubscribed", + "name": "Is Subscribed", + "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineSubscriptions", + "setDefinitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "e951de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedDate", + "definitionName": { + "value": "Created Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "GroupConnect LINE Subscriptions.Created Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 4, + "parentDefinition": { + "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineSubscriptions", + "definitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "CreatedDate", + "valueDefinitionID": "e951de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedDate", + "name": "Created Date", + "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineSubscriptions", + "setDefinitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "ea51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedBy", + "definitionName": { + "value": "Created By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "GroupConnect LINE Subscriptions.Created By", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 5, + "parentDefinition": { + "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineSubscriptions", + "definitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "CreatedBy", + "valueDefinitionID": "ea51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedBy", + "name": "Created By", + "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineSubscriptions", + "setDefinitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "eb51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedDate", + "definitionName": { + "value": "Modified Date" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "GroupConnect LINE Subscriptions.Modified Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 6, + "parentDefinition": { + "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineSubscriptions", + "definitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ModifiedDate", + "valueDefinitionID": "eb51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedDate", + "name": "Modified Date", + "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineSubscriptions", + "setDefinitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "ec51de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedBy", + "definitionName": { + "value": "Modified By" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "GroupConnect LINE Subscriptions.Modified By", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 7, + "parentDefinition": { + "definitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "GroupConnectLineSubscriptions", + "definitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "ModifiedBy", + "valueDefinitionID": "ec51de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedBy", + "name": "Modified By", + "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineSubscriptions", + "setDefinitionName": { + "value": "GroupConnect LINE Subscriptions" + }, + "parentIdentifier": "e551de3f-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "4e9519db-ad21-483a-a3fc-8ab4557eded1", + "applicationKey": "com.exacttarget.GroupConnect", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "localizedDescription": {}, + "fullyQualifiedName": "GroupConnect LINE Subscriptions", + "isCustomObjectBacked": false, + "isEvent": false, + "isHidden": false, + "isReadOnly": false, + "isRoot": false, + "isSendable": false, + "isSystemDefined": true, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 0, + "storageObjectIDs": ["dd51de3f-31e2-e611-80cc-1402ec7222b4"], + "setDefinitionID": "e551de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "GroupConnectLineSubscriptions", + "name": "GroupConnect LINE Subscriptions" + }, + { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "f785d645-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "c885d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "0086d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "c485d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "fa85d645-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "1286d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "1586d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "0b86d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "fb85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "fb85d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Sku", + "localizedDescription": { + "value": "Sku" + }, + "definitionID": "f785d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "SKU", + "definitionName": { + "value": "SKU" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.SKU", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f785d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Sku", + "storageFieldReferenceID": { + "type": "guid", + "value": "8fbf489f-b82c-4c03-ab47-e8576a5625db" + }, + "valueDefinitionID": "f785d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "SKU", + "name": "SKU", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Decimal", + "description": "Price", + "localizedDescription": { + "value": "Price" + }, + "definitionID": "f485d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Price", + "definitionName": { + "value": "Price" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.Price", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 18, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f485d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "scale": 2, + "storageName": "Price", + "storageFieldReferenceID": { + "type": "guid", + "value": "f6942680-95e1-4000-9026-77fbfd8d5e41" + }, + "valueDefinitionID": "f485d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Price", + "name": "Price", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Number", + "description": "Quantity", + "localizedDescription": { + "value": "Quantity" + }, + "definitionID": "f585d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Quantity", + "definitionName": { + "value": "Quantity" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.Quantity", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f585d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Quantity", + "storageFieldReferenceID": { + "type": "guid", + "value": "29508cf9-fac3-4d64-8e28-e691978bd659" + }, + "valueDefinitionID": "f585d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Quantity", + "name": "Quantity", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "order_number", + "localizedDescription": { + "value": "order_number" + }, + "definitionID": "f385d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Order_Number", + "definitionName": { + "value": "Order Number" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.Order Number", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f385d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "order_number", + "storageFieldReferenceID": { + "type": "guid", + "value": "d4024f16-8e2a-4f19-a852-6736071d8ec6" + }, + "valueDefinitionID": "f385d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Order_Number", + "name": "Order Number", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "user_id", + "localizedDescription": { + "value": "user_id" + }, + "definitionID": "fa85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "User_ID", + "definitionName": { + "value": "User ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.User ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "fa85d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "user_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "c318e0f3-c386-4beb-ab78-be4067c5520d" + }, + "valueDefinitionID": "fa85d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "User_ID", + "name": "User ID", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Date", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Date", + "description": "Timestamp", + "localizedDescription": { + "value": "Timestamp" + }, + "definitionID": "f985d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Timestamp", + "definitionName": { + "value": "Timestamp" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.Timestamp", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f985d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 7, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Timestamp", + "storageFieldReferenceID": { + "type": "guid", + "value": "499933ee-cc51-4a79-8db1-bf6bf304d61f" + }, + "valueDefinitionID": "f985d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Timestamp", + "name": "Timestamp", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "Job_ID", + "localizedDescription": { + "value": "Job_ID" + }, + "definitionID": "f085d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Job_ID", + "definitionName": { + "value": "Job_ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.Job_ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f085d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 9, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Job_ID", + "storageFieldReferenceID": { + "type": "guid", + "value": "f021da2f-c005-46ca-a561-b6c3d9e095d0" + }, + "valueDefinitionID": "f085d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Job_ID", + "name": "Job_ID", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "List_ID", + "localizedDescription": { + "value": "List_ID" + }, + "definitionID": "f285d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "List_ID", + "definitionName": { + "value": "List_ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.List_ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f285d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 10, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "List_ID", + "storageFieldReferenceID": { + "type": "guid", + "value": "6a8da7cf-8496-4ffe-8c5c-057fce68cccc" + }, + "valueDefinitionID": "f285d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "List_ID", + "name": "List_ID", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "Batch_ID", + "localizedDescription": { + "value": "Batch_ID" + }, + "definitionID": "ef85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Batch_ID", + "definitionName": { + "value": "Batch_ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 11, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.Batch_ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "ef85d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 11, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Batch_ID", + "storageFieldReferenceID": { + "type": "guid", + "value": "053d483c-62a0-4361-80a4-e99d8bde4550" + }, + "valueDefinitionID": "ef85d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Batch_ID", + "name": "Batch_ID", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Number", + "description": "Landing_URL_ID", + "localizedDescription": { + "value": "Landing_URL_ID" + }, + "definitionID": "f185d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Landing_URL_ID", + "definitionName": { + "value": "Landing_URL_ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 12, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.Landing_URL_ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f185d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 12, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Landing_URL_ID", + "storageFieldReferenceID": { + "type": "guid", + "value": "d37c4358-5810-4d47-bcec-92829b828703" + }, + "valueDefinitionID": "f185d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Landing_URL_ID", + "name": "Landing_URL_ID", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Numeric", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "Subscriber_ID", + "localizedDescription": { + "value": "Subscriber_ID" + }, + "definitionID": "f885d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Subscriber_ID", + "definitionName": { + "value": "Subscriber_ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 13, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.Subscriber_ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f885d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 13, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Subscriber_ID", + "storageFieldReferenceID": { + "type": "guid", + "value": "5c0c3f04-baec-434a-b463-4f82e3a9fb9c" + }, + "valueDefinitionID": "f885d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Subscriber_ID", + "name": "Subscriber_ID", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "session_id", + "localizedDescription": { + "value": "session_id" + }, + "definitionID": "f685d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "session_id", + "definitionName": { + "value": "session_id" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 14, + "fullyQualifiedName": "Predictive Intelligence Product Purchases.session_id", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f685d645-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 14, + "parentDefinition": { + "definitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProductPurchases", + "definitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "session_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "33bf36ba-c6b7-43cd-b996-abf12ced61fb" + }, + "valueDefinitionID": "f685d645-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "session_id", + "name": "session_id", + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "setDefinitionName": { + "value": "Predictive Intelligence Product Purchases" + }, + "parentIdentifier": "ee85d645-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence Product Purchases", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 2, + "storageLogicalType": "DataExtension", + "storageName": "IGO_PURCHASES", + "storageObjectIDs": ["e085d645-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "d752de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProductPurchases", + "name": "Predictive Intelligence Product Purchases" + }, + { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "02ea847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "fullyQualifiedName": "Chat Message Subscriptions.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "02ea847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "f7e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_MobileNumber", + "definitionName": { + "value": "MobileNumber" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Chat Message Subscriptions.MobileNumber", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 254, + "ordinal": 2, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_MobileNumber", + "storageFieldReferenceID": { + "type": "guid", + "value": "169e88d8-d9fe-43f4-82e2-f325674328ee" + }, + "valueDefinitionID": "f7e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_MobileNumber", + "name": "MobileNumber", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "f3e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_ChannelId", + "definitionName": { + "value": "ChannelId" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Chat Message Subscriptions.ChannelId", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 50, + "ordinal": 3, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ChannelId", + "storageFieldReferenceID": { + "type": "guid", + "value": "5f56cbc2-6799-4b37-b24d-38b16e9ed30a" + }, + "valueDefinitionID": "f3e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_ChannelId", + "name": "ChannelId", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "f4e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_ChannelType", + "definitionName": { + "value": "ChannelType" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Chat Message Subscriptions.ChannelType", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 20, + "ordinal": 4, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ChannelType", + "storageFieldReferenceID": { + "type": "guid", + "value": "d442b162-248b-4546-b0ee-7d86d4444d3b" + }, + "valueDefinitionID": "f4e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_ChannelType", + "name": "ChannelType", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "ffe9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_OptOutStatusID", + "definitionName": { + "value": "OptOutStatusID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Chat Message Subscriptions.OptOutStatusID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 5, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "restrictionLookupListID": 15, + "storageName": "_OptOutStatusID", + "storageFieldReferenceID": { + "type": "guid", + "value": "ca82f469-ea9e-44d8-ad4f-d8ed7536518f" + }, + "valueDefinitionID": "ffe9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_OptOutStatusID", + "name": "OptOutStatusID", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "fee9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_OptOutMethodID", + "definitionName": { + "value": "OptOutMethodID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Chat Message Subscriptions.OptOutMethodID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 6, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptOutMethodID", + "storageFieldReferenceID": { + "type": "guid", + "value": "c47ca0dc-f8b3-4476-8ffb-1cbf22b6254e" + }, + "valueDefinitionID": "fee9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_OptOutMethodID", + "name": "OptOutMethodID", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Date", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Date", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "fde9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_OptOutDate", + "definitionName": { + "value": "OptOutDate" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "Chat Message Subscriptions.OptOutDate", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 7, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptOutDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "0b8b6cdd-86ba-4d36-8e27-0e0b4bde256f" + }, + "valueDefinitionID": "fde9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_OptOutDate", + "name": "OptOutDate", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "fce9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_OptInStatusID", + "definitionName": { + "value": "OptInStatusID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 8, + "fullyQualifiedName": "Chat Message Subscriptions.OptInStatusID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 8, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptInStatusID", + "storageFieldReferenceID": { + "type": "guid", + "value": "c0f3cd62-55cb-4f61-bb97-d3676e9c7eea" + }, + "valueDefinitionID": "fce9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_OptInStatusID", + "name": "OptInStatusID", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "fbe9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_OptInMethodID", + "definitionName": { + "value": "OptInMethodID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "Chat Message Subscriptions.OptInMethodID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 9, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptInMethodID", + "storageFieldReferenceID": { + "type": "guid", + "value": "a4d5dea8-cd22-435c-b389-9cdce054149c" + }, + "valueDefinitionID": "fbe9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_OptInMethodID", + "name": "OptInMethodID", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Date", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Date", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "fae9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_OptInDate", + "definitionName": { + "value": "OptInDate" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "Chat Message Subscriptions.OptInDate", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 10, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_OptInDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "4fbd9715-9b10-4e4b-bf89-215786c84e96" + }, + "valueDefinitionID": "fae9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_OptInDate", + "name": "OptInDate", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Byte", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "00ea847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_Source", + "definitionName": { + "value": "Source" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 11, + "fullyQualifiedName": "Chat Message Subscriptions.Source", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 11, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_Source", + "storageFieldReferenceID": { + "type": "guid", + "value": "2b7a081b-127c-4d65-bdfe-f80f274f4580" + }, + "valueDefinitionID": "00ea847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_Source", + "name": "Source", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Text", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Text", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "01ea847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_SourceObjectId ", + "definitionName": { + "value": "SourceObjectId" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 12, + "fullyQualifiedName": "Chat Message Subscriptions.SourceObjectId", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "ordinal": 12, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_SourceObjectId ", + "storageFieldReferenceID": { + "type": "guid", + "value": "47505922-899e-45b8-a1cc-c0049d280504" + }, + "valueDefinitionID": "01ea847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_SourceObjectId ", + "name": "SourceObjectId", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Date", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "f6e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_CreatedDate", + "definitionName": { + "value": "CreatedDate" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 13, + "fullyQualifiedName": "Chat Message Subscriptions.CreatedDate", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 13, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "ae8a3f3e-1020-484e-8e24-5c11c7393d56" + }, + "valueDefinitionID": "f6e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_CreatedDate", + "name": "CreatedDate", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "f5e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_CreatedBy ", + "definitionName": { + "value": "CreatedBy" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 14, + "fullyQualifiedName": "Chat Message Subscriptions.CreatedBy", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 14, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CreatedBy ", + "storageFieldReferenceID": { + "type": "guid", + "value": "0b7dac0b-728a-4fb7-a63e-c21311d784d3" + }, + "valueDefinitionID": "f5e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_CreatedBy ", + "name": "CreatedBy", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Date", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "f9e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_ModifiedDate", + "definitionName": { + "value": "ModifiedDate" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 15, + "fullyQualifiedName": "Chat Message Subscriptions.ModifiedDate", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 15, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedDate", + "storageFieldReferenceID": { + "type": "guid", + "value": "10d39942-4628-4e99-a927-523fe48d1068" + }, + "valueDefinitionID": "f9e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_ModifiedDate", + "name": "ModifiedDate", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "f8e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "_ModifiedBy ", + "definitionName": { + "value": "ModifiedBy" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 16, + "fullyQualifiedName": "Chat Message Subscriptions.ModifiedBy", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 16, + "parentDefinition": { + "definitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "definitionKey": "ChatMessageSubscriptions", + "definitionName": { + "value": "Chat Message Subscriptions" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_ModifiedBy ", + "storageFieldReferenceID": { + "type": "guid", + "value": "a0486cff-d96e-41dd-9286-c77ddad92f75" + }, + "valueDefinitionID": "f8e9847d-696d-eb11-b81e-48df37d1df5a", + "valueDefinitionKey": "_ModifiedBy ", + "name": "ModifiedBy", + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "setDefinitionName": { + "value": "Chat Message Subscriptions" + }, + "parentIdentifier": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + } + ], + "applicationID": "e25893f9-08f3-480f-8def-7f8ab0583611", + "applicationKey": "com.exacttarget.mobileconnect", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 2, + "createDate": "2021-02-12T13:36:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Chat Message Subscriptions", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": false, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 0, + "storageLogicalType": "DataExtension", + "storageName": "_ChatMessagingSubscription", + "storageObjectIDs": ["e1e9847d-696d-eb11-b81e-48df37d1df5a"], + "storageReferenceID": { + "type": "guid", + "value": "38042500-a868-eb11-b81e-48df37d1df5a" + }, + "setDefinitionID": "f2e9847d-696d-eb11-b81e-48df37d1df5a", + "setDefinitionKey": "ChatMessageSubscriptions", + "name": "Chat Message Subscriptions" + }, + { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "relationships": [ + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": true, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "e152de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeGroup" + }, + "leftRelationshipIDs": [ + { + "type": "int16", + "value": "4" + } + ], + "leftRelationshipReferenceType": "CustomerData", + "relationshipAttributes": [ + { + "leftAttributeID": "1151de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "fc52de3f-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "9885d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "2386d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "2686d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "1e86d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "5a86d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "5d86d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "5286d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "b785d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "ba85d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "b285d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + }, + { + "canModify": false, + "canRemove": false, + "isHidden": false, + "isSystemDefined": false, + "isGroupToSetRelationship": false, + "leftItem": { + "cardinality": "One", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + }, + "relationshipAttributes": [ + { + "leftAttributeID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", + "leftConnectingID": { + "identifierType": "FullyQualifiedName" + }, + "rightAttributeID": "fa85d645-31e2-e611-80cc-1402ec7222b4", + "rightConnectingID": { + "identifierType": "FullyQualifiedName" + } + } + ], + "relationshipID": "fd85d645-31e2-e611-80cc-1402ec7222b4", + "rightItem": { + "cardinality": "Many", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "identifier": "ee85d645-31e2-e611-80cc-1402ec7222b4", + "relationshipType": "AttributeSet" + } + } + ], + "valueDefinitions": [ + { + "baseType": "Numeric", + "dataSourceID": 1, + "dataSourceName": {}, + "dataType": "LongNumber", + "description": "", + "localizedDescription": { + "value": "" + }, + "definitionID": "0453de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CustomObjectKey", + "definitionName": { + "value": "Custom Object Key" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 1, + "fullyQualifiedName": "Predictive Intelligence Profiles.Custom Object Key", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "ordinal": 1, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "_CustomObjectKey", + "valueDefinitionID": "0453de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CustomObjectKey", + "name": "Custom Object Key", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "user_id", + "localizedDescription": { + "value": "user_id" + }, + "definitionID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "User_ID", + "definitionName": { + "value": "User ID" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 2, + "fullyQualifiedName": "Predictive Intelligence Profiles.User ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "fe52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "user_id", + "storageFieldReferenceID": { + "type": "guid", + "value": "eceebc11-78ad-421f-a94f-020667aac6d4" + }, + "valueDefinitionID": "fe52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "User_ID", + "name": "User ID", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "email", + "localizedDescription": { + "value": "email" + }, + "definitionID": "fc52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Email", + "definitionName": { + "value": "Email" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 3, + "fullyQualifiedName": "Predictive Intelligence Profiles.Email", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "fc52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "email", + "storageFieldReferenceID": { + "type": "guid", + "value": "71e4d8c6-e3d4-430e-9c9f-7e56b092d36a" + }, + "valueDefinitionID": "fc52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Email", + "name": "Email", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Value_1", + "localizedDescription": { + "value": "Value_1" + }, + "definitionID": "ff52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Value_1", + "definitionName": { + "value": "Value 1" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 4, + "fullyQualifiedName": "Predictive Intelligence Profiles.Value 1", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "ff52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Value_1", + "storageFieldReferenceID": { + "type": "guid", + "value": "8e0573f4-8bc8-4fb3-afc8-ad933a8d823b" + }, + "valueDefinitionID": "ff52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Value_1", + "name": "Value 1", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Value_2", + "localizedDescription": { + "value": "Value_2" + }, + "definitionID": "0053de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Value_2", + "definitionName": { + "value": "Value 2" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 5, + "fullyQualifiedName": "Predictive Intelligence Profiles.Value 2", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "0053de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 5, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Value_2", + "storageFieldReferenceID": { + "type": "guid", + "value": "dcf6690a-4fbe-418c-baa7-e1c50443560b" + }, + "valueDefinitionID": "0053de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Value_2", + "name": "Value 2", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Value_3", + "localizedDescription": { + "value": "Value_3" + }, + "definitionID": "0153de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Value_3", + "definitionName": { + "value": "Value 3" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 6, + "fullyQualifiedName": "Predictive Intelligence Profiles.Value 3", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "0153de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Value_3", + "storageFieldReferenceID": { + "type": "guid", + "value": "b2a7de94-c985-4337-afcc-445aa80c2ced" + }, + "valueDefinitionID": "0153de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Value_3", + "name": "Value 3", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Value_4", + "localizedDescription": { + "value": "Value_4" + }, + "definitionID": "0253de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Value_4", + "definitionName": { + "value": "Value 4" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 7, + "fullyQualifiedName": "Predictive Intelligence Profiles.Value 4", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "0253de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 7, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Value_4", + "storageFieldReferenceID": { + "type": "guid", + "value": "28984526-60dc-4768-aaff-4018d9842e77" + }, + "valueDefinitionID": "0253de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Value_4", + "name": "Value 4", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Value_5", + "localizedDescription": { + "value": "Value_5" + }, + "definitionID": "0353de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Value_5", + "definitionName": { + "value": "Value 5" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 8, + "fullyQualifiedName": "Predictive Intelligence Profiles.Value 5", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "0353de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 8, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Value_5", + "storageFieldReferenceID": { + "type": "guid", + "value": "aa50e6f3-6863-41fa-a536-8ed1d0fca989" + }, + "valueDefinitionID": "0353de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Value_5", + "name": "Value 5", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Attribute_1", + "localizedDescription": { + "value": "Attribute_1" + }, + "definitionID": "f552de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Attribute_1", + "definitionName": { + "value": "Attribute 1" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 9, + "fullyQualifiedName": "Predictive Intelligence Profiles.Attribute 1", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f552de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 9, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Attribute_1", + "storageFieldReferenceID": { + "type": "guid", + "value": "16934a3e-d869-4b8c-b817-48ff5b554f30" + }, + "valueDefinitionID": "f552de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Attribute_1", + "name": "Attribute 1", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Attribute_2", + "localizedDescription": { + "value": "Attribute_2" + }, + "definitionID": "f652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Attribute_2", + "definitionName": { + "value": "Attribute 2" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 10, + "fullyQualifiedName": "Predictive Intelligence Profiles.Attribute 2", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f652de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 10, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Attribute_2", + "storageFieldReferenceID": { + "type": "guid", + "value": "121ce628-61aa-4344-91b1-7f27413a16e5" + }, + "valueDefinitionID": "f652de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Attribute_2", + "name": "Attribute 2", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Attribute_3", + "localizedDescription": { + "value": "Attribute_3" + }, + "definitionID": "f752de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Attribute_3", + "definitionName": { + "value": "Attribute 3" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 11, + "fullyQualifiedName": "Predictive Intelligence Profiles.Attribute 3", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f752de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 11, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Attribute_3", + "storageFieldReferenceID": { + "type": "guid", + "value": "34e53678-e867-4526-9fd6-d31e2771a003" + }, + "valueDefinitionID": "f752de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Attribute_3", + "name": "Attribute 3", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Attribute_4", + "localizedDescription": { + "value": "Attribute_4" + }, + "definitionID": "f852de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Attribute_4", + "definitionName": { + "value": "Attribute 4" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 12, + "fullyQualifiedName": "Predictive Intelligence Profiles.Attribute 4", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f852de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 12, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Attribute_4", + "storageFieldReferenceID": { + "type": "guid", + "value": "b3efb625-de9a-4eef-b6eb-6add451d2f7a" + }, + "valueDefinitionID": "f852de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Attribute_4", + "name": "Attribute 4", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "Attribute_5", + "localizedDescription": { + "value": "Attribute_5" + }, + "definitionID": "f952de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Attribute_5", + "definitionName": { + "value": "Attribute 5" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 13, + "fullyQualifiedName": "Predictive Intelligence Profiles.Attribute 5", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "f952de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 13, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "Attribute_5", + "storageFieldReferenceID": { + "type": "guid", + "value": "f4836380-72eb-49c2-a8af-5a283d168683" + }, + "valueDefinitionID": "f952de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Attribute_5", + "name": "Attribute 5", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "city", + "localizedDescription": { + "value": "city" + }, + "definitionID": "fa52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "City", + "definitionName": { + "value": "City" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 14, + "fullyQualifiedName": "Predictive Intelligence Profiles.City", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "fa52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 14, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "city", + "storageFieldReferenceID": { + "type": "guid", + "value": "486ae151-74f7-4b98-ba9b-6ad927399de9" + }, + "valueDefinitionID": "fa52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "City", + "name": "City", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "region", + "localizedDescription": { + "value": "region" + }, + "definitionID": "fd52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Region", + "definitionName": { + "value": "Region" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 15, + "fullyQualifiedName": "Predictive Intelligence Profiles.Region", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "fd52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 15, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "region", + "storageFieldReferenceID": { + "type": "guid", + "value": "4b8bb8f1-0bcb-4201-9c26-fdd8e10c7ad8" + }, + "valueDefinitionID": "fd52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Region", + "name": "Region", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + { + "baseType": "Text", + "dataSourceID": 5, + "dataSourceName": {}, + "dataType": "Text", + "description": "country", + "localizedDescription": { + "value": "country" + }, + "definitionID": "fb52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Country", + "definitionName": { + "value": "Country" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "displayOrder": 16, + "fullyQualifiedName": "Predictive Intelligence Profiles.Country", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 256, + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageTypeID": 1, + "storageType": "Plain", + "valueDefinitionID": "fb52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 16, + "parentDefinition": { + "definitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "PredictiveIntelProfiles", + "definitionName": { + "value": "Predictive Intelligence Profiles" + }, + "connectingID": { + "identifierType": "FullyQualifiedName" + } + }, + "parentType": "Set", + "storageName": "country", + "storageFieldReferenceID": { + "type": "guid", + "value": "f9e65e6a-45dc-4f08-9a44-715e6e4763f7" + }, + "valueDefinitionID": "fb52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Country", + "name": "Country", + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "setDefinitionName": { + "value": "Predictive Intelligence Profiles" + }, + "parentIdentifier": "f452de3f-31e2-e611-80cc-1402ec7222b4" + } + ], + "applicationID": "f4981f88-a13e-4abf-b331-47f41c73258d", + "applicationKey": "com.exacttarget.Predictive Web", + "attributeCount": 0, + "canAddValues": false, + "canChangeValues": false, + "canModify": false, + "canRemove": false, + "categoryID": 386, + "createdBy": -1000, + "createDate": "2017-01-24T06:33:00", + "customObjectOwnerMID": 1111111, + "dataRetentionProperties": { + "isRowBasedRetention": false, + "isResetRetentionPeriodOnImport": false, + "isDeleteAtEndOfRetentionPeriod": false, + "periodUnitOfMeasure": 4, + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4" + }, + "localizedDescription": {}, + "fullyQualifiedName": "Predictive Intelligence Profiles", + "isCustomObjectBacked": true, + "isEvent": false, + "isHidden": false, + "isReadOnly": true, + "isRoot": false, + "isSendable": false, + "isShared": false, + "isSystemDefined": true, + "isTestaable": false, + "parentID": "00000000-0000-0000-0000-000000000000", + "relationshipCount": 5, + "storageLogicalType": "DataExtension", + "storageName": "IGO_PROFILES", + "storageObjectIDs": ["e352de3f-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "d452de3f-31e2-e611-80cc-1402ec7222b4" + }, + "setDefinitionID": "f452de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "PredictiveIntelProfiles", + "name": "Predictive Intelligence Profiles" + } + ], + "responseContext": { + "operationStatus": "OK", + "schemaType": "Contacts", + "populateInternalProperties": false + }, + "requestServiceMessageID": "ae488366-fa20-449a-ba74-ee353a7ab446", + "responseDateTime": "2023-07-12T09:17:32.1332068-06:00", + "resultMessages": [], + "serviceMessageID": "3206d5b6-f603-4049-bce8-6afce627a7c6" +} diff --git a/test/type.attributeSet.test.js b/test/type.attributeSet.test.js new file mode 100644 index 000000000..168623c83 --- /dev/null +++ b/test/type.attributeSet.test.js @@ -0,0 +1,54 @@ +const chai = require('chai'); +const chaiFiles = require('chai-files'); + +chai.use(chaiFiles); + +const assert = chai.assert; +const cache = require('../lib/util/cache'); +const testUtils = require('./utils'); +const handler = require('../lib/index'); + +describe('type: attributeSet', () => { + beforeEach(() => { + testUtils.mockSetup(); + }); + afterEach(() => { + testUtils.mockReset(); + }); + describe('Retrieve ================', () => { + it('Should retrieve a attributeSet', async () => { + // WHEN + const retrieve = await handler.retrieve('testInstance/testBU', ['attributeSet']); + + // THEN + assert.equal(process.exitCode, false, 'retrieve should not have thrown an error'); + assert.equal( + retrieve['testInstance/testBU'].attributeSet + ? Object.keys(retrieve['testInstance/testBU'].attributeSet).length + : 0, + 27, + 'only 27 attributeSets expected in retrieve response' + ); + // get results from cache + const result = cache.getCache(); + assert.equal( + result.attributeSet ? Object.keys(result.attributeSet).length : 0, + 27, + 'only 27 attributeSets expected in cache' + ); + assert.deepEqual( + await testUtils.getActualJson('Contact', 'attributeSet'), + await testUtils.getExpectedJson('9999999', 'attributeSet', 'retrieve'), + + 'returned metadata was not equal expected' + ); + + assert.equal( + testUtils.getAPIHistoryLength(), + 7, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + }); +}); From 301de3f205412ad153e928c2ed3a109a6944f310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 13 Jul 2023 15:46:38 +0200 Subject: [PATCH 107/208] #711: test for attributeGroup added --- .../attributeGroup/retrieve-expected.json | 25 +++++++++ test/type.attributeGroup.test.js | 55 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 test/resources/9999999/attributeGroup/retrieve-expected.json create mode 100644 test/type.attributeGroup.test.js diff --git a/test/resources/9999999/attributeGroup/retrieve-expected.json b/test/resources/9999999/attributeGroup/retrieve-expected.json new file mode 100644 index 000000000..f3bc7c5df --- /dev/null +++ b/test/resources/9999999/attributeGroup/retrieve-expected.json @@ -0,0 +1,25 @@ +{ + "applicationKey": "com.exacttarget.mobileconnect", + "attributeCount": 37, + "attributeGroupIconKey": "Mobile", + "attributeGroupType": "Standard", + "attributeSetIdentifiers": ["MobileDemographics", "MobileSubscriptions"], + "canAddProperties": false, + "canAddRelationships": true, + "canChangeProperties": false, + "canModify": false, + "canRemove": false, + "definitionKey": "ETMobileConnect", + "definitionName": { + "value": "MobileConnect Data" + }, + "description": "", + "displayOrder": 4, + "isHidden": false, + "isOwner": true, + "isSystemDefined": true, + "requiredRelationships": [ + "4651de3f-31e2-e611-80cc-1402ec7222b4", + "4352de3f-31e2-e611-80cc-1402ec7222b4" + ] +} diff --git a/test/type.attributeGroup.test.js b/test/type.attributeGroup.test.js new file mode 100644 index 000000000..49ff53a13 --- /dev/null +++ b/test/type.attributeGroup.test.js @@ -0,0 +1,55 @@ +const chai = require('chai'); +const chaiFiles = require('chai-files'); + +chai.use(chaiFiles); + +const assert = chai.assert; +const cache = require('../lib/util/cache'); +const testUtils = require('./utils'); +const handler = require('../lib/index'); + +describe('type: attributeGroup', () => { + beforeEach(() => { + testUtils.mockSetup(); + }); + afterEach(() => { + testUtils.mockReset(); + }); + describe('Retrieve ================', () => { + it('Should retrieve a attributeGroup', async () => { + // WHEN + const retrieve = await handler.retrieve('testInstance/testBU', ['attributeGroup']); + + // THEN + assert.equal(process.exitCode, false, 'retrieve should not have thrown an error'); + assert.equal( + retrieve['testInstance/testBU'].attributeGroup + ? Object.keys(retrieve['testInstance/testBU'].attributeGroup).length + : 0, + 7, + 'only 7 attributeGroups expected in retrieve response' + ); + + // get results from cache + const result = cache.getCache(); + assert.equal( + result.attributeGroup ? Object.keys(result.attributeGroup).length : 0, + 7, + 'only 7 attributeGroups expected in cache' + ); + assert.deepEqual( + await testUtils.getActualJson('ETMobileConnect', 'attributeGroup'), + await testUtils.getExpectedJson('9999999', 'attributeGroup', 'retrieve'), + + 'returned metadata was not equal expected' + ); + + assert.equal( + testUtils.getAPIHistoryLength(), + 2, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + }); +}); From 67093b5e67598e4ad5a1a06c99047ff036413f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 13 Jul 2023 15:48:25 +0200 Subject: [PATCH 108/208] #711: improved attributeSet test --- .../attributeSet/retrieve-expected.json | 743 ++++++++++++++++-- test/type.attributeSet.test.js | 3 +- 2 files changed, 664 insertions(+), 82 deletions(-) diff --git a/test/resources/9999999/attributeSet/retrieve-expected.json b/test/resources/9999999/attributeSet/retrieve-expected.json index fd1214b50..cf01d6710 100644 --- a/test/resources/9999999/attributeSet/retrieve-expected.json +++ b/test/resources/9999999/attributeSet/retrieve-expected.json @@ -1,6 +1,6 @@ { - "applicationID": "ce703ed3-e01f-4f5f-900d-76a95b363e29", - "applicationKey": "com.exacttarget.contacts", + "applicationID": "e25893f9-08f3-480f-8def-7f8ab0583611", + "applicationKey": "com.exacttarget.mobileconnect", "attributeCount": 0, "canAddValues": false, "canChangeValues": false, @@ -8,160 +8,741 @@ "canRemove": false, "createDate": "2017-01-24T06:33:00", "createdBy": -1000, - "definitionKey": "Contact", - "isCustomObjectBacked": false, + "dataRetentionProperties": { + "isDeleteAtEndOfRetentionPeriod": false, + "isResetRetentionPeriodOnImport": false, + "isRowBasedRetention": false, + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4" + }, + "definitionKey": "MobileSubscriptions", + "isCustomObjectBacked": true, "isEvent": false, "isHidden": false, - "isReadOnly": true, + "isReadOnly": false, "isRoot": false, "isSendable": false, + "isShared": false, "isSystemDefined": true, + "isTestaable": false, "localizedDescription": {}, - "name": "Contact", + "name": "MobileConnect Subscriptions", "parentID": "00000000-0000-0000-0000-000000000000", - "relationshipCount": 1, - "relationships": [ - { - "canModify": false, - "canRemove": false, - "isGroupToSetRelationship": true, - "isHidden": false, - "isSystemDefined": false, - "leftItem": { - "cardinality": "One", - "r__attributeGroup_definitionKey": "ETSystem", - "relationshipType": "AttributeGroup" - }, - "leftRelationshipIDs": [ - { - "type": "int16", - "value": "2" - } - ], - "leftRelationshipReferenceType": "CustomerData", - "relationshipAttributes": [ - { - "c__leftFullyQualifiedName": "Contact.Contact ID", - "c__rightFullyQualifiedName": "Contact.Contact ID" - } - ], - "relationshipID": "9893dc39-31e2-e611-80cc-1402ec7222b4", - "rightItem": { - "cardinality": "One", - "r__attributeSet_definitionKey": "Contact", - "relationshipType": "AttributeSet" - } - } - ], - "setDefinitionID": "9093dc39-31e2-e611-80cc-1402ec7222b4", - "setDefinitionKey": "Contact", - "storageObjectIDs": ["2ba72136-9f31-4a79-ab62-4ba5d19cd759"], + "r__folder_Path": "Data Extensions", + "relationshipCount": 0, + "setDefinitionID": "3152de3f-31e2-e611-80cc-1402ec7222b4", + "setDefinitionKey": "MobileSubscriptions", + "storageLogicalType": "DataExtension", + "storageName": "_MobileSubscription", + "storageObjectIDs": ["2252de3f-31e2-e611-80cc-1402ec7222b4"], + "storageReferenceID": { + "type": "guid", + "value": "7793dc39-31e2-e611-80cc-1402ec7222b4" + }, "valueDefinitions": [ { "baseType": "Numeric", "connectingID": { "identifierType": "FullyQualifiedName" }, - "customerDataID": 2, - "dataSourceID": 1, + "dataSourceID": 3, "dataSourceName": {}, - "dataType": "Number", - "definitionID": "9293dc39-31e2-e611-80cc-1402ec7222b4", - "definitionKey": "ContactID", + "dataType": "LongNumber", + "definitionID": "3252de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedBy", "definitionName": { - "value": "Contact ID" + "value": "Created By" }, "description": "", - "fullyQualifiedName": "Contact.Contact ID", + "displayOrder": 1, + "fullyQualifiedName": "MobileConnect Subscriptions.Created By", + "isHidden": true, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "localizedDescription": { + "value": "" + }, + "name": "Created By", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3252de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 1, + "parentType": "Set", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "a64a3ed9-b8fd-46cc-a10b-1d5fdf074ce6" + }, + "storageName": "_CreatedBy", + "valueDefinitionID": "3252de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedBy" + }, + { + "baseType": "Date", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "definitionID": "3352de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "CreatedDate", + "definitionName": { + "value": "Created Date" + }, + "description": "", + "displayOrder": 2, + "fullyQualifiedName": "MobileConnect Subscriptions.Created Date", "isHidden": false, "isIdentityValue": false, "isNullable": false, - "isPrimaryKey": true, + "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "localizedDescription": { "value": "" }, - "name": "Contact ID", + "name": "Created Date", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3352de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 2, "parentType": "Set", "setDefinitionName": { - "value": "Contact" + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "dfc3f6fb-a250-4ef8-93ed-bb079ced468d" }, - "storageName": "SubscriberID", - "valueDefinitionID": "9293dc39-31e2-e611-80cc-1402ec7222b4", - "valueDefinitionKey": "ContactID" + "storageName": "_CreatedDate", + "valueDefinitionID": "3352de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "CreatedDate" }, { "baseType": "Text", "connectingID": { "identifierType": "FullyQualifiedName" }, - "customerDataID": 3, - "dataSourceID": 1, + "dataSourceID": 3, "dataSourceName": {}, "dataType": "Text", - "definitionID": "9393dc39-31e2-e611-80cc-1402ec7222b4", - "definitionKey": "ContactKey", + "definitionID": "3f52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "SubscriptionDefinitionID", + "definitionName": { + "value": "Keyword" + }, + "description": "", + "displayOrder": 3, + "fullyQualifiedName": "MobileConnect Subscriptions.Keyword", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "localizedDescription": { + "value": "" + }, + "name": "Keyword", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3f52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 3, + "parentType": "Set", + "restrictionLookupListID": 7, + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "c13ab46d-6e65-475a-990d-291bd43e5063" + }, + "storageName": "_SubscriptionDefinitionID", + "valueDefinitionID": "3f52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "SubscriptionDefinitionID" + }, + { + "baseType": "Text", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Phone", + "definitionID": "3452de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "MobileNumber", "definitionName": { - "value": "Contact Key" + "value": "Mobile Number" }, "description": "", - "fullyQualifiedName": "Contact.Contact Key", + "displayOrder": 4, + "fullyQualifiedName": "MobileConnect Subscriptions.Mobile Number", "isHidden": false, "isIdentityValue": false, "isNullable": false, + "isPrimaryKey": true, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 15, + "localizedDescription": { + "value": "" + }, + "name": "Mobile Number", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3452de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 4, + "parentType": "Set", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "ead8a6d2-bc6c-4768-a6e3-c3cc749bfc1d" + }, + "storageName": "_MobileNumber", + "valueDefinitionID": "3452de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "MobileNumber" + }, + { + "baseType": "Numeric", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "LongNumber", + "definitionID": "53dd5f89-bca1-ed11-b852-48df37d1df5b", + "definitionKey": "MobileSubscriptionID", + "definitionName": { + "value": "Mobile Subscription ID" + }, + "description": "", + "displayOrder": 5, + "fullyQualifiedName": "MobileConnect Subscriptions.Mobile Subscription ID", + "isHidden": true, + "isIdentityValue": true, + "isNullable": false, "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, - "length": -1, "localizedDescription": { "value": "" }, - "name": "Contact Key", + "name": "Mobile Subscription ID", + "ordinal": 5, "parentType": "Set", "setDefinitionName": { - "value": "Contact" + "value": "MobileConnect Subscriptions" }, - "storageName": "SubscriberKey", - "valueDefinitionID": "9393dc39-31e2-e611-80cc-1402ec7222b4", - "valueDefinitionKey": "ContactKey" + "storageName": "_MobileSubscriptionID", + "valueDefinitionID": "53dd5f89-bca1-ed11-b852-48df37d1df5b", + "valueDefinitionKey": "MobileSubscriptionID" }, { "baseType": "Numeric", "connectingID": { "identifierType": "FullyQualifiedName" }, - "customerDataID": 1, - "dataSourceID": 1, + "dataSourceID": 3, "dataSourceName": {}, - "dataType": "Number", - "definitionID": "9193dc39-31e2-e611-80cc-1402ec7222b4", - "definitionKey": "BusinessUnitID", + "dataType": "LongNumber", + "definitionID": "3552de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedBy", "definitionName": { - "value": "Business Unit ID" + "value": "Modified By" }, "description": "", - "fullyQualifiedName": "Contact.Business Unit ID", + "displayOrder": 6, + "fullyQualifiedName": "MobileConnect Subscriptions.Modified By", "isHidden": true, "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "localizedDescription": { + "value": "" + }, + "name": "Modified By", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3552de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 6, + "parentType": "Set", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "30d7ec39-85d1-46dc-9888-771f11ffe10d" + }, + "storageName": "_ModifiedBy", + "valueDefinitionID": "3552de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedBy" + }, + { + "baseType": "Date", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "defaultValue": "GETDATE()", + "definitionID": "3652de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "ModifiedDate", + "definitionName": { + "value": "Modified Date" + }, + "description": "", + "displayOrder": 7, + "fullyQualifiedName": "MobileConnect Subscriptions.Modified Date", + "isHidden": false, + "isIdentityValue": false, "isNullable": false, - "isPrimaryKey": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "localizedDescription": { + "value": "" + }, + "name": "Modified Date", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3652de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 7, + "parentType": "Set", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "b68155cc-e483-4949-82f9-fb47cbd59764" + }, + "storageName": "_ModifiedDate", + "valueDefinitionID": "3652de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "ModifiedDate" + }, + { + "baseType": "Date", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "definitionID": "3752de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInDate", + "definitionName": { + "value": "Opt In Date" + }, + "description": "", + "displayOrder": 8, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt In Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, "isReadOnly": true, "isSystemDefined": true, "isUpdateable": false, "localizedDescription": { "value": "" }, - "name": "Business Unit ID", + "name": "Opt In Date", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3752de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 8, "parentType": "Set", "setDefinitionName": { - "value": "Contact" + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "8da557ee-7ba7-44f4-99ba-0681cbeb1ba1" + }, + "storageName": "_OptInDate", + "valueDefinitionID": "3752de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInDate" + }, + { + "baseType": "Numeric", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "definitionID": "3852de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInMethodID", + "definitionName": { + "value": "Opt In Method" + }, + "description": "", + "displayOrder": 9, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt In Method", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "localizedDescription": { + "value": "" + }, + "name": "Opt In Method", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3852de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 9, + "parentType": "Set", + "restrictionLookupListID": 2, + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "da2713ab-a802-4cd6-9e05-0a7444d62388" + }, + "storageName": "_OptInMethodID", + "valueDefinitionID": "3852de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInMethodID" + }, + { + "baseType": "Numeric", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "definitionID": "3952de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptInStatusID", + "definitionName": { + "value": "Opt In Status" + }, + "description": "", + "displayOrder": 10, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt In Status", + "isHidden": false, + "isIdentityValue": false, + "isNullable": false, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "localizedDescription": { + "value": "" + }, + "name": "Opt In Status", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3952de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 10, + "parentType": "Set", + "restrictionLookupListID": 1, + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "c733b80d-2ed5-4fb6-94a3-9c996cbae558" + }, + "storageName": "_OptInStatusID", + "valueDefinitionID": "3952de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptInStatusID" + }, + { + "baseType": "Date", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Date", + "definitionID": "3a52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptOutDate", + "definitionName": { + "value": "Opt Out Date" + }, + "description": "", + "displayOrder": 11, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt Out Date", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "localizedDescription": { + "value": "" + }, + "name": "Opt Out Date", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3a52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 11, + "parentType": "Set", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "27c3ccec-47ad-4578-9051-a41f85178049" + }, + "storageName": "_OptOutDate", + "valueDefinitionID": "3a52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptOutDate" + }, + { + "baseType": "Numeric", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "definitionID": "3b52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptOutMethodID", + "definitionName": { + "value": "Opt Out Method" + }, + "description": "", + "displayOrder": 12, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt Out Method", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "localizedDescription": { + "value": "" + }, + "name": "Opt Out Method", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3b52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 12, + "parentType": "Set", + "restrictionLookupListID": 4, + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "089b96fc-bfc6-402e-a481-1e18d3e18a8d" + }, + "storageName": "_OptOutMethodID", + "valueDefinitionID": "3b52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptOutMethodID" + }, + { + "baseType": "Numeric", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "definitionID": "3c52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "OptOutStatusID", + "definitionName": { + "value": "Opt Out Status" + }, + "description": "", + "displayOrder": 13, + "fullyQualifiedName": "MobileConnect Subscriptions.Opt Out Status", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": false, + "isSystemDefined": true, + "isUpdateable": false, + "localizedDescription": { + "value": "" + }, + "name": "Opt Out Status", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3c52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 13, + "parentType": "Set", + "restrictionLookupListID": 3, + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "67194503-acd8-4c1c-b042-9dfb3f3ebd44" + }, + "storageName": "_OptOutStatusID", + "valueDefinitionID": "3c52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "OptOutStatusID" + }, + { + "baseType": "Numeric", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Byte", + "definitionID": "3d52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "Source", + "definitionName": { + "value": "Source" + }, + "description": "", + "displayOrder": 14, + "fullyQualifiedName": "MobileConnect Subscriptions.Source", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "localizedDescription": { + "value": "" + }, + "name": "Source", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3d52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 14, + "parentType": "Set", + "restrictionLookupListID": 5, + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "2e903257-43e8-4a7b-8ed4-757ca772ddbb" + }, + "storageName": "_Source", + "valueDefinitionID": "3d52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "Source" + }, + { + "baseType": "Text", + "connectingID": { + "identifierType": "FullyQualifiedName" + }, + "dataSourceID": 3, + "dataSourceName": {}, + "dataType": "Text", + "definitionID": "3e52de3f-31e2-e611-80cc-1402ec7222b4", + "definitionKey": "SourceObjectID", + "definitionName": { + "value": "Source Object ID" + }, + "description": "", + "displayOrder": 15, + "fullyQualifiedName": "MobileConnect Subscriptions.Source Object ID", + "isHidden": false, + "isIdentityValue": false, + "isNullable": true, + "isPrimaryKey": false, + "isReadOnly": true, + "isSystemDefined": true, + "isUpdateable": false, + "length": 200, + "localizedDescription": { + "value": "" + }, + "name": "Source Object ID", + "obfuscationProperties": { + "maskType": "None", + "maskTypeID": 0, + "storageType": "Plain", + "storageTypeID": 1, + "valueDefinitionID": "3e52de3f-31e2-e611-80cc-1402ec7222b4" + }, + "ordinal": 15, + "parentType": "Set", + "setDefinitionName": { + "value": "MobileConnect Subscriptions" + }, + "storageFieldReferenceID": { + "type": "guid", + "value": "1d4f26f5-ec91-46de-9fc1-d819832f07e7" }, - "storageName": "ClientID", - "valueDefinitionID": "9193dc39-31e2-e611-80cc-1402ec7222b4", - "valueDefinitionKey": "BusinessUnitID" + "storageName": "_SourceObjectId", + "valueDefinitionID": "3e52de3f-31e2-e611-80cc-1402ec7222b4", + "valueDefinitionKey": "SourceObjectID" } ] } diff --git a/test/type.attributeSet.test.js b/test/type.attributeSet.test.js index 168623c83..d05ea88a0 100644 --- a/test/type.attributeSet.test.js +++ b/test/type.attributeSet.test.js @@ -36,8 +36,9 @@ describe('type: attributeSet', () => { 27, 'only 27 attributeSets expected in cache' ); + assert.deepEqual( - await testUtils.getActualJson('Contact', 'attributeSet'), + await testUtils.getActualJson('MobileSubscriptions', 'attributeSet'), await testUtils.getExpectedJson('9999999', 'attributeSet', 'retrieve'), 'returned metadata was not equal expected' From 4c77a41f3ac541701db9345227a2e8c31d479fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 13 Jul 2023 17:00:12 +0200 Subject: [PATCH 109/208] #843: add test class for type script --- .../testExisting_script.script-meta.json | 6 + .../testExisting_script.script-meta.ssjs | 1 + .../script/testNew_script.script-meta.json | 6 + .../script/testNew_script.script-meta.ssjs | 1 + .../patch-response.json | 10 + .../automation/v1/scripts/get-response.json | 4 +- .../automation/v1/scripts/post-response.json | 10 + ...ieve-ContentType=ssjsactivity-response.xml | 48 +++ .../9999999/script/build-expected.json | 6 + .../9999999/script/build-expected.ssjs | 1 + .../9999999/script/get-expected.json | 8 + .../9999999/script/get-expected.ssjs | 1 + .../9999999/script/patch-expected.json | 8 + .../9999999/script/patch-expected.ssjs | 1 + .../9999999/script/post-expected.json | 8 + .../9999999/script/post-expected.ssjs | 1 + .../9999999/script/template-expected.json | 6 + .../9999999/script/template-expected.ssjs | 1 + test/type.script.test.js | 324 ++++++++++++++++++ 19 files changed, 449 insertions(+), 2 deletions(-) create mode 100644 test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.json create mode 100644 test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.ssjs create mode 100644 test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.json create mode 100644 test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.ssjs create mode 100644 test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/patch-response.json create mode 100644 test/resources/9999999/automation/v1/scripts/post-response.json create mode 100644 test/resources/9999999/dataFolder/retrieve-ContentType=ssjsactivity-response.xml create mode 100644 test/resources/9999999/script/build-expected.json create mode 100644 test/resources/9999999/script/build-expected.ssjs create mode 100644 test/resources/9999999/script/get-expected.json create mode 100644 test/resources/9999999/script/get-expected.ssjs create mode 100644 test/resources/9999999/script/patch-expected.json create mode 100644 test/resources/9999999/script/patch-expected.ssjs create mode 100644 test/resources/9999999/script/post-expected.json create mode 100644 test/resources/9999999/script/post-expected.ssjs create mode 100644 test/resources/9999999/script/template-expected.json create mode 100644 test/resources/9999999/script/template-expected.ssjs create mode 100644 test/type.script.test.js diff --git a/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.json b/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.json new file mode 100644 index 000000000..cefd0e179 --- /dev/null +++ b/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.json @@ -0,0 +1,6 @@ +{ + "description": "updated on deploy", + "key": "testExisting_script", + "name": "testExisting_script", + "r__folder_Path": "Scripts" +} diff --git a/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.ssjs b/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.ssjs new file mode 100644 index 000000000..e20d1ee2d --- /dev/null +++ b/test/mockRoot/deploy/testInstance/testBU/script/testExisting_script.script-meta.ssjs @@ -0,0 +1 @@ +// dummy updated diff --git a/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.json b/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.json new file mode 100644 index 000000000..5a2f9b73a --- /dev/null +++ b/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.json @@ -0,0 +1,6 @@ +{ + "description": "created on deploy", + "key": "testNew_script", + "name": "testNew_script", + "r__folder_Path": "Scripts" +} diff --git a/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.ssjs b/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.ssjs new file mode 100644 index 000000000..bbfd28311 --- /dev/null +++ b/test/mockRoot/deploy/testInstance/testBU/script/testNew_script.script-meta.ssjs @@ -0,0 +1 @@ +// dummy created diff --git a/test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/patch-response.json b/test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/patch-response.json new file mode 100644 index 000000000..bffec43f9 --- /dev/null +++ b/test/resources/9999999/automation/v1/scripts/39f6a488-20eb-4ba0-b0b9-023725b574e4/patch-response.json @@ -0,0 +1,10 @@ +{ + "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", + "name": "testExisting_script", + "key": "testExisting_script", + "description": "updated on deploy", + "script": "", + "categoryId": 304, + "createdDate": "2022-10-20T00:41:26.163", + "modifiedDate": "2022-10-20T00:41:26.163" +} diff --git a/test/resources/9999999/automation/v1/scripts/get-response.json b/test/resources/9999999/automation/v1/scripts/get-response.json index d5830148f..15b0cac89 100644 --- a/test/resources/9999999/automation/v1/scripts/get-response.json +++ b/test/resources/9999999/automation/v1/scripts/get-response.json @@ -8,8 +8,8 @@ "name": "testExisting_script", "key": "testExisting_script", "description": "", - "script": "", + "categoryId": 304, "createdDate": "2022-10-20T00:41:26.163", "modifiedDate": "2022-10-20T00:41:26.163" } diff --git a/test/resources/9999999/automation/v1/scripts/post-response.json b/test/resources/9999999/automation/v1/scripts/post-response.json new file mode 100644 index 000000000..aeeb66322 --- /dev/null +++ b/test/resources/9999999/automation/v1/scripts/post-response.json @@ -0,0 +1,10 @@ +{ + "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-new", + "name": "testNew_script", + "key": "testNew_script", + "description": "created on deploy", + "script": "", + "categoryId": 304, + "createdDate": "2022-10-20T00:41:26.163", + "modifiedDate": "2022-10-20T00:41:26.163" +} diff --git a/test/resources/9999999/dataFolder/retrieve-ContentType=ssjsactivity-response.xml b/test/resources/9999999/dataFolder/retrieve-ContentType=ssjsactivity-response.xml new file mode 100644 index 000000000..65f4ad08a --- /dev/null +++ b/test/resources/9999999/dataFolder/retrieve-ContentType=ssjsactivity-response.xml @@ -0,0 +1,48 @@ + + + + RetrieveResponse + urn:uuid:f36f3303-3b5a-4641-8109-b26447634d91 + urn:uuid:33983968-28c4-4379-bb5f-f80ae32eb988 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2022-04-19T20:03:41Z + 2022-04-19T20:08:41Z + + + + + + OK + 02cd5ccb-8f84-4651-826f-71169eeecf05 + + + 9999999 + + + 2017-01-24T06:32:42.353 + 2017-01-24T06:32:42.353 + 304 + + SSJSActivity_default + + + 0 + + + Scripts + + SSJSActivity + true + false + true + + + + diff --git a/test/resources/9999999/script/build-expected.json b/test/resources/9999999/script/build-expected.json new file mode 100644 index 000000000..6daa00403 --- /dev/null +++ b/test/resources/9999999/script/build-expected.json @@ -0,0 +1,6 @@ +{ + "description": "", + "key": "testTemplated_script", + "name": "testTemplated_script", + "r__folder_Path": "Scripts" +} diff --git a/test/resources/9999999/script/build-expected.ssjs b/test/resources/9999999/script/build-expected.ssjs new file mode 100644 index 000000000..27c4b7e5c --- /dev/null +++ b/test/resources/9999999/script/build-expected.ssjs @@ -0,0 +1 @@ +//dummy diff --git a/test/resources/9999999/script/get-expected.json b/test/resources/9999999/script/get-expected.json new file mode 100644 index 000000000..6572bab64 --- /dev/null +++ b/test/resources/9999999/script/get-expected.json @@ -0,0 +1,8 @@ +{ + "createdDate": "2022-10-20T00:41:26.163", + "description": "", + "key": "testExisting_script", + "modifiedDate": "2022-10-20T00:41:26.163", + "name": "testExisting_script", + "r__folder_Path": "Scripts" +} diff --git a/test/resources/9999999/script/get-expected.ssjs b/test/resources/9999999/script/get-expected.ssjs new file mode 100644 index 000000000..27c4b7e5c --- /dev/null +++ b/test/resources/9999999/script/get-expected.ssjs @@ -0,0 +1 @@ +//dummy diff --git a/test/resources/9999999/script/patch-expected.json b/test/resources/9999999/script/patch-expected.json new file mode 100644 index 000000000..81f145a49 --- /dev/null +++ b/test/resources/9999999/script/patch-expected.json @@ -0,0 +1,8 @@ +{ + "createdDate": "2022-10-20T00:41:26.163", + "description": "updated on deploy", + "key": "testExisting_script", + "modifiedDate": "2022-10-20T00:41:26.163", + "name": "testExisting_script", + "r__folder_Path": "Scripts" +} diff --git a/test/resources/9999999/script/patch-expected.ssjs b/test/resources/9999999/script/patch-expected.ssjs new file mode 100644 index 000000000..e20d1ee2d --- /dev/null +++ b/test/resources/9999999/script/patch-expected.ssjs @@ -0,0 +1 @@ +// dummy updated diff --git a/test/resources/9999999/script/post-expected.json b/test/resources/9999999/script/post-expected.json new file mode 100644 index 000000000..a2389daac --- /dev/null +++ b/test/resources/9999999/script/post-expected.json @@ -0,0 +1,8 @@ +{ + "createdDate": "2022-10-20T00:41:26.163", + "description": "created on deploy", + "key": "testNew_script", + "modifiedDate": "2022-10-20T00:41:26.163", + "name": "testNew_script", + "r__folder_Path": "Scripts" +} diff --git a/test/resources/9999999/script/post-expected.ssjs b/test/resources/9999999/script/post-expected.ssjs new file mode 100644 index 000000000..bbfd28311 --- /dev/null +++ b/test/resources/9999999/script/post-expected.ssjs @@ -0,0 +1 @@ +// dummy created diff --git a/test/resources/9999999/script/template-expected.json b/test/resources/9999999/script/template-expected.json new file mode 100644 index 000000000..bd3ae9904 --- /dev/null +++ b/test/resources/9999999/script/template-expected.json @@ -0,0 +1,6 @@ +{ + "description": "", + "key": "{{{prefix}}}script", + "name": "{{{prefix}}}script", + "r__folder_Path": "Scripts" +} diff --git a/test/resources/9999999/script/template-expected.ssjs b/test/resources/9999999/script/template-expected.ssjs new file mode 100644 index 000000000..27c4b7e5c --- /dev/null +++ b/test/resources/9999999/script/template-expected.ssjs @@ -0,0 +1 @@ +//dummy diff --git a/test/type.script.test.js b/test/type.script.test.js new file mode 100644 index 000000000..838976a22 --- /dev/null +++ b/test/type.script.test.js @@ -0,0 +1,324 @@ +const chai = require('chai'); +const chaiFiles = require('chai-files'); +const assert = chai.assert; +chai.use(chaiFiles); +const expect = chai.expect; +const file = chaiFiles.file; +// const dir = chaiFiles.dir; +const cache = require('../lib/util/cache'); +const testUtils = require('./utils'); +const handler = require('../lib/index'); + +describe('type: script', () => { + beforeEach(() => { + testUtils.mockSetup(); + }); + afterEach(() => { + testUtils.mockReset(); + }); + + describe('Retrieve ================', () => { + it('Should retrieve all scripts', async () => { + // WHEN + const retrieve = await handler.retrieve('testInstance/testBU', ['script']); + // THEN + assert.equal(process.exitCode, false, 'retrieve should not have thrown an error'); + + // retrieve result + assert.equal( + retrieve['testInstance/testBU'].script + ? Object.keys(retrieve['testInstance/testBU'].script).length + : 0, + 1, + 'only 1 script expected in retrieve response' + ); + + // get results from cache + const result = cache.getCache(); + assert.equal( + result.script ? Object.keys(result.script).length : 0, + 1, + 'only 1 script expected' + ); + // normal test + assert.deepEqual( + await testUtils.getActualJson('testExisting_script', 'script'), + await testUtils.getExpectedJson('9999999', 'script', 'get'), + 'returned metadata with correct key was not equal expected' + ); + expect(file(testUtils.getActualFile('testExisting_script', 'script', 'ssjs'))).to.equal( + file(testUtils.getExpectedFile('9999999', 'script', 'get', 'ssjs')) + ); + + assert.equal( + testUtils.getAPIHistoryLength(), + 3, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + it('Should retrieve one specific script by key', async () => { + // WHEN + await handler.retrieve('testInstance/testBU', ['script'], ['testExisting_script']); + // THEN + assert.equal(process.exitCode, false, 'retrieve should not have thrown an error'); + // get results from cache + const result = cache.getCache(); + assert.equal( + result.script ? Object.keys(result.script).length : 0, + 1, + 'only one script expected' + ); + assert.deepEqual( + await testUtils.getActualJson('testExisting_script', 'script'), + await testUtils.getExpectedJson('9999999', 'script', 'get'), + 'returned metadata was not equal expected' + ); + expect(file(testUtils.getActualFile('testExisting_script', 'script', 'ssjs'))).to.equal( + file(testUtils.getExpectedFile('9999999', 'script', 'get', 'ssjs')) + ); + assert.equal( + testUtils.getAPIHistoryLength(), + 3, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + it('Should retrieve one specific script via --like', async () => { + // WHEN + handler.setOptions({ like: { key: '%Existing_script' } }); + await handler.retrieve('testInstance/testBU', ['script']); + // THEN + assert.equal(process.exitCode, false, 'retrieve should not have thrown an error'); + // get results from cache + const result = cache.getCache(); + assert.equal( + result.script ? Object.keys(result.script).length : 0, + 1, + 'one script in cache expected' + ); + assert.deepEqual( + await testUtils.getActualJson('testExisting_script', 'script'), + await testUtils.getExpectedJson('9999999', 'script', 'get'), + 'returned metadata was not equal expected' + ); + expect(file(testUtils.getActualFile('testExisting_script', 'script', 'ssjs'))).to.equal( + file(testUtils.getExpectedFile('9999999', 'script', 'get', 'ssjs')) + ); + assert.equal( + testUtils.getAPIHistoryLength(), + 3, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + it('Should not retrieve any script via --like and key due to a mismatching filter', async () => { + // WHEN + handler.setOptions({ like: { key: 'NotExisting_script' } }); + await handler.retrieve('testInstance/testBU', ['script']); + // THEN + assert.equal(process.exitCode, false, 'retrieve should not have thrown an error'); + // get results from cache + const result = cache.getCache(); + assert.equal( + result.script ? Object.keys(result.script).length : 0, + 1, + 'one script in cache expected' + ); + + expect(file(testUtils.getActualFile('testExisting_script', 'script', 'ssjs'))).to.not + .exist; + assert.equal( + testUtils.getAPIHistoryLength(), + 3, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + }); + describe('Deploy ================', () => { + beforeEach(() => { + testUtils.mockSetup(true); + }); + it('Should create & upsert a script', async () => { + // WHEN + await handler.deploy('testInstance/testBU', ['script']); + // THEN + assert.equal(process.exitCode, false, 'deploy should not have thrown an error'); + // get results from cache + const result = cache.getCache(); + assert.equal( + result.script ? Object.keys(result.script).length : 0, + 2, + 'two scripts expected' + ); + // confirm created item + assert.deepEqual( + await testUtils.getActualJson('testNew_script', 'script'), + await testUtils.getExpectedJson('9999999', 'script', 'post'), + 'returned metadata was not equal expected for insert script' + ); + expect(file(testUtils.getActualFile('testNew_script', 'script', 'ssjs'))).to.equal( + file(testUtils.getExpectedFile('9999999', 'script', 'post', 'ssjs')) + ); + // confirm updated item + assert.deepEqual( + await testUtils.getActualJson('testExisting_script', 'script'), + await testUtils.getExpectedJson('9999999', 'script', 'patch'), + 'returned metadata was not equal expected for insert script' + ); + expect(file(testUtils.getActualFile('testExisting_script', 'script', 'ssjs'))).to.equal( + file(testUtils.getExpectedFile('9999999', 'script', 'patch', 'ssjs')) + ); + // check number of API calls + assert.equal( + testUtils.getAPIHistoryLength(), + 5, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + }); + describe('Templating ================', () => { + it('Should create a script template via retrieveAsTemplate and build it', async () => { + // GIVEN there is a template + const result = await handler.retrieveAsTemplate( + 'testInstance/testBU', + 'script', + ['testExisting_script'], + 'testSourceMarket' + ); + // WHEN + assert.equal( + process.exitCode, + false, + 'retrieveAsTemplate should not have thrown an error' + ); + assert.equal( + result.script ? Object.keys(result.script).length : 0, + 1, + 'only one script expected' + ); + assert.deepEqual( + await testUtils.getActualTemplateJson('testExisting_script', 'script'), + await testUtils.getExpectedJson('9999999', 'script', 'template'), + 'returned template JSON of retrieveAsTemplate was not equal expected' + ); + expect( + file(testUtils.getActualTemplateFile('testExisting_script', 'script', 'ssjs')) + ).to.equal(file(testUtils.getExpectedFile('9999999', 'script', 'template', 'ssjs'))); + // THEN + await handler.buildDefinition( + 'testInstance/testBU', + 'script', + 'testExisting_script', + 'testTargetMarket' + ); + assert.equal( + process.exitCode, + false, + 'buildDefinition should not have thrown an error' + ); + + assert.deepEqual( + await testUtils.getActualDeployJson('testTemplated_script', 'script'), + await testUtils.getExpectedJson('9999999', 'script', 'build'), + 'returned deployment JSON was not equal expected' + ); + expect( + file(testUtils.getActualDeployFile('testTemplated_script', 'script', 'ssjs')) + ).to.equal(file(testUtils.getExpectedFile('9999999', 'script', 'build', 'ssjs'))); + + assert.equal( + testUtils.getAPIHistoryLength(), + 3, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + it('Should create a script template via buildTemplate and build it', async () => { + // download first before we test buildTemplate + await handler.retrieve('testInstance/testBU', ['script']); + // GIVEN there is a template + const result = await handler.buildTemplate( + 'testInstance/testBU', + 'script', + ['testExisting_script'], + 'testSourceMarket' + ); + // WHEN + assert.equal(process.exitCode, false, 'buildTemplate should not have thrown an error'); + + assert.equal( + result.script ? Object.keys(result.script).length : 0, + 1, + 'only one script expected' + ); + assert.deepEqual( + await testUtils.getActualTemplateJson('testExisting_script', 'script'), + await testUtils.getExpectedJson('9999999', 'script', 'template'), + 'returned template JSON of buildTemplate was not equal expected' + ); + expect( + file(testUtils.getActualTemplateFile('testExisting_script', 'script', 'ssjs')) + ).to.equal(file(testUtils.getExpectedFile('9999999', 'script', 'template', 'ssjs'))); + // THEN + await handler.buildDefinition( + 'testInstance/testBU', + 'script', + 'testExisting_script', + 'testTargetMarket' + ); + assert.equal( + process.exitCode, + false, + 'buildDefinition should not have thrown an error' + ); + + assert.deepEqual( + await testUtils.getActualDeployJson('testTemplated_script', 'script'), + await testUtils.getExpectedJson('9999999', 'script', 'build'), + 'returned deployment JSON was not equal expected' + ); + expect( + file(testUtils.getActualDeployFile('testTemplated_script', 'script', 'ssjs')) + ).to.equal(file(testUtils.getExpectedFile('9999999', 'script', 'build', 'ssjs'))); + + assert.equal( + testUtils.getAPIHistoryLength(), + 3, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); + }); + describe('Delete ================', () => {}); + describe('CI/CD ================', () => { + it('Should return a list of files based on their type and key', async () => { + // WHEN + const fileList = await handler.getFilesToCommit('testInstance/testBU', 'script', [ + 'testExisting_script', + ]); + // THEN + assert.equal( + process.exitCode, + false, + 'getFilesToCommit should not have thrown an error' + ); + assert.equal(fileList.length, 3, 'expected only 3 file paths (html, json, ssjs)'); + + assert.equal( + fileList[0].split('\\').join('/'), + 'retrieve/testInstance/testBU/script/testExisting_script.script-meta.json', + 'wrong JSON path' + ); + assert.equal( + fileList[1].split('\\').join('/'), + 'retrieve/testInstance/testBU/script/testExisting_script.script-meta.ssjs', + 'wrong JSON path' + ); + return; + }); + }); + describe('Execute ================', () => {}); +}); From fd4a6e7a2141d00aa35b73527edc58800e441a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Thu, 13 Jul 2023 17:21:34 +0200 Subject: [PATCH 110/208] #843: add test for scripts without valid ssjs --- .../automation/v1/scripts/get-response.json | 10 +++ .../script/get_noScriptTag-expected.html | 1 + .../script/get_noScriptTag-expected.json | 8 +++ test/type.script.test.js | 63 ++++++++++++++++--- 4 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 test/resources/9999999/script/get_noScriptTag-expected.html create mode 100644 test/resources/9999999/script/get_noScriptTag-expected.json diff --git a/test/resources/9999999/automation/v1/scripts/get-response.json b/test/resources/9999999/automation/v1/scripts/get-response.json index 15b0cac89..d928b6361 100644 --- a/test/resources/9999999/automation/v1/scripts/get-response.json +++ b/test/resources/9999999/automation/v1/scripts/get-response.json @@ -12,6 +12,16 @@ "categoryId": 304, "createdDate": "2022-10-20T00:41:26.163", "modifiedDate": "2022-10-20T00:41:26.163" + }, + { + "ssjsActivityId": "39f6a488-20eb-4ba0-b0b9-noScriptTag", + "name": "testExisting_script_noScriptTag", + "key": "testExisting_script_noScriptTag", + "description": "", + "script": "// no script tag\n", + "categoryId": 304, + "createdDate": "2022-10-20T00:41:26.163", + "modifiedDate": "2022-10-20T00:41:26.163" } ] } diff --git a/test/resources/9999999/script/get_noScriptTag-expected.html b/test/resources/9999999/script/get_noScriptTag-expected.html new file mode 100644 index 000000000..634388fcc --- /dev/null +++ b/test/resources/9999999/script/get_noScriptTag-expected.html @@ -0,0 +1 @@ +// no script tag diff --git a/test/resources/9999999/script/get_noScriptTag-expected.json b/test/resources/9999999/script/get_noScriptTag-expected.json new file mode 100644 index 000000000..f6090804f --- /dev/null +++ b/test/resources/9999999/script/get_noScriptTag-expected.json @@ -0,0 +1,8 @@ +{ + "createdDate": "2022-10-20T00:41:26.163", + "description": "", + "key": "testExisting_script_noScriptTag", + "modifiedDate": "2022-10-20T00:41:26.163", + "name": "testExisting_script_noScriptTag", + "r__folder_Path": "Scripts" +} diff --git a/test/type.script.test.js b/test/type.script.test.js index 838976a22..84202cfec 100644 --- a/test/type.script.test.js +++ b/test/type.script.test.js @@ -29,16 +29,16 @@ describe('type: script', () => { retrieve['testInstance/testBU'].script ? Object.keys(retrieve['testInstance/testBU'].script).length : 0, - 1, - 'only 1 script expected in retrieve response' + 2, + 'only 2 scripts expected in retrieve response' ); // get results from cache const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, - 1, - 'only 1 script expected' + 2, + 'only 2 scripts expected' ); // normal test assert.deepEqual( @@ -46,10 +46,26 @@ describe('type: script', () => { await testUtils.getExpectedJson('9999999', 'script', 'get'), 'returned metadata with correct key was not equal expected' ); + expect(file(testUtils.getActualFile('testExisting_script', 'script', 'html'))).to.not + .exist; expect(file(testUtils.getActualFile('testExisting_script', 'script', 'ssjs'))).to.equal( file(testUtils.getExpectedFile('9999999', 'script', 'get', 'ssjs')) ); + assert.deepEqual( + await testUtils.getActualJson('testExisting_script_noScriptTag', 'script'), + await testUtils.getExpectedJson('9999999', 'script', 'get_noScriptTag'), + 'returned metadata was not equal expected' + ); + expect( + file(testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'html')) + ).to.equal( + file(testUtils.getExpectedFile('9999999', 'script', 'get_noScriptTag', 'html')) + ); + expect( + file(testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'ssjs')) + ).to.not.exist; + assert.equal( testUtils.getAPIHistoryLength(), 3, @@ -74,9 +90,22 @@ describe('type: script', () => { await testUtils.getExpectedJson('9999999', 'script', 'get'), 'returned metadata was not equal expected' ); + expect(file(testUtils.getActualFile('testExisting_script', 'script', 'html'))).to.not + .exist; expect(file(testUtils.getActualFile('testExisting_script', 'script', 'ssjs'))).to.equal( file(testUtils.getExpectedFile('9999999', 'script', 'get', 'ssjs')) ); + + expect( + file(testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'json')) + ).to.not.exist; + expect( + file(testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'ssjs')) + ).to.not.exist; + expect( + file(testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'html')) + ).to.not.exist; + assert.equal( testUtils.getAPIHistoryLength(), 3, @@ -88,14 +117,16 @@ describe('type: script', () => { // WHEN handler.setOptions({ like: { key: '%Existing_script' } }); await handler.retrieve('testInstance/testBU', ['script']); + // THEN assert.equal(process.exitCode, false, 'retrieve should not have thrown an error'); + // get results from cache const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, - 1, - 'one script in cache expected' + 2, + 'two scripts in cache expected' ); assert.deepEqual( await testUtils.getActualJson('testExisting_script', 'script'), @@ -105,6 +136,17 @@ describe('type: script', () => { expect(file(testUtils.getActualFile('testExisting_script', 'script', 'ssjs'))).to.equal( file(testUtils.getExpectedFile('9999999', 'script', 'get', 'ssjs')) ); + + expect( + file(testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'json')) + ).to.not.exist; + expect( + file(testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'ssjs')) + ).to.not.exist; + expect( + file(testUtils.getActualFile('testExisting_script_noScriptTag', 'script', 'html')) + ).to.not.exist; + assert.equal( testUtils.getAPIHistoryLength(), 3, @@ -118,12 +160,13 @@ describe('type: script', () => { await handler.retrieve('testInstance/testBU', ['script']); // THEN assert.equal(process.exitCode, false, 'retrieve should not have thrown an error'); + // get results from cache const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, - 1, - 'one script in cache expected' + 2, + 'two scripts in cache expected' ); expect(file(testUtils.getActualFile('testExisting_script', 'script', 'ssjs'))).to.not @@ -149,8 +192,8 @@ describe('type: script', () => { const result = cache.getCache(); assert.equal( result.script ? Object.keys(result.script).length : 0, - 2, - 'two scripts expected' + 3, + 'three scripts expected' ); // confirm created item assert.deepEqual( From 4e5b494406a306f5bb9e27e045d2f9047b91fd7f Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Thu, 13 Jul 2023 19:14:34 +0200 Subject: [PATCH 111/208] #38: tests, return keys of updated items --- docs/dist/documentation.md | 16 -- lib/index.js | 169 +++++++++++++----- .../patch-response.json | 85 +++++++++ .../9999999/query/patch_fixKeys-expected.json | 11 ++ .../9999999/query/patch_fixKeys-expected.sql | 6 + test/type.query.test.js | 39 +--- 6 files changed, 225 insertions(+), 101 deletions(-) create mode 100644 test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json create mode 100644 test/resources/9999999/query/patch_fixKeys-expected.json create mode 100644 test/resources/9999999/query/patch_fixKeys-expected.sql diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 968513df6..0d6f6df46 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -519,7 +519,6 @@ main class * [.execute(businessUnit, [selectedType], [keys])](#Mcdev.execute) ⇒ Promise.<boolean> * [.pause(businessUnit, [selectedType], [keys])](#Mcdev.pause) ⇒ Promise.<boolean> * [.fixKeys(businessUnit, type, [keys])](#Mcdev.fixKeys) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> - * [._fixKeysBU(cred, bu, type, [keyArr])](#Mcdev._fixKeysBU) ⇒ Promise.<boolean> @@ -814,21 +813,6 @@ Updates the key to match the name field | type | TYPE.SupportedMetadataTypes | limit execution to given metadata type | | [keys] | Array.<string> | customerkey of the metadata | - - -### Mcdev.\_fixKeysBU(cred, bu, type, [keyArr]) ⇒ Promise.<boolean> -helper for [fixKeys](#Mcdev.fixKeys) - -**Kind**: static method of [Mcdev](#Mcdev) -**Returns**: Promise.<boolean> - true if all successfully, false if not - -| Param | Type | Description | -| --- | --- | --- | -| cred | string | name of Credential | -| bu | string | name of BU | -| type | TYPE.SupportedMetadataTypes | limit execution to given metadata type | -| [keyArr] | Array.<string> | customerkey of the metadata | - ## Asset ⇐ [MetadataType](#MetadataType) diff --git a/lib/index.js b/lib/index.js index ff148613d..ee612612c 100644 --- a/lib/index.js +++ b/lib/index.js @@ -989,8 +989,6 @@ class Mcdev { Util.startLogger(); Util.logger.info('mcdev:: fixKeys'); const properties = await config.getProperties(); - let counter_credBu = 0; - let counter_failed = 0; if (!(await config.checkProperties(properties))) { // return null here to avoid seeing 2 error messages for the same issue return null; @@ -1004,51 +1002,36 @@ class Mcdev { return null; } let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; - // to allow all-BU via user selection we need to run this here already - if ( - properties.credentials && - (!properties.credentials[cred] || - (bu !== '*' && !properties.credentials[cred].businessUnits[bu])) - ) { - const buObject = await Cli.getCredentialObject( - properties, - cred === null ? null : cred + '/' + bu, - null, - true - ); - if (buObject === null) { - return; - } else { - cred = buObject.credential; - bu = buObject.businessUnit; - } - } + // if ( + // properties.credentials && + // (!properties.credentials[cred] || + // (bu !== '*' && !properties.credentials[cred].businessUnits[bu])) + // ) { + // const buObject = await Cli.getCredentialObject( + // properties, + // cred === null ? null : cred + '/' + bu, + // null, + // true + // ); + // if (buObject === null) { + // return; + // } else { + // cred = buObject.credential; + // bu = buObject.businessUnit; + // } + // } // update keys on a BU - if (await this._fixKeysBU(cred, bu, type, keys)) { - counter_credBu++; - } else { - counter_failed++; - } - Util.logger.info(`\n :: Done\n`); - if (counter_credBu !== 0) { - Util.logger.info(`\n :: Updated keys on ${counter_credBu} BUs\n`); - } - return counter_failed === 0 ? true : false; - } + // fixKeyResult[] + // if (fixKeyResult.push(await this._fixKeysBU(cred, bu, type, keys))) { + // counter_credBu++; + // } else { + // counter_failed++; + // } - /** - * helper for {@link Mcdev.fixKeys} - * - * @param {string} cred name of Credential - * @param {string} bu name of BU - * @param {TYPE.SupportedMetadataTypes} type limit execution to given metadata type - * @param {string[]} [keyArr] customerkey of the metadata - * @returns {Promise.} true if all successfully, false if not - */ - static async _fixKeysBU(cred, bu, type, keyArr) { - const properties = await config.getProperties(); let numItemsToUpdate; let deployed; + 0; + const buObject = await Cli.getCredentialObject( properties, cred === null ? null : cred + '/' + bu, @@ -1070,11 +1053,11 @@ class Mcdev { } Util.logger.info(`First retrieve ${type}`); const retriever = new Retriever(properties, buObject); - const retrieved = await retriever.retrieve([type], keyArr, null, false); + const retrieved = await retriever.retrieve([type], keys, null, false); const typeArr = Object.values(retrieved)[0]; // merge results if multiple keys were provided - if (keyArr?.length > 1) { + if (keys?.length > 1) { const base = typeArr[0]; for (let i = 1; i < typeArr.length; i++) { // merge all items into the first array @@ -1092,14 +1075,104 @@ class Mcdev { Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; properties.directories.deploy = properties.directories.retrieve; deployed = await Deployer._deployBU(cred, bu, properties, [type], keysForDeploy, true); - // TODO find types that are dependent on this type by iterating over THEIR dependencies - // await this.#retrieveBU(cred, bu, MetadataTypeDefinitions[type].dependencies); + const dependentTypes = await this.#getDependentMetadata(type); + await retriever.retrieve(dependentTypes, null, null, false); + Util.OPTIONS.changeKeyField = false; + await Deployer._deployBU(cred, bu, properties, dependentTypes, null, true); // TODO update other types that are dependent on this type. } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } - return numItemsToUpdate === Object.values(deployed).length ? true : false; + Util.logger.info(`\n :: Done\n`); + return Object.keys(Object.values(deployed)[0]); + } + + /** + * helper for {@link Mcdev.fixKeys} + * + * @param {string} cred name of Credential + * @param {string} bu name of BU + * @param {TYPE.SupportedMetadataTypes} type limit execution to given metadata type + * @param {string[]} [keyArr] customerkey of the metadata + * @returns {Array} fixedKeys of re-deployed items + */ + // static async _fixKeysBU(cred, bu, type, keyArr) { + // const properties = await config.getProperties(); + // let numItemsToUpdate; + // let deployed; + // const buObject = await Cli.getCredentialObject( + // properties, + // cred === null ? null : cred + '/' + bu, + // null, + // true + // ); + // if (buObject !== null) { + // cache.initCache(buObject); + // cred = buObject.credential; + // bu = buObject.businessUnit; + // } + // Util.logger.info(`\n :: Updating keys for ${type} on ${cred}/${bu}\n`); + // try { + // try { + // MetadataTypeInfo[type].client = auth.getSDK(buObject); + // } catch (ex) { + // Util.logger.error(ex.message); + // return; + // } + // Util.logger.info(`First retrieve ${type}`); + // const retriever = new Retriever(properties, buObject); + // const retrieved = await retriever.retrieve([type], keyArr, null, false); + + // const typeArr = Object.values(retrieved)[0]; + // // merge results if multiple keys were provided + // if (keyArr?.length > 1) { + // const base = typeArr[0]; + // for (let i = 1; i < typeArr.length; i++) { + // // merge all items into the first array + // Object.assign(base, typeArr[i]); + // } + // // kick out all but first entry + // typeArr.length = 1; + // } + // const keysForDeploy = MetadataTypeInfo[type].getKeysForFixing(typeArr[0], type); + // numItemsToUpdate = keysForDeploy.length; + // if (numItemsToUpdate < 1) { + // Util.logger.info(`No items to update. Exiting`); + // return true; + // } + // Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; + // properties.directories.deploy = properties.directories.retrieve; + // deployed = await Deployer._deployBU(cred, bu, properties, [type], keysForDeploy, true); + // // TODO find types that are dependent on this type by iterating over THEIR dependencies + // const dependentTypes = await this.#getDependentMetadata(type); + // await retriever.retrieve(dependentTypes, null, null, false); + // Util.OPTIONS.changeKeyField = false; + // await Deployer._deployBU(cred, bu, properties, dependentTypes, null, true); + // // TODO update other types that are dependent on this type. + // } catch (ex) { + // Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); + // } + // return Object.keys(Object.values(deployed)[0]); + // } + /** + *helper for {@link Mcdev._fixKeysBU}. Retrieve dependent metadata + * + * @private + * @param {string} cred name of Credential + * @param {string} bu name of BU + * @param {string} type type of the metadata passed as a parameter to fixKeys function + * @returns {Array} array of types that depend on the given type + */ + static async #getDependentMetadata(type) { + const dependencies = []; + Util.logger.info(`\n :: Retrieving dependent metadata \n`); + for (const dependentType of Object.keys(MetadataTypeDefinitions)) { + if (MetadataTypeDefinitions[dependentType].dependencies.includes(type)) { + dependencies.push(dependentType); + } + } + return dependencies; } } diff --git a/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json b/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json new file mode 100644 index 000000000..58ec6b51c --- /dev/null +++ b/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json @@ -0,0 +1,85 @@ +{ + "id": "08afb0e2-b00a-4c88-ad2e-pause", + "name": "testExisting_automation_pause", + "description": "bla bla", + "key": "testExisting_automation_pause", + "typeId": 1, + "type": "scheduled", + "statusId": 4, + "status": "Scheduled", + "categoryId": 290937, + "schedule": { + "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", + "typeId": 3, + "startDate": "2022-07-30T00:00:00", + "endDate": "2022-07-30T00:00:00", + "scheduledTime": "0001-01-01T07:00:00", + "rangeTypeId": 0, + "occurrences": 1, + "pattern": "01", + "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", + "timezoneName": "W. Europe Standard Time", + "scheduleStatus": "scheduled", + "timezoneId": 5 + }, + "steps": [ + { + "id": "13fda077-0e82-4936-b936-a36b0997fc44", + "name": "", + "step": 1, + "activities": [ + { + "id": "8081a992-a27d-4a43-984a-d60114ea1025", + "name": "testExisting_dataExtract", + "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", + "objectTypeId": 73, + "displayOrder": 1 + }, + { + "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", + "name": "testExisting_emailSend", + "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", + "objectTypeId": 42, + "displayOrder": 2 + }, + { + "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", + "name": "testExisting_fileTransfer", + "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", + "objectTypeId": 53, + "displayOrder": 3 + }, + { + "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", + "name": "testExisting_importFile", + "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", + "objectTypeId": 43, + "displayOrder": 4, + "targetDataExtensions": [ + { + "id": "21711373-72c1-ec11-b83b-48df37d1deb7", + "name": "testExisting_dataExtension", + "key": "testExisting_dataExtension", + "description": "bla bla", + "rowCount": 0 + } + ] + }, + { + "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", + "name": "testExisting_query_WRONG_NAME", + "activityObjectId": "549f0568-607c-4940-afef-437965094dat", + "objectTypeId": 300, + "displayOrder": 5 + }, + { + "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", + "name": "testExisting_script", + "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", + "objectTypeId": 423, + "displayOrder": 6 + } + ] + } + ] +} diff --git a/test/resources/9999999/query/patch_fixKeys-expected.json b/test/resources/9999999/query/patch_fixKeys-expected.json new file mode 100644 index 000000000..77a1e032e --- /dev/null +++ b/test/resources/9999999/query/patch_fixKeys-expected.json @@ -0,0 +1,11 @@ +{ + "name": "testExisting_query_fixedKeys", + "key": "testExisting_query_fixedKeys", + "description": "updated on deploy", + "targetKey": "testExisting_dataExtension", + "createdDate": "2022-04-26T15:21:16.453", + "modifiedDate": "2022-04-26T16:04:15.88", + "targetUpdateTypeName": "Overwrite", + "isFrozen": false, + "r__folder_Path": "Query" +} diff --git a/test/resources/9999999/query/patch_fixKeys-expected.sql b/test/resources/9999999/query/patch_fixKeys-expected.sql new file mode 100644 index 000000000..2a32f5fad --- /dev/null +++ b/test/resources/9999999/query/patch_fixKeys-expected.sql @@ -0,0 +1,6 @@ +SELECT + SubscriberKey AS testField +FROM + _Subscribers +WHERE + country IN ('test') diff --git a/test/type.query.test.js b/test/type.query.test.js index 29bf05dd2..6480d3b7a 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -252,16 +252,9 @@ describe('type: query', () => { 'testExisting_query_fixKeys', 'testExisting_query', ]); + assert.equal(resultFixKeys.length, 1, 'returned keys do not correspond to expected'); // THEN assert.equal(process.exitCode, false, 'fixKeys should not have thrown an error'); - assert.equal(resultFixKeys, true, 'fixKeys should not have thrown an error'); - // get results from cache - // const result = cache.getCache(); - // assert.equal( - // result.query ? Object.keys(result.query).length : 0, - // 4, - // 'four queries expected in cache' - // ); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKeys', 'query'), @@ -274,39 +267,11 @@ describe('type: query', () => { // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 14, + 47, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; }); - // it('Should change the key during update with --changeKeyValue'); - // it('Should deploy and execute with --execute', async () => { - // handler.setOptions({ execute: true }); - // // WHEN - // await handler.deploy('testInstance/testBU', ['query']); - // // THEN - // assert.equal( - // process.exitCode, - // false, - // 'deploy with --execute should not have thrown an error' - // ); - // // confirm updated item - // assert.deepEqual( - // await testUtils.getActualJson('testExisting_query', 'query'), - // await testUtils.getExpectedJson('9999999', 'query', 'patch'), - // 'returned metadata was not equal expected for insert query' - // ); - // expect(file(testUtils.getActualFile('testExisting_query', 'query', 'sql'))).to.equal( - // file(testUtils.getExpectedFile('9999999', 'query', 'patch', 'sql')) - // ); - // // check number of API calls - // assert.equal( - // testUtils.getAPIHistoryLength(), - // 12, - // 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' - // ); - // return; - // }); }); describe('Templating ================', () => { it('Should create a query template via retrieveAsTemplate and build it', async () => { From c1072104ce343f51f0ef9342ca123cbdc9577cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 14 Jul 2023 10:06:53 +0200 Subject: [PATCH 112/208] #1025: split of existing schedule automation logic to prep for new runOnce logic --- docs/dist/documentation.md | 15 +++++++++++ lib/cli.js | 11 ++++++-- lib/index.js | 3 ++- lib/metadataTypes/Automation.js | 20 ++++++++++++--- test/type.automation.test.js | 45 ++++++++++++++++++++++++++------- 5 files changed, 79 insertions(+), 15 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index c8cc127b9..76a05d13f 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -202,6 +202,9 @@ Provides default functionality that can be overwritten by child metadata type cl

helper for execute

Automation.(metadata)Promise.<object>
+

helper for execute

+
+
Automation.(metadata)Promise.<object>

helper for pause

Automation.(metadata)
@@ -8378,6 +8381,18 @@ helper for [execute](#Automation.execute) +## Automation.(metadata) ⇒ Promise.<object> +helper for [execute](#Automation.execute) + +**Kind**: global function +**Returns**: Promise.<object> - Returns the result of the API call + +| Param | Type | Description | +| --- | --- | --- | +| metadata | TYPE.AutomationItem | metadata json | + + + ## Automation.(metadata) ⇒ Promise.<object> helper for [pause](#Automation.pause) diff --git a/lib/cli.js b/lib/cli.js index 36476badb..1c8395c55 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -87,9 +87,10 @@ yargs 'optional for asset-message: runs refresh command for related triggeredSends after deploy', }) .option('execute', { - type: 'boolean', + type: 'string', group: 'Options for deploy:', - describe: 'optional for query: runs execute after deploy', + describe: + 'optional: executes item after deploy; for automations you can set it to --execute=schedule; alternatively it will run the automation once immediately', }); }, handler: (argv) => { @@ -430,6 +431,12 @@ yargs group: 'Options for execute:', describe: 'filter metadata components (can include % as wildcard or _ for a single character)', + }) + .option('schedule', { + type: 'boolean', + group: 'Options for execute:', + describe: + 'optionally start existing schedule instead of running item once immediately (only works for automations)', }); }, handler: (argv) => { diff --git a/lib/index.js b/lib/index.js index 4c836dafc..13b2325e4 100644 --- a/lib/index.js +++ b/lib/index.js @@ -54,13 +54,14 @@ class Mcdev { 'changeKeyField', 'changeKeyValue', 'commitHistory', + 'execute', 'filter', 'fromRetrieve', 'json', 'like', 'noLogFile', 'refresh', - 'execute', + 'schedule', 'skipInteraction', ]; for (const option of knownOptions) { diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index 1f6dd6d19..2d1522140 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -508,9 +508,23 @@ class Automation extends MetadataType { * @returns {Promise.} Returns the result of the API call */ static async #executeItem(metadataMap, key) { - this.#preDeploySchedule(metadataMap[key]); - metadataMap[key].status = 'Scheduled'; - return this.#scheduleAutomation(metadataMap, metadataMap, key); + if (Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule') { + this.#preDeploySchedule(metadataMap[key]); + metadataMap[key].status = 'Scheduled'; + return this.#scheduleAutomation(metadataMap, metadataMap, key); + } else { + return this.#runOnce(metadataMap[key]); + } + } + + /** + * helper for {@link Automation.execute} + * + * @param {TYPE.AutomationItem} metadata metadata json + * @returns {Promise.} Returns the result of the API call + */ + static async #runOnce(metadata) { + return metadata; } /** * a function to start query execution via API diff --git a/test/type.automation.test.js b/test/type.automation.test.js index 531b6b802..fa0526fd4 100644 --- a/test/type.automation.test.js +++ b/test/type.automation.test.js @@ -116,9 +116,9 @@ describe('type: automation', () => { ); return; }); - it('Should update & start an automation with --execute option', async () => { + it('Should update & schedule an automation with --execute option', async () => { // WHEN - handler.setOptions({ execute: true }); + handler.setOptions({ execute: 'schedule' }); const deployed = await handler.deploy( 'testInstance/testBU', ['automation'], @@ -178,6 +178,8 @@ describe('type: automation', () => { ); return; }); + it('Should update & runOnce an automation with --execute option'); + it('Should change the key during update via --changeKeyValue'); }); describe('Templating ================', () => { @@ -319,7 +321,8 @@ describe('type: automation', () => { }); }); describe('Execute ================', () => { - it('Should start an automation by key', async () => { + it('Should schedule an automation by key', async () => { + handler.setOptions({ schedule: true }); const execute = await handler.execute('testInstance/testBU', 'automation', [ 'testExisting_automation', ]); @@ -327,15 +330,15 @@ describe('type: automation', () => { assert.equal(execute, true, 'automation was supposed to be executed'); return; }); - it('Should start an automation selected via --like', async () => { - handler.setOptions({ like: { key: 'testExist%automation' } }); + it('Should schedule an automation selected via --like', async () => { + handler.setOptions({ like: { key: 'testExist%automation' }, schedule: true }); const execute = await handler.execute('testInstance/testBU', 'automation'); assert.equal(process.exitCode, false, 'execute should not have thrown an error'); assert.equal(execute, true, 'automation was supposed to be executed'); return; }); - it('Should not start executing an automation because key and --like was specified', async () => { - handler.setOptions({ like: { key: 'testExisting%' } }); + it('Should not schedule executing an automation because key and --like was specified', async () => { + handler.setOptions({ like: { key: 'testExisting%' }, schedule: true }); const execute = await handler.execute('testInstance/testBU', 'automation', [ 'testExisting_automation', ]); @@ -343,6 +346,30 @@ describe('type: automation', () => { assert.equal(execute, false, 'automation was not supposed to be executed'); return; }); + it('Should runOnce an automation by key', async () => { + // const execute = await handler.execute('testInstance/testBU', 'automation', [ + // 'testExisting_automation', + // ]); + // assert.equal(process.exitCode, false, 'execute should not have thrown an error'); + // assert.equal(execute, true, 'automation was supposed to be executed'); + // return; + }); + it('Should runOnce an automation selected via --like', async () => { + // handler.setOptions({ like: { key: 'testExist%automation' } }); + // const execute = await handler.execute('testInstance/testBU', 'automation'); + // assert.equal(process.exitCode, false, 'execute should not have thrown an error'); + // assert.equal(execute, true, 'automation was supposed to be executed'); + // return; + }); + it('Should not runOnce executing an automation because key and --like was specified', async () => { + // handler.setOptions({ like: { key: 'testExisting%' }}); + // const execute = await handler.execute('testInstance/testBU', 'automation', [ + // 'testExisting_automation', + // ]); + // assert.equal(process.exitCode, true, 'execute should not have thrown an error'); + // assert.equal(execute, false, 'automation was not supposed to be executed'); + // return; + }); }); describe('Pause ================', () => { it('Should pause a automation by key', async () => { @@ -360,12 +387,12 @@ describe('type: automation', () => { assert.equal(pause, true, 'automation was supposed to be paused'); return; }); - it('Should not pause executing a automation because key and --like was specified', async () => { + it('Should not pause automation because key and --like was specified', async () => { handler.setOptions({ like: { key: 'testExisting_a%n_pause' } }); const pause = await handler.pause('testInstance/testBU', 'automation', [ 'testExisting_automation_pause', ]); - assert.equal(process.exitCode, true, 'pause should not have thrown an error'); + assert.equal(process.exitCode, true, 'pause should have thrown an error'); assert.equal(pause, false, 'automation was not supposed to be paused'); return; }); From 1af95979d6b2e315f17ba1de10df34929373fe03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 14 Jul 2023 11:52:04 +0200 Subject: [PATCH 113/208] #1025: Add support to runOnce an automation via execute command --- docs/dist/documentation.md | 45 ++++++++- lib/metadataTypes/Automation.js | 38 +++++-- lib/metadataTypes/MetadataType.js | 59 ++++++++--- lib/util/util.js | 9 ++ test/resourceFactory.js | 10 ++ ...2-b00a-4c88-ad2e-1f7f8788c560-response.xml | 42 ++++++++ test/type.automation.test.js | 98 +++++++++++++++---- 7 files changed, 258 insertions(+), 43 deletions(-) create mode 100644 test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 76a05d13f..3eab79560 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -201,7 +201,7 @@ Provides default functionality that can be overwritten by child metadata type cl
Automation.(metadataMap, key)Promise.<object>

helper for execute

-
Automation.(metadata)Promise.<object>
+
Automation.(metadataEntry)Promise.<object>

helper for execute

Automation.(metadata)Promise.<object>
@@ -3314,6 +3314,7 @@ Provides default functionality that can be overwritten by child metadata type cl * [.retrieveSOAP(retrieveDir, [requestParams], [singleRetrieve], [additionalFields])](#MetadataType.retrieveSOAP) ⇒ Promise.<TYPE.MetadataTypeMapObj> * [.retrieveREST(retrieveDir, uri, [templateVariables], [singleRetrieve])](#MetadataType.retrieveREST) ⇒ Promise.<{metadata: (TYPE.MetadataTypeMap\|TYPE.MetadataTypeItem), type: string}> * [.executeREST(uri, key)](#MetadataType.executeREST) ⇒ Promise.<string> + * [.executeSOAP([metadataEntry])](#MetadataType.executeSOAP) ⇒ Promise.<object> * [.runDocumentOnRetrieve([singleRetrieve], metadataMap)](#MetadataType.runDocumentOnRetrieve) ⇒ Promise.<void> * [.parseResponseBody(body, [singleRetrieve])](#MetadataType.parseResponseBody) ⇒ TYPE.MetadataTypeMap * [.deleteFieldByDefinition(metadataEntry, fieldPath, definitionProperty, origin)](#MetadataType.deleteFieldByDefinition) ⇒ void @@ -3802,6 +3803,18 @@ Used to execute a query/automation etc. | uri | string | REST endpoint where the POST request should be sent | | key | string | item key | + + +### MetadataType.executeSOAP([metadataEntry]) ⇒ Promise.<object> +Used to execute a query/automation etc. + +**Kind**: static method of [MetadataType](#MetadataType) +**Returns**: Promise.<object> - api response + +| Param | Type | Description | +| --- | --- | --- | +| [metadataEntry] | TYPE.MetadataTypeItem | single metadata entry | + ### MetadataType.runDocumentOnRetrieve([singleRetrieve], metadataMap) ⇒ Promise.<void> @@ -5998,6 +6011,7 @@ CLI entry for SFMC DevTools * [.getSsjs(code)](#Util.getSsjs) ⇒ string * [.stringLike(testString, search)](#Util.stringLike) ⇒ boolean * [.fieldsLike(metadata, [filters])](#Util.fieldsLike) ⇒ boolean + * [.capitalizeFirstLetter(str)](#Util.capitalizeFirstLetter) ⇒ string @@ -6380,6 +6394,18 @@ returns true if no LIKE filter is defined or if all filters match | metadata | TYPE.MetadataTypeItem | a single metadata item | | [filters] | object | only used in recursive calls | + + +### Util.capitalizeFirstLetter(str) ⇒ string +helper used by SOAP methods to ensure the type always uses an upper-cased first letter + +**Kind**: static method of [Util](#Util) +**Returns**: string - str with first letter capitalized + +| Param | Type | +| --- | --- | +| str | string | + ## MetadataTypeDefinitions @@ -7916,6 +7942,7 @@ Util that contains logger and simple util methods * [.getSsjs(code)](#Util.getSsjs) ⇒ string * [.stringLike(testString, search)](#Util.stringLike) ⇒ boolean * [.fieldsLike(metadata, [filters])](#Util.fieldsLike) ⇒ boolean + * [.capitalizeFirstLetter(str)](#Util.capitalizeFirstLetter) ⇒ string @@ -8298,6 +8325,18 @@ returns true if no LIKE filter is defined or if all filters match | metadata | TYPE.MetadataTypeItem | a single metadata item | | [filters] | object | only used in recursive calls | + + +### Util.capitalizeFirstLetter(str) ⇒ string +helper used by SOAP methods to ensure the type always uses an upper-cased first letter + +**Kind**: static method of [Util](#Util) +**Returns**: string - str with first letter capitalized + +| Param | Type | +| --- | --- | +| str | string | + ## csvToArray(csv) ⇒ Array.<string> @@ -8381,7 +8420,7 @@ helper for [execute](#Automation.execute) -## Automation.(metadata) ⇒ Promise.<object> +## Automation.(metadataEntry) ⇒ Promise.<object> helper for [execute](#Automation.execute) **Kind**: global function @@ -8389,7 +8428,7 @@ helper for [execute](#Automation.execute) | Param | Type | Description | | --- | --- | --- | -| metadata | TYPE.AutomationItem | metadata json | +| metadataEntry | TYPE.AutomationItem | metadata object | diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index 2d1522140..21457870f 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -463,7 +463,8 @@ class Automation extends MetadataType { static async execute(keyArr) { const metadataMap = {}; for (const key of keyArr) { - if (key) { + if (Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule') { + // schedule const results = await this.retrieve(undefined, undefined, undefined, key); if (Object.keys(results.metadata).length) { for (const key of Object.keys(results.metadata)) { @@ -476,20 +477,37 @@ class Automation extends MetadataType { } } } + } else { + // runOnce + const objectId = await this.#getObjectIdForSingleRetrieve(key); + metadataMap[key] = {}; + metadataMap[key][this.definition.idField] = objectId; + metadataMap[key][this.definition.keyField] = key; } } - + if (!Object.keys(metadataMap).length) { + Util.logger.error(`No ${this.definition.type} to execute`); + return false; + } Util.logger.info( - `Starting automations according to schedule: ${Object.keys(metadataMap).length}` + `Starting automations ${ + Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule' + ? 'according to schedule' + : 'to run once (use --schedule or --execute=schedule to schedule instead)' + }: ${Object.keys(metadataMap).length}` ); const promiseResults = []; - for (const key of Object.keys(metadataMap)) { - if (metadataMap[key].status === 'Scheduled') { + if ( + (Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule') && + metadataMap[key].status === 'Scheduled' + ) { + // schedule Util.logger.info( ` - skipping ${this.definition.type} ${metadataMap[key].name}: already scheduled.` ); } else { + // schedule + runOnce promiseResults.push(this.#executeItem(metadataMap, key)); } } @@ -520,11 +538,11 @@ class Automation extends MetadataType { /** * helper for {@link Automation.execute} * - * @param {TYPE.AutomationItem} metadata metadata json + * @param {TYPE.AutomationItem} metadataEntry metadata object * @returns {Promise.} Returns the result of the API call */ - static async #runOnce(metadata) { - return metadata; + static async #runOnce(metadataEntry) { + return super.executeSOAP(metadataEntry); } /** * a function to start query execution via API @@ -1441,7 +1459,7 @@ class Automation extends MetadataType { * @param {string} key customer key * @returns {Promise.} objectId or enpty string */ - static async _getObjectIdForSingleRetrieve(key) { + static async #getObjectIdForSingleRetrieve(key) { const response = await this.client.soap.retrieve('Program', ['ObjectID'], { filter: { leftOperand: 'CustomerKey', @@ -1460,7 +1478,7 @@ class Automation extends MetadataType { */ static async deleteByKey(customerKey) { // the delete endpoint returns a general exception if the automation does not exist; handle it gracefully instead by adding a retrieve first - const objectId = customerKey ? await this._getObjectIdForSingleRetrieve(customerKey) : null; + const objectId = customerKey ? await this.#getObjectIdForSingleRetrieve(customerKey) : null; if (!objectId) { Util.logger.error(` - automation not found`); return false; diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index d18f75848..b2aa7d0e4 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -851,7 +851,7 @@ class MetadataType { this.removeNotCreateableFields(metadataEntry); try { const response = await this.client.soap.create( - soapType.charAt(0).toUpperCase() + soapType.slice(1), + Util.capitalizeFirstLetter(soapType), metadataEntry, null ); @@ -956,7 +956,7 @@ class MetadataType { this.removeNotUpdateableFields(metadataEntry); try { const response = await this.client.soap.update( - soapType.charAt(0).toUpperCase() + soapType.slice(1), + Util.capitalizeFirstLetter(soapType), metadataEntry, null ); @@ -997,9 +997,14 @@ class MetadataType { * @returns {string} error message */ static getSOAPErrorMsg(ex) { - return ex?.json?.Results?.length - ? `${ex.json.Results[0].StatusMessage} (Code ${ex.json.Results[0].ErrorCode})` - : ex.message; + if (ex?.json?.Results?.length) { + if (ex?.json?.Results[0].StatusMessage) { + return `${ex.json.Results[0].StatusMessage} (Code ${ex.json.Results[0].ErrorCode})`; + } else if (ex?.json?.Results[0].Result.StatusMessage) { + return `${ex.json.Results[0].Result.StatusMessage} (Code ${ex.json.Results[0].Result.ErrorCode})`; + } + } + return ex.message; } /** * Retrieves SOAP via generic fuel-soap wrapper based metadata of metadata type into local filesystem. executes callback with retrieved metadata @@ -1016,7 +1021,11 @@ class MetadataType { const soapType = this.definition.soapType || this.definition.type; let response; try { - response = await this.client.soap.retrieveBulk(soapType, fields, requestParams); + response = await this.client.soap.retrieveBulk( + Util.capitalizeFirstLetter(soapType), + fields, + requestParams + ); } catch (ex) { this._handleSOAPErrors(ex, 'retrieving'); return {}; @@ -1100,6 +1109,38 @@ class MetadataType { } } + /** + * Used to execute a query/automation etc. + * + * @param {TYPE.MetadataTypeItem} [metadataEntry] single metadata entry + * @returns {Promise.} api response + */ + static async executeSOAP(metadataEntry) { + const soapType = this.definition.soapType || this.definition.type; + try { + const response = await this.client.soap.perform( + Util.capitalizeFirstLetter(soapType), + 'start', + { + ObjectID: metadataEntry[this.definition.idField], + } + ); + if (response?.OverallStatus === 'OK') { + Util.logger.info( + ` - executed ${this.definition.type}: ${ + metadataEntry[this.definition.keyField] + }` + ); + } else { + throw new Error(response?.OverallStatus); + } + return response; + } catch (ex) { + this._handleSOAPErrors(ex, 'executing', metadataEntry); + return null; + } + } + /** * helper for {@link MetadataType.retrieveREST} and {@link MetadataType.retrieveSOAP} * @@ -1912,11 +1953,7 @@ class MetadataType { metadata[overrideKeyField || this.definition.keyField] = customerKey; const soapType = this.definition.soapType || this.definition.type; try { - await this.client.soap.delete( - soapType.charAt(0).toUpperCase() + soapType.slice(1), - metadata, - null - ); + await this.client.soap.delete(Util.capitalizeFirstLetter(soapType), metadata, null); if (!handleOutside) { Util.logger.info(` - deleted ${this.definition.type}: ${customerKey}`); } diff --git a/lib/util/util.js b/lib/util/util.js index e552fe382..6ed3ceda5 100644 --- a/lib/util/util.js +++ b/lib/util/util.js @@ -834,6 +834,15 @@ const Util = { return false; }); }, + /** + * helper used by SOAP methods to ensure the type always uses an upper-cased first letter + * + * @param {string} str + * @returns {string} str with first letter capitalized + */ + capitalizeFirstLetter(str) { + return str.charAt(0).toUpperCase() + str.slice(1); + }, }; Util.startLogger(false, true); diff --git a/test/resourceFactory.js b/test/resourceFactory.js index 766eced42..4893db342 100644 --- a/test/resourceFactory.js +++ b/test/resourceFactory.js @@ -149,6 +149,16 @@ exports.handleSOAPRequest = async (config) => { break; } + case 'Perform': { + responseXML = await this.loadSOAPRecords( + config.headers.SOAPAction.toLocaleLowerCase(), + fullObj.Envelope.Body.PerformRequestMsg.Definitions.Definition['@_xsi:type'], + jObj.Envelope.Header.fueloauth, + fullObj.Envelope.Body.PerformRequestMsg.Definitions.Definition.ObjectID + ); + + break; + } default: { throw new Error( `The SOAP Action ${config.headers.SOAPAction} is not supported by test handler` diff --git a/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml b/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml new file mode 100644 index 000000000..103df1e55 --- /dev/null +++ b/test/resources/9999999/automation/perform-08afb0e2-b00a-4c88-ad2e-1f7f8788c560-response.xml @@ -0,0 +1,42 @@ + + + + DeleteResponse + urn:uuid:cc45bb83-15a3-4a82-ba48-47ac4fb13000 + urn:uuid:29986848-a0c3-4f3b-bf5a-91151f784449 + http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous + + + 2023-06-02T13:41:30Z + 2023-06-02T13:46:30Z + + + + + + + + OK + Performed Activity + + + 08afb0e2-b00a-4c88-ad2e-1f7f8788c560 + testExisting_automation + false + + + true + + + + OK + + 898702fc-a432-4176-8130-5d6dd5ad9ca6 + + + \ No newline at end of file diff --git a/test/type.automation.test.js b/test/type.automation.test.js index fa0526fd4..581c232d3 100644 --- a/test/type.automation.test.js +++ b/test/type.automation.test.js @@ -178,8 +178,68 @@ describe('type: automation', () => { ); return; }); - it('Should update & runOnce an automation with --execute option'); + it('Should update & runOnce an automation with --execute option', async () => { + // WHEN + handler.setOptions({ execute: true }); + const deployed = await handler.deploy( + 'testInstance/testBU', + ['automation'], + ['testExisting_automation'] + ); + // THEN + assert.equal( + process.exitCode, + false, + 'deploy with --execute should not have thrown an error' + ); + + // get results from cache + const cached = cache.getCache(); + assert.equal( + cached.automation ? Object.keys(cached.automation).length : 0, + 2, + 'two cached automation expected' + ); + assert.equal( + deployed['testInstance/testBU'].automation + ? Object.keys(deployed['testInstance/testBU'].automation).length + : 0, + 1, + 'one deployed automation expected' + ); + assert.equal( + deployed['testInstance/testBU'].automation + ? Object.keys(deployed['testInstance/testBU'].automation)[0] + : null, + 'testExisting_automation', + 'expected specific automation to have been deployed' + ); + // update + assert.deepEqual( + await testUtils.getActualJson('testExisting_automation', 'automation'), + await testUtils.getExpectedJson('9999999', 'automation', 'update'), + 'returned metadata was not equal expected for update' + ); + // check if MD file was created and equals expectations + expect(file(testUtils.getActualDoc('testExisting_automation', 'automation'))).to.equal( + file( + testUtils.getExpectedFile( + '9999999', + 'automation', + 'update-testExisting_automation', + 'md' + ) + ) + ); + + assert.equal( + testUtils.getAPIHistoryLength(), + 16, + 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' + ); + return; + }); it('Should change the key during update via --changeKeyValue'); }); describe('Templating ================', () => { @@ -347,28 +407,28 @@ describe('type: automation', () => { return; }); it('Should runOnce an automation by key', async () => { - // const execute = await handler.execute('testInstance/testBU', 'automation', [ - // 'testExisting_automation', - // ]); - // assert.equal(process.exitCode, false, 'execute should not have thrown an error'); - // assert.equal(execute, true, 'automation was supposed to be executed'); - // return; + const execute = await handler.execute('testInstance/testBU', 'automation', [ + 'testExisting_automation', + ]); + assert.equal(process.exitCode, false, 'execute should not have thrown an error'); + assert.equal(execute, true, 'automation was supposed to be executed'); + return; }); it('Should runOnce an automation selected via --like', async () => { - // handler.setOptions({ like: { key: 'testExist%automation' } }); - // const execute = await handler.execute('testInstance/testBU', 'automation'); - // assert.equal(process.exitCode, false, 'execute should not have thrown an error'); - // assert.equal(execute, true, 'automation was supposed to be executed'); - // return; + handler.setOptions({ like: { key: 'testExist%automation' } }); + const execute = await handler.execute('testInstance/testBU', 'automation'); + assert.equal(process.exitCode, false, 'execute should not have thrown an error'); + assert.equal(execute, true, 'automation was supposed to be executed'); + return; }); it('Should not runOnce executing an automation because key and --like was specified', async () => { - // handler.setOptions({ like: { key: 'testExisting%' }}); - // const execute = await handler.execute('testInstance/testBU', 'automation', [ - // 'testExisting_automation', - // ]); - // assert.equal(process.exitCode, true, 'execute should not have thrown an error'); - // assert.equal(execute, false, 'automation was not supposed to be executed'); - // return; + handler.setOptions({ like: { key: 'testExisting%' } }); + const execute = await handler.execute('testInstance/testBU', 'automation', [ + 'testExisting_automation', + ]); + assert.equal(process.exitCode, true, 'execute should not have thrown an error'); + assert.equal(execute, false, 'automation was not supposed to be executed'); + return; }); }); describe('Pause ================', () => { From 586421153868aa32bd40818688a0ce665e37a895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 14 Jul 2023 14:43:32 +0200 Subject: [PATCH 114/208] #1025: improve error handling around deploying running automations --- docs/dist/documentation.md | 37 +++++++++++++++++++++---------- lib/metadataTypes/Automation.js | 31 +++++++++++++++++++++++++- lib/metadataTypes/MetadataType.js | 14 +++++++----- lib/metadataTypes/Query.js | 5 +++-- lib/util/util.js | 2 +- 5 files changed, 67 insertions(+), 22 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 3eab79560..99ba66f0f 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -1342,6 +1342,7 @@ Automation MetadataType * [.retrieveAsTemplate(templateDir, name, templateVariables)](#Automation.retrieveAsTemplate) ⇒ Promise.<TYPE.AutomationItemObj> * [.postRetrieveTasks(metadata)](#Automation.postRetrieveTasks) ⇒ TYPE.AutomationItem \| void * [.execute(keyArr)](#Automation.execute) ⇒ Promise.<boolean> + * [.getErrorsREST(ex)](#Automation.getErrorsREST) ⇒ Array.<string> \| void * [.pause(keyArr)](#Automation.pause) ⇒ Promise.<boolean> * [.deploy(metadata, targetBU, retrieveDir)](#Automation.deploy) ⇒ Promise.<TYPE.AutomationMap> * [.create(metadata)](#Automation.create) ⇒ Promise @@ -1425,6 +1426,18 @@ a function to start query execution via API | --- | --- | --- | | keyArr | Array.<string> | customerkey of the metadata | + + +### Automation.getErrorsREST(ex) ⇒ Array.<string> \| void +Standardizes a check for multiple messages but adds query specific filters to error texts + +**Kind**: static method of [Automation](#Automation) +**Returns**: Array.<string> \| void - formatted Error Message + +| Param | Type | Description | +| --- | --- | --- | +| ex | object | response payload from REST API | + ### Automation.pause(keyArr) ⇒ Promise.<boolean> @@ -3332,7 +3345,7 @@ Provides default functionality that can be overwritten by child metadata type cl * [.findSubType(templateDir, templateName)](#MetadataType.findSubType) ⇒ Promise.<string> * [.readSecondaryFolder(templateDir, typeDirArr, templateName, fileName, ex)](#MetadataType.readSecondaryFolder) ⇒ object * [.buildDefinition(templateDir, targetDir, templateName, variables)](#MetadataType.buildDefinition) ⇒ Promise.<TYPE.MetadataTypeMapObj> - * [.checkForErrors(ex)](#MetadataType.checkForErrors) ⇒ Array.<string> \| void + * [.getErrorsREST(ex)](#MetadataType.getErrorsREST) ⇒ Array.<string> \| void * [.document([metadata], [isDeploy])](#MetadataType.document) ⇒ void * [.deleteByKey(customerKey)](#MetadataType.deleteByKey) ⇒ boolean * [.postDeleteTasks(customerKey, [additionalExtensions])](#MetadataType.postDeleteTasks) ⇒ Promise.<void> @@ -4053,9 +4066,9 @@ parsing is required (for example scripts & queries) | templateName | string | name of the metadata file | | variables | TYPE.TemplateMap | variables to be replaced in the metadata | - + -### MetadataType.checkForErrors(ex) ⇒ Array.<string> \| void +### MetadataType.getErrorsREST(ex) ⇒ Array.<string> \| void Standardizes a check for multiple messages **Kind**: static method of [MetadataType](#MetadataType) @@ -4741,7 +4754,7 @@ Query MetadataType * [.buildDefinitionForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#Query.buildDefinitionForNested) ⇒ Promise.<Array.<Array.<string>>> * [.buildTemplateForNested(templateDir, targetDir, metadata, templateVariables, templateName)](#Query.buildTemplateForNested) ⇒ Promise.<Array.<Array.<string>>> * [.getFilesToCommit(keyArr)](#Query.getFilesToCommit) ⇒ Array.<string> - * [.checkForErrors(ex)](#Query.checkForErrors) ⇒ Array.<string> \| void + * [.getErrorsREST(ex)](#Query.getErrorsREST) ⇒ Array.<string> \| void * [.deleteByKey(customerKey)](#Query.deleteByKey) ⇒ boolean * [.postDeleteTasks(customerKey)](#Query.postDeleteTasks) ⇒ void * [.postDeployTasks(upsertResults)](#Query.postDeployTasks) @@ -4908,9 +4921,9 @@ additionally, the documentation for dataExtension and automation should be retur | --- | --- | --- | | keyArr | Array.<string> | customerkey of the metadata | - + -### Query.checkForErrors(ex) ⇒ Array.<string> \| void +### Query.getErrorsREST(ex) ⇒ Array.<string> \| void Standardizes a check for multiple messages but adds query specific filters to error texts **Kind**: static method of [Query](#Query) @@ -6402,9 +6415,9 @@ helper used by SOAP methods to ensure the type always uses an upper-cased first **Kind**: static method of [Util](#Util) **Returns**: string - str with first letter capitalized -| Param | Type | -| --- | --- | -| str | string | +| Param | Type | Description | +| --- | --- | --- | +| str | string | string to capitalize | @@ -8333,9 +8346,9 @@ helper used by SOAP methods to ensure the type always uses an upper-cased first **Kind**: static method of [Util](#Util) **Returns**: string - str with first letter capitalized -| Param | Type | -| --- | --- | -| str | string | +| Param | Type | Description | +| --- | --- | --- | +| str | string | string to capitalize | diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index 21457870f..714ff3f8b 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -242,6 +242,7 @@ class Automation extends MetadataType { key: m.CustomerKey, name: m.Name, programId: automationsLegacy.metadata[m.CustomerKey]?.id, + status: automationsLegacy.metadata[m.CustomerKey]?.status, }; } } @@ -544,6 +545,25 @@ class Automation extends MetadataType { static async #runOnce(metadataEntry) { return super.executeSOAP(metadataEntry); } + + /** + * Standardizes a check for multiple messages but adds query specific filters to error texts + * + * @param {object} ex response payload from REST API + * @returns {string[] | void} formatted Error Message + */ + static getErrorsREST(ex) { + const errors = super.getErrorsREST(ex); + if (errors?.length > 0) { + return errors.map((msg) => + msg + .split('403 Forbidden') + .join('403 Forbidden: Please check if the automation is currently running.') + ); + } + return errors; + } + /** * a function to start query execution via API * @@ -669,7 +689,16 @@ class Automation extends MetadataType { * @returns {Promise} Promise */ static update(metadata, metadataBefore) { - metadata.id = metadataBefore.id; + if (metadataBefore.status === 'Running') { + Util.logger.error( + ` ☇ error updating ${this.definition.type} ${ + metadata[this.definition.keyField] || metadata[this.definition.nameField] + } / ${ + metadata[this.definition.nameField] + }: You cannot update an automation that's currently running. Please wait a bit and retry.` + ); + return null; + } const uri = '/automation/v1/automations/' + metadata.id; return super.updateREST(metadata, uri); } diff --git a/lib/metadataTypes/MetadataType.js b/lib/metadataTypes/MetadataType.js index b2aa7d0e4..9de1a3863 100644 --- a/lib/metadataTypes/MetadataType.js +++ b/lib/metadataTypes/MetadataType.js @@ -821,7 +821,7 @@ class MetadataType { ); return response; } catch (ex) { - const parsedErrors = this.checkForErrors(ex); + const parsedErrors = this.getErrorsREST(ex); Util.logger.error( ` ☇ error creating ${this.definition.type} ${ metadataEntry[this.definition.keyField] || @@ -884,7 +884,7 @@ class MetadataType { // set to empty object in case API returned nothing to be able to update it in helper classes const response = (await this.client.rest[httpMethod](uri, metadataEntry)) || {}; await this._postChangeKeyTasks(metadataEntry); - this.checkForErrors(response); + this.getErrorsREST(response); await this.postUpdateTasks(metadataEntry, response); // some times, e.g. automation dont return a key in their update response and hence we need to fall back to name Util.logger.info( @@ -895,7 +895,7 @@ class MetadataType { ); return response; } catch (ex) { - const parsedErrors = this.checkForErrors(ex); + const parsedErrors = this.getErrorsREST(ex); Util.logger.error( ` ☇ error updating ${this.definition.type} ${ metadataEntry[this.definition.keyField] || @@ -1863,7 +1863,7 @@ class MetadataType { * @param {object} ex response payload from REST API * @returns {string[] | void} formatted Error Message */ - static checkForErrors(ex) { + static getErrorsREST(ex) { const errors = []; if (ex?.response?.status >= 400 && ex?.response?.status < 600) { if (ex.response.data.errors) { @@ -1886,11 +1886,13 @@ class MetadataType { } } else if (ex.response.data.message) { errors.push(ex.response.data.message); - } else { + } else if (ex.response.data) { errors.push(`Undefined Errors: ${JSON.stringify(ex.response.data)}`); + Util.logger.debug(JSON.stringify(ex.response.data)); + } else { + errors.push(`${ex.response.status} ${ex.response.statusText}`); } Util.logger.debug(JSON.stringify(ex.config)); - Util.logger.debug(JSON.stringify(ex.response.data)); } return errors; } diff --git a/lib/metadataTypes/Query.js b/lib/metadataTypes/Query.js index 4fe76d256..63f0e273b 100644 --- a/lib/metadataTypes/Query.js +++ b/lib/metadataTypes/Query.js @@ -420,11 +420,12 @@ class Query extends MetadataType { * @param {object} ex response payload from REST API * @returns {string[] | void} formatted Error Message */ - static checkForErrors(ex) { - const errors = super.checkForErrors(ex); + static getErrorsREST(ex) { + const errors = super.getErrorsREST(ex); if (errors?.length > 0) { return errors.map((msg) => msg.split('Error saving the Query field.').join('')); } + return errors; } /** * Delete a metadata item from the specified business unit diff --git a/lib/util/util.js b/lib/util/util.js index 6ed3ceda5..57df86fc9 100644 --- a/lib/util/util.js +++ b/lib/util/util.js @@ -837,7 +837,7 @@ const Util = { /** * helper used by SOAP methods to ensure the type always uses an upper-cased first letter * - * @param {string} str + * @param {string} str string to capitalize * @returns {string} str with first letter capitalized */ capitalizeFirstLetter(str) { From 9ad3e1b1d40b0f7f7f22f563b7ed0717819e416c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Fri, 14 Jul 2023 14:59:13 +0200 Subject: [PATCH 115/208] #1025: add new command schedule and deploy option --schedule --- docs/dist/documentation.md | 15 ++++++++++++ lib/cli.js | 41 +++++++++++++++++++++++++++++++-- lib/index.js | 12 ++++++++++ lib/metadataTypes/Automation.js | 13 ++++------- test/type.automation.test.js | 30 +++++++++++++++++++++--- 5 files changed, 98 insertions(+), 13 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 99ba66f0f..57e14a1e0 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -519,6 +519,7 @@ main class * [.buildDefinition(businessUnit, selectedType, name, market)](#Mcdev.buildDefinition) ⇒ Promise.<void> * [.buildDefinitionBulk(listName, type, name)](#Mcdev.buildDefinitionBulk) ⇒ Promise.<void> * [.getFilesToCommit(businessUnit, selectedType, keyArr)](#Mcdev.getFilesToCommit) ⇒ Promise.<Array.<string>> + * [.schedule(businessUnit, [selectedType], [keys])](#Mcdev.schedule) ⇒ Promise.<boolean> * [.execute(businessUnit, [selectedType], [keys])](#Mcdev.execute) ⇒ Promise.<boolean> * [.pause(businessUnit, [selectedType], [keys])](#Mcdev.pause) ⇒ Promise.<boolean> @@ -773,6 +774,20 @@ Build a specific metadata file based on a template using a list of bu-market com | selectedType | string | supported metadata type | | keyArr | Array.<string> | customerkey of the metadata | + + +### Mcdev.schedule(businessUnit, [selectedType], [keys]) ⇒ Promise.<boolean> +Schedule an item (shortcut for execute --schedule) + +**Kind**: static method of [Mcdev](#Mcdev) +**Returns**: Promise.<boolean> - true if all started successfully, false if not + +| Param | Type | Description | +| --- | --- | --- | +| businessUnit | string | name of BU | +| [selectedType] | TYPE.SupportedMetadataTypes | limit to given metadata types | +| [keys] | Array.<string> | customerkey of the metadata | + ### Mcdev.execute(businessUnit, [selectedType], [keys]) ⇒ Promise.<boolean> diff --git a/lib/cli.js b/lib/cli.js index 1c8395c55..99d83894e 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -87,10 +87,16 @@ yargs 'optional for asset-message: runs refresh command for related triggeredSends after deploy', }) .option('execute', { - type: 'string', + type: 'boolean', group: 'Options for deploy:', describe: - 'optional: executes item after deploy; for automations you can set it to --execute=schedule; alternatively it will run the automation once immediately', + 'optional: executes item after deploy; this will run the item once immediately', + }) + .option('schedule', { + type: 'boolean', + group: 'Options for deploy:', + describe: + 'optionally start existing schedule instead of running item once immediately (only works for automations)', }); }, handler: (argv) => { @@ -445,6 +451,37 @@ yargs Mcdev.execute(argv.BU, argv.TYPE, csvToArray(argv.KEY)); }, }) + .command({ + command: 'schedule [KEY]', + aliases: ['sched'], + desc: 'starts the predefined schedule of the item (shortcut for running execute --schedule)', + builder: (yargs) => { + yargs + .positional('BU', { + type: 'string', + describe: 'the business unit where to start an item', + }) + .positional('TYPE', { + type: 'string', + describe: 'metadata type', + }) + .positional('KEY', { + type: 'string', + describe: 'key(s) of the metadata component(s)', + }) + .option('like', { + type: 'string', + group: 'Options for execute:', + describe: + 'filter metadata components (can include % as wildcard or _ for a single character)', + }); + }, + handler: (argv) => { + Mcdev.setOptions(argv); + // ! do not allow multiple types to be passed in here via csvToArray + Mcdev.schedule(argv.BU, argv.TYPE, csvToArray(argv.KEY)); + }, + }) .command({ command: 'pause [KEY]', aliases: ['p', 'stop'], diff --git a/lib/index.js b/lib/index.js index 13b2325e4..19b625ec7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -729,6 +729,18 @@ class Mcdev { return DevOps.getFilesToCommit(properties, buObject, selectedType, keyArr); } } + /** + * Schedule an item (shortcut for execute --schedule) + * + * @param {string} businessUnit name of BU + * @param {TYPE.SupportedMetadataTypes} [selectedType] limit to given metadata types + * @param {string[]} [keys] customerkey of the metadata + * @returns {Promise.} true if all started successfully, false if not + */ + static async schedule(businessUnit, selectedType, keys) { + this.setOptions({ schedule: true }); + return this.#runMethod('execute', businessUnit, selectedType, keys); + } /** * Start/execute an item * diff --git a/lib/metadataTypes/Automation.js b/lib/metadataTypes/Automation.js index 714ff3f8b..f48554790 100644 --- a/lib/metadataTypes/Automation.js +++ b/lib/metadataTypes/Automation.js @@ -464,7 +464,7 @@ class Automation extends MetadataType { static async execute(keyArr) { const metadataMap = {}; for (const key of keyArr) { - if (Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule') { + if (Util.OPTIONS.schedule) { // schedule const results = await this.retrieve(undefined, undefined, undefined, key); if (Object.keys(results.metadata).length) { @@ -492,17 +492,14 @@ class Automation extends MetadataType { } Util.logger.info( `Starting automations ${ - Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule' + Util.OPTIONS.schedule ? 'according to schedule' : 'to run once (use --schedule or --execute=schedule to schedule instead)' }: ${Object.keys(metadataMap).length}` ); const promiseResults = []; for (const key of Object.keys(metadataMap)) { - if ( - (Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule') && - metadataMap[key].status === 'Scheduled' - ) { + if (Util.OPTIONS.schedule && metadataMap[key].status === 'Scheduled') { // schedule Util.logger.info( ` - skipping ${this.definition.type} ${metadataMap[key].name}: already scheduled.` @@ -527,7 +524,7 @@ class Automation extends MetadataType { * @returns {Promise.} Returns the result of the API call */ static async #executeItem(metadataMap, key) { - if (Util.OPTIONS.schedule || Util.OPTIONS.execute === 'schedule') { + if (Util.OPTIONS.schedule) { this.#preDeploySchedule(metadataMap[key]); metadataMap[key].status = 'Scheduled'; return this.#scheduleAutomation(metadataMap, metadataMap, key); @@ -905,7 +902,7 @@ class Automation extends MetadataType { } } } - if (Util.OPTIONS.execute) { + if (Util.OPTIONS.execute || Util.OPTIONS.schedule) { Util.logger.info(`Executing: ${this.definition.type}`); await this.execute(Object.keys(metadataMap)); } diff --git a/test/type.automation.test.js b/test/type.automation.test.js index 581c232d3..de2a5c204 100644 --- a/test/type.automation.test.js +++ b/test/type.automation.test.js @@ -118,7 +118,7 @@ describe('type: automation', () => { }); it('Should update & schedule an automation with --execute option', async () => { // WHEN - handler.setOptions({ execute: 'schedule' }); + handler.setOptions({ schedule: true }); const deployed = await handler.deploy( 'testInstance/testBU', ['automation'], @@ -382,6 +382,30 @@ describe('type: automation', () => { }); describe('Execute ================', () => { it('Should schedule an automation by key', async () => { + const execute = await handler.schedule('testInstance/testBU', 'automation', [ + 'testExisting_automation', + ]); + assert.equal(process.exitCode, false, 'execute should not have thrown an error'); + assert.equal(execute, true, 'automation was supposed to be executed'); + return; + }); + it('Should schedule an automation selected via --like', async () => { + handler.setOptions({ like: { key: 'testExist%automation' } }); + const execute = await handler.schedule('testInstance/testBU', 'automation'); + assert.equal(process.exitCode, false, 'execute should not have thrown an error'); + assert.equal(execute, true, 'automation was supposed to be executed'); + return; + }); + it('Should not schedule executing an automation because key and --like was specified', async () => { + handler.setOptions({ like: { key: 'testExisting%' } }); + const execute = await handler.schedule('testInstance/testBU', 'automation', [ + 'testExisting_automation', + ]); + assert.equal(process.exitCode, true, 'execute should not have thrown an error'); + assert.equal(execute, false, 'automation was not supposed to be executed'); + return; + }); + it('Should execute --schedule an automation by key', async () => { handler.setOptions({ schedule: true }); const execute = await handler.execute('testInstance/testBU', 'automation', [ 'testExisting_automation', @@ -390,14 +414,14 @@ describe('type: automation', () => { assert.equal(execute, true, 'automation was supposed to be executed'); return; }); - it('Should schedule an automation selected via --like', async () => { + it('Should execute --schedule an automation selected via --like', async () => { handler.setOptions({ like: { key: 'testExist%automation' }, schedule: true }); const execute = await handler.execute('testInstance/testBU', 'automation'); assert.equal(process.exitCode, false, 'execute should not have thrown an error'); assert.equal(execute, true, 'automation was supposed to be executed'); return; }); - it('Should not schedule executing an automation because key and --like was specified', async () => { + it('Should not execute --schedule executing an automation because key and --like was specified', async () => { handler.setOptions({ like: { key: 'testExisting%' }, schedule: true }); const execute = await handler.execute('testInstance/testBU', 'automation', [ 'testExisting_automation', From 8d4783d0733d4cd734c360c3e4a0be603559ed12 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Fri, 14 Jul 2023 15:29:51 +0200 Subject: [PATCH 116/208] #38: function to get dependent, test method --- docs/dist/documentation.md | 6 +-- lib/index.js | 106 ++----------------------------------- test/type.query.test.js | 15 ++++-- 3 files changed, 18 insertions(+), 109 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 0d6f6df46..c5fc3be13 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -518,7 +518,7 @@ main class * [.getFilesToCommit(businessUnit, selectedType, keyArr)](#Mcdev.getFilesToCommit) ⇒ Promise.<Array.<string>> * [.execute(businessUnit, [selectedType], [keys])](#Mcdev.execute) ⇒ Promise.<boolean> * [.pause(businessUnit, [selectedType], [keys])](#Mcdev.pause) ⇒ Promise.<boolean> - * [.fixKeys(businessUnit, type, [keys])](#Mcdev.fixKeys) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> + * [.fixKeys(businessUnit, type, [keys])](#Mcdev.fixKeys) ⇒ Array @@ -801,11 +801,11 @@ pause an item -### Mcdev.fixKeys(businessUnit, type, [keys]) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> +### Mcdev.fixKeys(businessUnit, type, [keys]) ⇒ Array Updates the key to match the name field **Kind**: static method of [Mcdev](#Mcdev) -**Returns**: Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> - deployed metadata per BU (first key: bu name, second key: metadata type) +**Returns**: Array - array of fixedKeys | Param | Type | Description | | --- | --- | --- | diff --git a/lib/index.js b/lib/index.js index ee612612c..453e9bd16 100644 --- a/lib/index.js +++ b/lib/index.js @@ -983,7 +983,7 @@ class Mcdev { * @param {string} businessUnit name of BU * @param {TYPE.SupportedMetadataTypes} type limit execution to given metadata type * @param {string[]} [keys] customerkey of the metadata - * @returns {Promise.>} deployed metadata per BU (first key: bu name, second key: metadata type) + * @returns {Array} array of fixedKeys */ static async fixKeys(businessUnit, type, keys) { Util.startLogger(); @@ -1002,35 +1002,8 @@ class Mcdev { return null; } let [cred, bu] = businessUnit ? businessUnit.split('/') : [null, null]; - // if ( - // properties.credentials && - // (!properties.credentials[cred] || - // (bu !== '*' && !properties.credentials[cred].businessUnits[bu])) - // ) { - // const buObject = await Cli.getCredentialObject( - // properties, - // cred === null ? null : cred + '/' + bu, - // null, - // true - // ); - // if (buObject === null) { - // return; - // } else { - // cred = buObject.credential; - // bu = buObject.businessUnit; - // } - // } - // update keys on a BU - // fixKeyResult[] - // if (fixKeyResult.push(await this._fixKeysBU(cred, bu, type, keys))) { - // counter_credBu++; - // } else { - // counter_failed++; - // } - let numItemsToUpdate; let deployed; - 0; const buObject = await Cli.getCredentialObject( properties, @@ -1075,92 +1048,19 @@ class Mcdev { Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; properties.directories.deploy = properties.directories.retrieve; deployed = await Deployer._deployBU(cred, bu, properties, [type], keysForDeploy, true); - // TODO find types that are dependent on this type by iterating over THEIR dependencies const dependentTypes = await this.#getDependentMetadata(type); await retriever.retrieve(dependentTypes, null, null, false); - Util.OPTIONS.changeKeyField = false; - await Deployer._deployBU(cred, bu, properties, dependentTypes, null, true); - // TODO update other types that are dependent on this type. } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } Util.logger.info(`\n :: Done\n`); return Object.keys(Object.values(deployed)[0]); } - /** - * helper for {@link Mcdev.fixKeys} - * - * @param {string} cred name of Credential - * @param {string} bu name of BU - * @param {TYPE.SupportedMetadataTypes} type limit execution to given metadata type - * @param {string[]} [keyArr] customerkey of the metadata - * @returns {Array} fixedKeys of re-deployed items - */ - // static async _fixKeysBU(cred, bu, type, keyArr) { - // const properties = await config.getProperties(); - // let numItemsToUpdate; - // let deployed; - // const buObject = await Cli.getCredentialObject( - // properties, - // cred === null ? null : cred + '/' + bu, - // null, - // true - // ); - // if (buObject !== null) { - // cache.initCache(buObject); - // cred = buObject.credential; - // bu = buObject.businessUnit; - // } - // Util.logger.info(`\n :: Updating keys for ${type} on ${cred}/${bu}\n`); - // try { - // try { - // MetadataTypeInfo[type].client = auth.getSDK(buObject); - // } catch (ex) { - // Util.logger.error(ex.message); - // return; - // } - // Util.logger.info(`First retrieve ${type}`); - // const retriever = new Retriever(properties, buObject); - // const retrieved = await retriever.retrieve([type], keyArr, null, false); - - // const typeArr = Object.values(retrieved)[0]; - // // merge results if multiple keys were provided - // if (keyArr?.length > 1) { - // const base = typeArr[0]; - // for (let i = 1; i < typeArr.length; i++) { - // // merge all items into the first array - // Object.assign(base, typeArr[i]); - // } - // // kick out all but first entry - // typeArr.length = 1; - // } - // const keysForDeploy = MetadataTypeInfo[type].getKeysForFixing(typeArr[0], type); - // numItemsToUpdate = keysForDeploy.length; - // if (numItemsToUpdate < 1) { - // Util.logger.info(`No items to update. Exiting`); - // return true; - // } - // Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; - // properties.directories.deploy = properties.directories.retrieve; - // deployed = await Deployer._deployBU(cred, bu, properties, [type], keysForDeploy, true); - // // TODO find types that are dependent on this type by iterating over THEIR dependencies - // const dependentTypes = await this.#getDependentMetadata(type); - // await retriever.retrieve(dependentTypes, null, null, false); - // Util.OPTIONS.changeKeyField = false; - // await Deployer._deployBU(cred, bu, properties, dependentTypes, null, true); - // // TODO update other types that are dependent on this type. - // } catch (ex) { - // Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); - // } - // return Object.keys(Object.values(deployed)[0]); - // } - /** - *helper for {@link Mcdev._fixKeysBU}. Retrieve dependent metadata + *helper for {@link Mcdev.fixKeys}. Retrieve dependent metadata * * @private - * @param {string} cred name of Credential - * @param {string} bu name of BU + * * @param {string} type type of the metadata passed as a parameter to fixKeys function * @returns {Array} array of types that depend on the given type */ diff --git a/test/type.query.test.js b/test/type.query.test.js index 6480d3b7a..68986c7d2 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -252,14 +252,23 @@ describe('type: query', () => { 'testExisting_query_fixKeys', 'testExisting_query', ]); - assert.equal(resultFixKeys.length, 1, 'returned keys do not correspond to expected'); + assert.equal( + resultFixKeys.length, + 1, + 'returned number of keys does not correspond to number of expected fixed keys' + ); + assert.equal( + resultFixKeys[0], + 'testExisting_query_fixedKeys', + 'returned keys do not correspond to expected fixed keys' + ); // THEN assert.equal(process.exitCode, false, 'fixKeys should not have thrown an error'); // confirm updated item assert.deepEqual( await testUtils.getActualJson('testExisting_query_fixedKeys', 'query'), await testUtils.getExpectedJson('9999999', 'query', 'patch_fixKeys'), - 'returned metadata was not equal expected for insert query' + 'returned metadata was not equal expected for update query' ); expect( file(testUtils.getActualFile('testExisting_query_fixedKeys', 'query', 'sql')) @@ -267,7 +276,7 @@ describe('type: query', () => { // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 47, + 33, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; From 06b7397e15664f5101b3875a5369786a63159fb4 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Fri, 14 Jul 2023 15:43:41 +0200 Subject: [PATCH 117/208] #38: expected number of calls --- test/type.query.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/type.query.test.js b/test/type.query.test.js index 68986c7d2..fcc7debd1 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -276,7 +276,7 @@ describe('type: query', () => { // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 33, + 31, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; From b0db4b076de20638a4a919342d45eedf345f4d10 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Fri, 14 Jul 2023 16:13:52 +0200 Subject: [PATCH 118/208] #38: warn users about outdated files --- lib/index.js | 6 +++++- test/type.query.test.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/index.js b/lib/index.js index 13a2fa5d3..12bd90f8d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1088,7 +1088,11 @@ class Mcdev { properties.directories.deploy = properties.directories.retrieve; deployed = await Deployer._deployBU(cred, bu, properties, [type], keysForDeploy, true); const dependentTypes = await this.#getDependentMetadata(type); - await retriever.retrieve(dependentTypes, null, null, false); + Util.logger.warn( + `Keys for type '${type}' were updated. Retrieve '${dependentTypes.join( + ',' + )}' again to have up-to-date data in your retrieve folder` + ); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } diff --git a/test/type.query.test.js b/test/type.query.test.js index fcc7debd1..b49bc9746 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -276,7 +276,7 @@ describe('type: query', () => { // check number of API calls assert.equal( testUtils.getAPIHistoryLength(), - 31, + 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); return; From 969dbda2ce1d2a00a8f024abdbfe2ecbf6e3c416 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Fri, 14 Jul 2023 16:27:29 +0200 Subject: [PATCH 119/208] #38: minor fixes --- docs/dist/documentation.md | 6 +++--- lib/index.js | 15 +++------------ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index ca6ced18f..edf0efb31 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -522,7 +522,7 @@ main class * [.schedule(businessUnit, [selectedType], [keys])](#Mcdev.schedule) ⇒ Promise.<boolean> * [.execute(businessUnit, [selectedType], [keys])](#Mcdev.execute) ⇒ Promise.<boolean> * [.pause(businessUnit, [selectedType], [keys])](#Mcdev.pause) ⇒ Promise.<boolean> - * [.fixKeys(businessUnit, type, [keys])](#Mcdev.fixKeys) ⇒ Array + * [.fixKeys(businessUnit, type, [keys])](#Mcdev.fixKeys) ⇒ Array.<string> @@ -819,11 +819,11 @@ pause an item -### Mcdev.fixKeys(businessUnit, type, [keys]) ⇒ Array +### Mcdev.fixKeys(businessUnit, type, [keys]) ⇒ Array.<string> Updates the key to match the name field **Kind**: static method of [Mcdev](#Mcdev) -**Returns**: Array - array of fixedKeys +**Returns**: Array.<string> - list of fixedKeys | Param | Type | Description | | --- | --- | --- | diff --git a/lib/index.js b/lib/index.js index 12bd90f8d..741ad22ff 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1022,7 +1022,7 @@ class Mcdev { * @param {string} businessUnit name of BU * @param {TYPE.SupportedMetadataTypes} type limit execution to given metadata type * @param {string[]} [keys] customerkey of the metadata - * @returns {Array} array of fixedKeys + * @returns {string[]} list of fixedKeys */ static async fixKeys(businessUnit, type, keys) { Util.startLogger(); @@ -1068,16 +1068,6 @@ class Mcdev { const retrieved = await retriever.retrieve([type], keys, null, false); const typeArr = Object.values(retrieved)[0]; - // merge results if multiple keys were provided - if (keys?.length > 1) { - const base = typeArr[0]; - for (let i = 1; i < typeArr.length; i++) { - // merge all items into the first array - Object.assign(base, typeArr[i]); - } - // kick out all but first entry - typeArr.length = 1; - } const keysForDeploy = MetadataTypeInfo[type].getKeysForFixing(typeArr[0], type); numItemsToUpdate = keysForDeploy.length; if (numItemsToUpdate < 1) { @@ -1088,6 +1078,7 @@ class Mcdev { properties.directories.deploy = properties.directories.retrieve; deployed = await Deployer._deployBU(cred, bu, properties, [type], keysForDeploy, true); const dependentTypes = await this.#getDependentMetadata(type); + // TODO retrieve and update other types that are dependent on this type. Util.logger.warn( `Keys for type '${type}' were updated. Retrieve '${dependentTypes.join( ',' @@ -1105,7 +1096,7 @@ class Mcdev { * @private * * @param {string} type type of the metadata passed as a parameter to fixKeys function - * @returns {Array} array of types that depend on the given type + * @returns {string[]} array of types that depend on the given type */ static async #getDependentMetadata(type) { const dependencies = []; From afd8ca66f8f9c534b232724867aae9e6b91edb27 Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Fri, 14 Jul 2023 16:36:14 +0200 Subject: [PATCH 120/208] #38: removed unnecessary file --- .../patch-response.json | 85 ------------------- 1 file changed, 85 deletions(-) delete mode 100644 test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json diff --git a/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json b/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json deleted file mode 100644 index 58ec6b51c..000000000 --- a/test/resources/9999999/automation/v1/automations/08afb0e2-b00a-4c88-ad2e-pause/patch-response.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "id": "08afb0e2-b00a-4c88-ad2e-pause", - "name": "testExisting_automation_pause", - "description": "bla bla", - "key": "testExisting_automation_pause", - "typeId": 1, - "type": "scheduled", - "statusId": 4, - "status": "Scheduled", - "categoryId": 290937, - "schedule": { - "id": "b393aa6c-a4a8-4c0f-a148-9250258a7339", - "typeId": 3, - "startDate": "2022-07-30T00:00:00", - "endDate": "2022-07-30T00:00:00", - "scheduledTime": "0001-01-01T07:00:00", - "rangeTypeId": 0, - "occurrences": 1, - "pattern": "01", - "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1", - "timezoneName": "W. Europe Standard Time", - "scheduleStatus": "scheduled", - "timezoneId": 5 - }, - "steps": [ - { - "id": "13fda077-0e82-4936-b936-a36b0997fc44", - "name": "", - "step": 1, - "activities": [ - { - "id": "8081a992-a27d-4a43-984a-d60114ea1025", - "name": "testExisting_dataExtract", - "activityObjectId": "56c5370a-f988-4f36-b0ee-0f876573f6d7", - "objectTypeId": 73, - "displayOrder": 1 - }, - { - "id": "d3774dc2-a271-4a44-8cbe-f630a6d6545e", - "name": "testExisting_emailSend", - "activityObjectId": "9b1c7bf9-4964-ed11-b849-48df37d1de8b", - "objectTypeId": 42, - "displayOrder": 2 - }, - { - "id": "2c77fc42-85eb-4611-98f9-223d29d89d72", - "name": "testExisting_fileTransfer", - "activityObjectId": "72c328ac-f5b0-4e37-91d3-a775666f15a6", - "objectTypeId": 53, - "displayOrder": 3 - }, - { - "id": "298b2794-28cb-4c70-b7ad-58b2c8cf48f7", - "name": "testExisting_importFile", - "activityObjectId": "9d16f42c-2260-ed11-b849-48df37d1de8b", - "objectTypeId": 43, - "displayOrder": 4, - "targetDataExtensions": [ - { - "id": "21711373-72c1-ec11-b83b-48df37d1deb7", - "name": "testExisting_dataExtension", - "key": "testExisting_dataExtension", - "description": "bla bla", - "rowCount": 0 - } - ] - }, - { - "id": "e3774dc2-a271-4a44-8cbe-f630a6d6545e", - "name": "testExisting_query_WRONG_NAME", - "activityObjectId": "549f0568-607c-4940-afef-437965094dat", - "objectTypeId": 300, - "displayOrder": 5 - }, - { - "id": "g3774dc2-a271-4a44-8cbe-f630a6d6545e", - "name": "testExisting_script", - "activityObjectId": "39f6a488-20eb-4ba0-b0b9-023725b574e4", - "objectTypeId": 423, - "displayOrder": 6 - } - ] - } - ] -} From 156d0ecca5b34b7edd9b351eddff30fe71f9215f Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Fri, 14 Jul 2023 18:12:11 +0200 Subject: [PATCH 121/208] #38: test exec context does not reset after execution of prev class --- lib/index.js | 2 +- test/type.query.test.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 741ad22ff..978b0e6ba 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1080,7 +1080,7 @@ class Mcdev { const dependentTypes = await this.#getDependentMetadata(type); // TODO retrieve and update other types that are dependent on this type. Util.logger.warn( - `Keys for type '${type}' were updated. Retrieve '${dependentTypes.join( + `Keys for type '${type}' were updated. Retrieve types'${dependentTypes.join( ',' )}' again to have up-to-date data in your retrieve folder` ); diff --git a/test/type.query.test.js b/test/type.query.test.js index b49bc9746..7b2c1dcf1 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -8,6 +8,7 @@ const file = chaiFiles.file; const cache = require('../lib/util/cache'); const testUtils = require('./utils'); const handler = require('../lib/index'); +const config = require('./../lib/util/config'); describe('type: query', () => { beforeEach(() => { @@ -247,6 +248,8 @@ describe('type: query', () => { return; }); it('Should fixKeys and deploy', async () => { + const properties = await config.getProperties(); + const deployDir = properties.directories.deploy; // WHEN const resultFixKeys = await handler.fixKeys('testInstance/testBU', 'query', [ 'testExisting_query_fixKeys', @@ -279,6 +282,7 @@ describe('type: query', () => { 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); + properties.directories.deploy = deployDir; return; }); }); From 15e89cde2f13ae9544f1062615d722a0f72a1a83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Sun, 16 Jul 2023 13:11:34 +0200 Subject: [PATCH 122/208] #1028: refactoring for fromRetrieve option --- docs/dist/documentation.md | 30 +++++++++++++----------------- lib/Deployer.js | 30 ++++++++++++++---------------- lib/index.js | 5 ++--- 3 files changed, 29 insertions(+), 36 deletions(-) diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 57e14a1e0..51675248b 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -395,10 +395,10 @@ Source and target business units are also compared before the deployment to appl * [new Deployer(properties, buObject)](#new_Deployer_new) * _instance_ * [.metadata](#Deployer+metadata) : TYPE.MultiMetadataTypeMap - * [._deploy([typeArr], [keyArr], [fromRetrieve])](#Deployer+_deploy) ⇒ Promise.<TYPE.MultiMetadataTypeMap> + * [._deploy([typeArr], [keyArr])](#Deployer+_deploy) ⇒ Promise.<TYPE.MultiMetadataTypeMap> * _static_ - * [.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve])](#Deployer.deploy) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> - * [._deployBU(cred, bu, properties, [typeArr], [keyArr], [fromRetrieve])](#Deployer._deployBU) ⇒ Promise.<TYPE.MultiMetadataTypeMap> + * [.deploy(businessUnit, [selectedTypesArr], [keyArr])](#Deployer.deploy) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> + * [._deployBU(cred, bu, properties, [typeArr], [keyArr])](#Deployer._deployBU) ⇒ Promise.<TYPE.MultiMetadataTypeMap> * [.readBUMetadata(deployDir, [typeArr], [listBadKeys])](#Deployer.readBUMetadata) ⇒ TYPE.MultiMetadataTypeMap * [.createFolderDefinitions(deployDir, metadata, metadataTypeArr)](#Deployer.createFolderDefinitions) ⇒ void @@ -419,7 +419,7 @@ Creates a Deployer, uses v2 auth if v2AuthOptions are passed. **Kind**: instance property of [Deployer](#Deployer) -### deployer.\_deploy([typeArr], [keyArr], [fromRetrieve]) ⇒ Promise.<TYPE.MultiMetadataTypeMap> +### deployer.\_deploy([typeArr], [keyArr]) ⇒ Promise.<TYPE.MultiMetadataTypeMap> Deploy all metadata that is located in the deployDir **Kind**: instance method of [Deployer](#Deployer) @@ -429,11 +429,10 @@ Deploy all metadata that is located in the deployDir | --- | --- | --- | | [typeArr] | Array.<TYPE.SupportedMetadataTypes> | limit deployment to given metadata type (can include subtype) | | [keyArr] | Array.<string> | limit deployment to given metadata keys | -| [fromRetrieve] | boolean | if true, no folders will be updated/created | -### Deployer.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve]) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> +### Deployer.deploy(businessUnit, [selectedTypesArr], [keyArr]) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> Deploys all metadata located in the 'deploy' directory to the specified business unit **Kind**: static method of [Deployer](#Deployer) @@ -444,11 +443,10 @@ Deploys all metadata located in the 'deploy' directory to the specified business | businessUnit | string | references credentials from properties.json | | [selectedTypesArr] | Array.<TYPE.SupportedMetadataTypes> | limit deployment to given metadata type | | [keyArr] | Array.<string> | limit deployment to given metadata keys | -| [fromRetrieve] | boolean | optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder | -### Deployer.\_deployBU(cred, bu, properties, [typeArr], [keyArr], [fromRetrieve]) ⇒ Promise.<TYPE.MultiMetadataTypeMap> +### Deployer.\_deployBU(cred, bu, properties, [typeArr], [keyArr]) ⇒ Promise.<TYPE.MultiMetadataTypeMap> helper for [deploy](#Deployer.deploy) **Kind**: static method of [Deployer](#Deployer) @@ -461,7 +459,6 @@ helper for [deploy](#Deployer.deploy) | properties | TYPE.Mcdevrc | General configuration to be used in retrieve | | [typeArr] | Array.<TYPE.SupportedMetadataTypes> | limit deployment to given metadata type | | [keyArr] | Array.<string> | limit deployment to given metadata keys | -| [fromRetrieve] | boolean | optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder | @@ -506,7 +503,7 @@ main class * [.explainTypes()](#Mcdev.explainTypes) ⇒ Array.<object> * [.upgrade()](#Mcdev.upgrade) ⇒ Promise.<boolean> * [.retrieve(businessUnit, [selectedTypesArr], [keys], [changelogOnly])](#Mcdev.retrieve) ⇒ Promise.<object> - * [.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve])](#Mcdev.deploy) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> + * [.deploy(businessUnit, [selectedTypesArr], [keyArr])](#Mcdev.deploy) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> * [.initProject([credentialsName])](#Mcdev.initProject) ⇒ Promise.<void> * [.joinProject()](#Mcdev.joinProject) ⇒ Promise.<void> * [.findBUs(credentialsName)](#Mcdev.findBUs) ⇒ Promise.<void> @@ -606,18 +603,17 @@ Retrieve all metadata from the specified business unit into the local file syste -### Mcdev.deploy(businessUnit, [selectedTypesArr], [keyArr], [fromRetrieve]) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> +### Mcdev.deploy(businessUnit, [selectedTypesArr], [keyArr]) ⇒ Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> Deploys all metadata located in the 'deploy' directory to the specified business unit **Kind**: static method of [Mcdev](#Mcdev) **Returns**: Promise.<Object.<string, TYPE.MultiMetadataTypeMap>> - deployed metadata per BU (first key: bu name, second key: metadata type) -| Param | Type | Default | Description | -| --- | --- | --- | --- | -| businessUnit | string | | references credentials from properties.json | -| [selectedTypesArr] | Array.<TYPE.SupportedMetadataTypes> | | limit deployment to given metadata type | -| [keyArr] | Array.<string> | | limit deployment to given metadata keys | -| [fromRetrieve] | boolean | false | optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder | +| Param | Type | Description | +| --- | --- | --- | +| businessUnit | string | references credentials from properties.json | +| [selectedTypesArr] | Array.<TYPE.SupportedMetadataTypes> | limit deployment to given metadata type | +| [keyArr] | Array.<string> | limit deployment to given metadata keys | diff --git a/lib/Deployer.js b/lib/Deployer.js index 8df75ff6d..2faefa95d 100644 --- a/lib/Deployer.js +++ b/lib/Deployer.js @@ -44,17 +44,17 @@ class Deployer { * @param {string} businessUnit references credentials from properties.json * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit deployment to given metadata type * @param {string[]} [keyArr] limit deployment to given metadata keys - * @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder * @returns {Promise.>} deployed metadata per BU (first key: bu name, second key: metadata type) */ - static async deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve) { + static async deploy(businessUnit, selectedTypesArr, keyArr) { Util.logger.info('mcdev:: Deploy'); const buMultiMetadataTypeMap = {}; const properties = await config.getProperties(); if (!(await config.checkProperties(properties))) { return null; } - if (fromRetrieve) { + const deployDirBak = properties.directories.deploy; + if (Util.OPTIONS.fromRetrieve) { properties.directories.deploy = properties.directories.retrieve; } if (Array.isArray(selectedTypesArr)) { @@ -66,7 +66,7 @@ class Deployer { } } if ( - fromRetrieve && + Util.OPTIONS.fromRetrieve && (!selectedTypesArr || !Array.isArray(selectedTypesArr) || !selectedTypesArr.length || @@ -97,8 +97,7 @@ class Deployer { bu, properties, selectedTypesArr, - keyArr, - fromRetrieve + keyArr ); buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap; counter_credBu++; @@ -151,8 +150,7 @@ class Deployer { buPath, properties, selectedTypesArr, - keyArr, - fromRetrieve + keyArr ); buMultiMetadataTypeMap[cred + '/' + buPath] = multiMetadataTypeMap; counter_credBu++; @@ -167,13 +165,15 @@ class Deployer { bu, properties, selectedTypesArr, - keyArr, - fromRetrieve + keyArr ); counter_credBu++; buMultiMetadataTypeMap[cred + '/' + bu] = multiMetadataTypeMap; } } + if (Util.OPTIONS.fromRetrieve) { + properties.directories.deploy = deployDirBak; + } if (counter_credBu !== 0) { Util.logger.info(`\n :: Deployed ${counter_credBu} BUs\n`); } @@ -187,10 +187,9 @@ class Deployer { * @param {TYPE.Mcdevrc} properties General configuration to be used in retrieve * @param {TYPE.SupportedMetadataTypes[]} [typeArr] limit deployment to given metadata type * @param {string[]} [keyArr] limit deployment to given metadata keys - * @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder * @returns {Promise.} ensure that BUs are worked on sequentially */ - static async _deployBU(cred, bu, properties, typeArr, keyArr, fromRetrieve) { + static async _deployBU(cred, bu, properties, typeArr, keyArr) { const buPath = `${cred}/${bu}`; Util.logger.info(`:: Deploying to ${buPath}`); const buObject = await Cli.getCredentialObject(properties, buPath, null, true); @@ -201,7 +200,7 @@ class Deployer { const deployer = new Deployer(properties, buObject); try { // await is required or the calls end up conflicting - multiMetadataTypeMap = await deployer._deploy(typeArr, keyArr, fromRetrieve); + multiMetadataTypeMap = await deployer._deploy(typeArr, keyArr); } catch (ex) { Util.logger.errorStack(ex, 'mcdev.deploy failed'); } @@ -214,10 +213,9 @@ class Deployer { * * @param {TYPE.SupportedMetadataTypes[]} [typeArr] limit deployment to given metadata type (can include subtype) * @param {string[]} [keyArr] limit deployment to given metadata keys - * @param {boolean} [fromRetrieve] if true, no folders will be updated/created * @returns {Promise.} Promise of all deployed metadata */ - async _deploy(typeArr, keyArr, fromRetrieve) { + async _deploy(typeArr, keyArr) { if (await File.pathExists(this.deployDir)) { /** @type {TYPE.MultiMetadataTypeMap} */ this.metadata = Deployer.readBUMetadata(this.deployDir, typeArr); @@ -251,7 +249,7 @@ class Deployer { } } - if (!fromRetrieve) { + if (!Util.OPTIONS.fromRetrieve) { await Deployer.createFolderDefinitions( this.deployDir, this.metadata, diff --git a/lib/index.js b/lib/index.js index 19b625ec7..3bd8ca25a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -381,12 +381,11 @@ class Mcdev { * @param {string} businessUnit references credentials from properties.json * @param {TYPE.SupportedMetadataTypes[]} [selectedTypesArr] limit deployment to given metadata type * @param {string[]} [keyArr] limit deployment to given metadata keys - * @param {boolean} [fromRetrieve] optionally deploy whats defined via selectedTypesArr + keyArr directly from retrieve folder instead of from deploy folder * @returns {Promise.>} deployed metadata per BU (first key: bu name, second key: metadata type) */ - static async deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve = false) { + static async deploy(businessUnit, selectedTypesArr, keyArr) { Util.startLogger(); - return Deployer.deploy(businessUnit, selectedTypesArr, keyArr, fromRetrieve); + return Deployer.deploy(businessUnit, selectedTypesArr, keyArr); } /** From 92e389f0b113e4319b633f30f2d96f67433c295d Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Sun, 16 Jul 2023 21:47:37 +0200 Subject: [PATCH 123/208] #38: set deploy dir --- lib/index.js | 5 ++--- test/type.query.test.js | 4 ---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/index.js b/lib/index.js index 8327011b1..1d82c7263 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1074,8 +1074,7 @@ class Mcdev { return true; } Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; - properties.directories.deploy = properties.directories.retrieve; - deployed = await Deployer._deployBU(cred, bu, properties, [type], keysForDeploy, true); + deployed = await Deployer.deploy(businessUnit, [type], keysForDeploy, true); const dependentTypes = await this.#getDependentMetadata(type); // TODO retrieve and update other types that are dependent on this type. Util.logger.warn( @@ -1087,7 +1086,7 @@ class Mcdev { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } Util.logger.info(`\n :: Done\n`); - return Object.keys(Object.values(deployed)[0]); + return Object.keys(Object.values(Object.values(deployed)[0])[0]); } /** *helper for {@link Mcdev.fixKeys}. Retrieve dependent metadata diff --git a/test/type.query.test.js b/test/type.query.test.js index 7b2c1dcf1..b49bc9746 100644 --- a/test/type.query.test.js +++ b/test/type.query.test.js @@ -8,7 +8,6 @@ const file = chaiFiles.file; const cache = require('../lib/util/cache'); const testUtils = require('./utils'); const handler = require('../lib/index'); -const config = require('./../lib/util/config'); describe('type: query', () => { beforeEach(() => { @@ -248,8 +247,6 @@ describe('type: query', () => { return; }); it('Should fixKeys and deploy', async () => { - const properties = await config.getProperties(); - const deployDir = properties.directories.deploy; // WHEN const resultFixKeys = await handler.fixKeys('testInstance/testBU', 'query', [ 'testExisting_query_fixKeys', @@ -282,7 +279,6 @@ describe('type: query', () => { 16, 'Unexpected number of requests made. Run testUtils.logAPIHistoryDebug() to see the requests' ); - properties.directories.deploy = deployDir; return; }); }); From e2b10f5f57b819e267d4588c9a5b6c8f30cb1b0e Mon Sep 17 00:00:00 2001 From: Yuliia Likhytska Date: Sun, 16 Jul 2023 22:22:38 +0200 Subject: [PATCH 124/208] #38: set retrieve --- lib/index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/index.js b/lib/index.js index 1d82c7263..96c503a4a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1074,7 +1074,8 @@ class Mcdev { return true; } Util.OPTIONS.changeKeyField = MetadataTypeDefinitions[type].nameField; - deployed = await Deployer.deploy(businessUnit, [type], keysForDeploy, true); + Util.OPTIONS.fromRetrieve = true; + deployed = await Deployer.deploy(businessUnit, [type], keysForDeploy); const dependentTypes = await this.#getDependentMetadata(type); // TODO retrieve and update other types that are dependent on this type. Util.logger.warn( @@ -1098,7 +1099,7 @@ class Mcdev { */ static async #getDependentMetadata(type) { const dependencies = []; - Util.logger.info(`\n :: Retrieving dependent metadata \n`); + Util.logger.info(`\n :: Get dependent metadata types \n`); for (const dependentType of Object.keys(MetadataTypeDefinitions)) { if (MetadataTypeDefinitions[dependentType].dependencies.includes(type)) { dependencies.push(dependentType); From 9b1f939f22420e1f743bb24a50b51030d559dced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Berkefeld?= Date: Mon, 17 Jul 2023 15:36:33 +0200 Subject: [PATCH 125/208] #38: jsdoc & log output improvements --- .github/workflows/coverage-develop-branch.yml | 2 -- .github/workflows/coverage-main-branch.yml | 2 -- .github/workflows/coverage.yml | 2 -- docs/dist/documentation.md | 10 +++++----- lib/Deployer.js | 12 ++++++++---- lib/index.js | 8 ++++++-- lib/metadataTypes/DataExtensionField.js | 2 +- lib/util/util.js | 5 +++-- 8 files changed, 23 insertions(+), 20 deletions(-) diff --git a/.github/workflows/coverage-develop-branch.yml b/.github/workflows/coverage-develop-branch.yml index d14c5fbe3..6122489af 100644 --- a/.github/workflows/coverage-develop-branch.yml +++ b/.github/workflows/coverage-develop-branch.yml @@ -26,8 +26,6 @@ jobs: - run: npm ci --ignore-scripts - - run: npm run lint - - name: Run mcdev-tests with coverage run: npm run coverage diff --git a/.github/workflows/coverage-main-branch.yml b/.github/workflows/coverage-main-branch.yml index 9aa2b1ff3..00f3883ec 100644 --- a/.github/workflows/coverage-main-branch.yml +++ b/.github/workflows/coverage-main-branch.yml @@ -26,8 +26,6 @@ jobs: - run: npm ci --ignore-scripts - - run: npm run lint - - name: Run mcdev-tests with coverage run: npm run coverage diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 82d75fb38..81689ff67 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -23,8 +23,6 @@ jobs: - run: npm ci --ignore-scripts - - run: npm run lint - - name: Run mcdev-tests with coverage run: npm run coverage diff --git a/docs/dist/documentation.md b/docs/dist/documentation.md index 98e0dcaf6..340d4ec3a 100644 --- a/docs/dist/documentation.md +++ b/docs/dist/documentation.md @@ -2036,7 +2036,7 @@ Retrieves all records for caching ### DataExtensionField.convertToSortedArray(fieldsObj) ⇒ Array.<TYPE.DataExtensionFieldItem> -helper for [DataExtension._retrieveFieldsForSingleDe](DataExtension._retrieveFieldsForSingleDe) that sorts the fields into an array +helper for DataExtension.retrieveFieldsForSingleDe that sorts the fields into an array **Kind**: static method of [DataExtensionField](#DataExtensionField) **Returns**: Array.<TYPE.DataExtensionFieldItem> - sorted array of field objects @@ -6170,7 +6170,7 @@ SFMC accepts multiple false values for Boolean attributes for which we are check ### Util.\_isValidType(selectedType, [handleOutside]) ⇒ boolean -helper for [retrieve](#Mcdev.retrieve), [retrieveAsTemplate](#Mcdev.retrieveAsTemplate) and [deploy](#Mcdev.deploy) +helper for Mcdev.retrieve, Mcdev.retrieveAsTemplate and Mcdev.deploy **Kind**: static method of [Util](#Util) **Returns**: boolean - type ok or not @@ -6394,7 +6394,7 @@ pause execution of code; useful when multiple server calls are dependent on each ### Util.getSsjs(code) ⇒ string -helper for [_extractCode](#Asset._extractCode) and [prepExtractedCode](#Script.prepExtractedCode) to determine if a code block is a valid SSJS block +helper for Asset.extractCode and Script.prepExtractedCode to determine if a code block is a valid SSJS block **Kind**: static method of [Util](#Util) **Returns**: string - the SSJS code if code block is a valid SSJS block, otherwise null @@ -8101,7 +8101,7 @@ SFMC accepts multiple false values for Boolean attributes for which we are check ### Util.\_isValidType(selectedType, [handleOutside]) ⇒ boolean -helper for [retrieve](#Mcdev.retrieve), [retrieveAsTemplate](#Mcdev.retrieveAsTemplate) and [deploy](#Mcdev.deploy) +helper for Mcdev.retrieve, Mcdev.retrieveAsTemplate and Mcdev.deploy **Kind**: static method of [Util](#Util) **Returns**: boolean - type ok or not @@ -8325,7 +8325,7 @@ pause execution of code; useful when multiple server calls are dependent on each ### Util.getSsjs(code) ⇒ string -helper for [_extractCode](#Asset._extractCode) and [prepExtractedCode](#Script.prepExtractedCode) to determine if a code block is a valid SSJS block +helper for Asset.extractCode and Script.prepExtractedCode to determine if a code block is a valid SSJS block **Kind**: static method of [Util](#Util) **Returns**: string - the SSJS code if code block is a valid SSJS block, otherwise null diff --git a/lib/Deployer.js b/lib/Deployer.js index 2faefa95d..5b4d283ff 100644 --- a/lib/Deployer.js +++ b/lib/Deployer.js @@ -136,7 +136,7 @@ class Deployer { return; } // valid credential given and -all- BUs targeted - Util.logger.info(`\n :: Deploying all BUs for ${cred}`); + Util.logger.info(`:: Deploying all BUs for ${cred}`); let counter_credBu = 0; // for (const bu in properties.credentials[cred].businessUnits) { const deployFolders = await File.readDirectories( @@ -157,7 +157,7 @@ class Deployer { Util.logger.info(''); Util.startLogger(true); } - Util.logger.info(`\n :: ${counter_credBu} BUs for ${cred}\n`); + Util.logger.info(` :: ${counter_credBu} BUs for ${cred}\n`); } else { // either bad credential or specific BU or no BU given const multiMetadataTypeMap = await this._deployBU( @@ -175,7 +175,7 @@ class Deployer { properties.directories.deploy = deployDirBak; } if (counter_credBu !== 0) { - Util.logger.info(`\n :: Deployed ${counter_credBu} BUs\n`); + Util.logger.info(`:: Deployed ${counter_credBu} BUs\n`); } return buMultiMetadataTypeMap; } @@ -289,7 +289,11 @@ class Deployer { // TODO rewrite to allow deploying only a specific sub-type; currently, subtypes are ignored when executing deploy const type = metadataType; if (this.metadata[type]) { - Util.logger.info('Deploying: ' + metadataType); + Util.logger.info( + 'Deploying: ' + + metadataType + + (Util.OPTIONS.fromRetrieve ? ' (from retrieve folder)' : '') + ); const result = await MetadataTypeInfo[type].deploy( this.metadata[type], diff --git a/lib/index.js b/lib/index.js index 96c503a4a..a9344e927 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1054,7 +1054,11 @@ class Mcdev { cred = buObject.credential; bu = buObject.businessUnit; } - Util.logger.info(`\n :: Updating keys for ${type} on ${cred}/${bu}\n`); + Util.logger.info( + `Updating keys for ${type} on ${cred}/${bu}` + + (keys ? Util.getKeysString(keys) : '') + + `\n` + ); try { try { MetadataTypeInfo[type].client = auth.getSDK(buObject); @@ -1086,7 +1090,7 @@ class Mcdev { } catch (ex) { Util.logger.errorStack(ex, 'mcdev.fixKeys failed'); } - Util.logger.info(`\n :: Done\n`); + Util.logger.info(`:: Done\n`); return Object.keys(Object.values(Object.values(deployed)[0])[0]); } /** diff --git a/lib/metadataTypes/DataExtensionField.js b/lib/metadataTypes/DataExtensionField.js index 61b68d642..7af1ab604 100644 --- a/lib/metadataTypes/DataExtensionField.js +++ b/lib/metadataTypes/DataExtensionField.js @@ -31,7 +31,7 @@ class DataExtensionField extends MetadataType { return super.retrieveSOAP(null, requestParams, null, additionalFields); } /** - * helper for {@link DataExtension._retrieveFieldsForSingleDe} that sorts the fields into an array + * helper for DataExtension.retrieveFieldsForSingleDe that sorts the fields into an array * * @param {TYPE.DataExtensionFieldMap} fieldsObj customerKey-based list of fields for one dataExtension * @returns {TYPE.DataExtensionFieldItem[]} sorted array of field objects diff --git a/lib/util/util.js b/lib/util/util.js index 57df86fc9..cb1783d9a 100644 --- a/lib/util/util.js +++ b/lib/util/util.js @@ -151,8 +151,9 @@ const Util = { isFalse(attrValue) { return ['false', 'FALSE', 'False', '0', 0, 'N', false].includes(attrValue); }, + /** - * helper for {@link Mcdev.retrieve}, {@link Mcdev.retrieveAsTemplate} and {@link Mcdev.deploy} + * helper for Mcdev.retrieve, Mcdev.retrieveAsTemplate and Mcdev.deploy * * @param {TYPE.SupportedMetadataTypes} selectedType type or type-subtype * @param {boolean} [handleOutside] if the API reponse is irregular this allows you to handle it outside of this generic method @@ -736,7 +737,7 @@ const Util = { }); }, /** - * helper for {@link Asset._extractCode} and {@link Script.prepExtractedCode} to determine if a code block is a valid SSJS block + * helper for Asset.extractCode and Script.prepExtractedCode to determine if a code block is a valid SSJS block * * @example the following is invalid: *