diff --git a/src/test/suite/commands/wizard/lwcGenerationCommand.test.ts b/src/test/suite/commands/wizard/lwcGenerationCommand.test.ts index 252b6ee6..b08d34ce 100644 --- a/src/test/suite/commands/wizard/lwcGenerationCommand.test.ts +++ b/src/test/suite/commands/wizard/lwcGenerationCommand.test.ts @@ -102,8 +102,8 @@ suite('LWC Generation Command Test Suite', () => { const fsAccess = sinon.stub(fs, 'access'); fsAccess.returns(); const invalidJsonFile = 'landing_page.json'; - const invalidJsonContents = 'invalid_json_here'; - fs.writeFileSync(invalidJsonFile, invalidJsonContents, 'utf8'); + const invalidJsonContent = 'invalid_json_here'; + fs.writeFileSync(invalidJsonFile, invalidJsonContent, 'utf8'); const status = await LwcGenerationCommand.getSObjectsFromLandingPage(); @@ -121,10 +121,45 @@ suite('LWC Generation Command Test Suite', () => { const fsAccess = sinon.stub(fs, 'access'); fsAccess.returns(); const validJsonFile = 'landing_page.json'; - const jsonContents = - '{ "definition": "mcf/list", "properties": { "objectApiName": "Account" }, "nested": { "definition": "mcf/timedList", "properties": { "objectApiName": "Contact"} } }'; - fs.writeFileSync(validJsonFile, jsonContents, 'utf8'); - + const jsonContent = { + view: { + regions: { + components: { + components: [ + { + regions: { + components: { + components: [ + { + definition: 'mcf/list', + properties: { + objectApiName: 'Account' + } + } + ] + } + } + }, + { + regions: { + components: { + components: [ + { + definition: 'mcf/list', + properties: { + objectApiName: 'Contact' + } + } + ] + } + } + } + ] + } + } + } + }; + fs.writeFileSync(validJsonFile, JSON.stringify(jsonContent), 'utf8'); const status = await LwcGenerationCommand.getSObjectsFromLandingPage(); assert.equal(status.sobjects.length, 2); diff --git a/src/test/suite/utils/data/landing_page_case_management.json b/src/test/suite/utils/data/landing_page_case_management.json new file mode 100644 index 00000000..21728bdc --- /dev/null +++ b/src/test/suite/utils/data/landing_page_case_management.json @@ -0,0 +1,228 @@ +{ + "view": { + "definition": "generated/landing_page", + "name": "component_view", + "properties": {}, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/container", + "name": "container", + "properties": { + "backgroundColor": "#F3F2f2" + }, + "dataProviders": {}, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/card", + "name": "global_actions", + "properties": { + "label": "Global Actions" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcfp/actionList", + "name": "actions_list", + "properties": {}, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcfp/actionItem", + "name": "global_action", + "properties": { + "apiName": "Global.New_Case_Report" + }, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "recent_cases", + "properties": { + "label": "Recent Cases" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/list", + "name": "case_list", + "properties": { + "size": 5, + "objectApiName": "Case", + "fieldMap": { + "mainField": "Subject", + "subField1": "Status" + }, + "fields": { + "Subject": "StringValue", + "Status": "StringValue" + }, + "orderBy": [ + { + "LastViewedDate": "DESC" + } + ] + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/recordRow", + "name": "record_row", + "properties": {}, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "recent_accounts", + "properties": { + "label": "Recent Accounts" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/list", + "name": "account_list", + "properties": { + "size": 5, + "objectApiName": "Account", + "fieldMap": { + "mainField": "Name", + "subField1": "AnnualRevenue", + "subField2": "Industry" + }, + "fields": { + "Name": "StringValue", + "AnnualRevenue": "StringValue", + "Industry": "StringValue" + }, + "orderBy": [ + { + "LastViewedDate": "DESC" + } + ] + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/recordRow", + "name": "record_row", + "properties": {}, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "recent_contacts", + "properties": { + "label": "Recent Contacts" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/list", + "name": "contact_list", + "properties": { + "size": 5, + "objectApiName": "Contact", + "fieldMap": { + "mainField": "Name", + "subField1": "Title" + }, + "fields": { + "Name": "StringValue", + "Title": "StringValue", + "MobilePhone": "StringValue", + "Email": "StringValue" + }, + "orderBy": [ + { + "LastViewedDate": "DESC" + } + ], + "swipeActions": { + "call": [ + { + "label": "Mobile", + "value": "MobilePhone" + } + ], + "email": [ + { + "label": "Email", + "value": "Email" + } + ] + } + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/recordRow", + "name": "record_row", + "properties": {}, + "regions": {} + } + ] + } + } + } + ] + } + } + } + ] + } + } + } + ] + } + } + }, + "target": "mcf__native", + "apiName": "landing_page", + "id": "8592e04f-f59b-4a19-9b1f-af7d55f2b491" +} \ No newline at end of file diff --git a/src/test/suite/utils/data/landing_page_default.json b/src/test/suite/utils/data/landing_page_default.json new file mode 100644 index 00000000..25bbdc4e --- /dev/null +++ b/src/test/suite/utils/data/landing_page_default.json @@ -0,0 +1,195 @@ +{ + "view": { + "definition": "generated/landing_page", + "name": "component_view", + "properties": {}, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/container", + "name": "container", + "properties": { + "backgroundColor": "#F3F2f2" + }, + "dataProviders": {}, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/card", + "name": "recently_viewed_contacts", + "properties": { + "label": "Recently Viewed Contacts" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/list", + "name": "contact_list", + "properties": { + "size": 5, + "objectApiName": "Contact", + "swipeActions": { + "call": [ + { + "label": "Mobile", + "value": "MobilePhone" + } + ], + "email": [ + { + "label": "Email", + "value": "Email" + } + ] + }, + "fieldMap": { + "mainField": "Name", + "subField1": "MobilePhone" + }, + "fields": { + "Name": "StringValue", + "MobilePhone": "StringValue", + "Email": "StringValue" + }, + "orderBy": [ + { + "LastViewedDate": "DESC" + } + ] + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/recordRow", + "name": "record_row", + "properties": {}, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "account_card", + "properties": { + "label": "Accounts" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/list", + "name": "account_list", + "properties": { + "size": 5, + "objectApiName": "Account", + "fieldMap": { + "mainField": "Name", + "subField1": "Industry", + "subField2": "Id" + }, + "fields": { + "Name": "StringValue", + "Industry": "StringValue", + "Id": "String" + }, + "orderBy": [ + { + "Name": "ASC" + } + ] + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/recordRow", + "name": "record_row", + "properties": { + "displayIcon": false + }, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "opportunity_card", + "properties": { + "label": "Upcoming Opportunities" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/list", + "name": "opportunity_list", + "properties": { + "size": 3, + "objectApiName": "Opportunity", + "fieldMap": { + "mainField": "Name" + }, + "fields": { + "Name": "StringValue" + }, + "orderBy": [ + { + "CloseDate": "ASC" + } + ] + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/recordRow", + "name": "record_row", + "properties": { + "displayIcon": false + }, + "regions": {} + } + ] + } + } + } + ] + } + } + } + ] + } + } + } + ] + } + } + }, + "target": "mcf__native", + "apiName": "landing_page", + "id": "8592e04f-f59b-4a19-9b1f-af7d55f2b491" +} \ No newline at end of file diff --git a/src/test/suite/utils/data/landing_page_healthcare.json b/src/test/suite/utils/data/landing_page_healthcare.json new file mode 100644 index 00000000..1727d260 --- /dev/null +++ b/src/test/suite/utils/data/landing_page_healthcare.json @@ -0,0 +1,252 @@ +{ + "view": { + "definition": "generated/landing_page", + "name": "component_view", + "properties": {}, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/container", + "name": "container", + "properties": { + "backgroundColor": "#F3F2f2" + }, + "dataProviders": {}, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/card", + "name": "global_actions", + "properties": { + "label": "Global Actions" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcfp/actionList", + "name": "actions_list", + "properties": {}, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcfp/actionItem", + "name": "global_action", + "properties": { + "apiName": "Global.Barcode_Scanner" + }, + "regions": {} + }, + { + "definition": "mcfp/actionItem", + "name": "global_action", + "properties": { + "apiName": "Global.New_Visit" + }, + "regions": {} + }, + { + "definition": "mcfp/actionItem", + "name": "global_action", + "properties": { + "apiName": "Global.New_Visitor" + }, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "component_view", + "properties": { + "label": "Today's Events" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/timedList", + "name": "visits_list", + "properties": { + "size": 5, + "objectApiName": "Visit", + "fieldMap": { + "mainField": "Name", + "startTime": "PlannedVisitStartTime", + "endTime": "PlannedVisitEndTime", + "subField1": "VisitPriority" + }, + "fields": { + "Name": "StringValue", + "PlannedVisitStartTime": "DateTimeValue", + "PlannedVisitEndTime": "DateTimeValue", + "VisitPriority": "StringValue", + "AddressId": "StringValue" + }, + "swipeActions": { + "map": [ + { + "label": "Navigate", + "value": { + "address": "AddressId" + } + } + ] + } + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/timedRow", + "name": "component_view", + "properties": {}, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "recent_contacts", + "properties": { + "label": "Recent Contacts" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/list", + "name": "contact_list", + "properties": { + "size": 5, + "objectApiName": "Contact", + "fieldMap": { + "mainField": "Name", + "subField1": "Email", + "subField2": "Title" + }, + "fields": { + "Name": "StringValue", + "Department": "StringValue", + "Title": "StringValue", + "MobilePhone": "StringValue", + "Email": "StringValue" + }, + "orderBy": [ + { + "LastViewedDate": "DESC" + } + ], + "swipeActions": { + "call": [ + { + "label": "Mobile", + "value": "MobilePhone" + } + ], + "email": [ + { + "label": "Email", + "value": "Email" + } + ] + } + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/recordRow", + "name": "record_row", + "properties": {}, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "recent_visitors", + "properties": { + "label": "Recent Visitors" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/list", + "name": "visitor_list", + "properties": { + "size": 5, + "objectApiName": "Visitor", + "fieldMap": { + "mainField": "Name" + }, + "fields": { + "Name": "StringValue" + }, + "orderBy": [ + { + "LastViewedDate": "DESC" + } + ] + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/recordRow", + "name": "record_row", + "properties": {}, + "regions": {} + } + ] + } + } + } + ] + } + } + } + ] + } + } + } + ] + } + } + }, + "target": "mcf__native", + "apiName": "landing_page", + "id": "8592e04f-f59b-4a19-9b1f-af7d55f2b491" +} \ No newline at end of file diff --git a/src/test/suite/utils/data/landing_page_retail_execution.json b/src/test/suite/utils/data/landing_page_retail_execution.json new file mode 100644 index 00000000..5534d403 --- /dev/null +++ b/src/test/suite/utils/data/landing_page_retail_execution.json @@ -0,0 +1,304 @@ +{ + "view": { + "definition": "generated/landing_page", + "name": "component_view", + "properties": {}, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/container", + "name": "container", + "properties": { + "backgroundColor": "#F3F2f2" + }, + "dataProviders": {}, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/card", + "name": "global_actions", + "properties": { + "label": "Global Actions" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcfp/actionList", + "name": "actions_list", + "properties": {}, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcfp/actionItem", + "name": "global_action", + "properties": { + "apiName": "Global.New_Opportunity" + }, + "regions": {} + }, + { + "definition": "mcfp/actionItem", + "name": "global_action", + "properties": { + "apiName": "Global.New_Lead" + }, + "regions": {} + }, + { + "definition": "mcfp/actionItem", + "name": "global_action", + "properties": { + "apiName": "Global.New_Account" + }, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "component_view", + "properties": { + "label": "Today's Events" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/timedList", + "name": "visits_list", + "properties": { + "size": 5, + "objectApiName": "Visit", + "fieldMap": { + "mainField": "Name", + "startTime": "PlannedVisitStartTime", + "endTime": "PlannedVisitEndTime", + "subField1": "Status" + }, + "fields": { + "Name": "StringValue", + "PlannedVisitStartTime": "DateTimeValue", + "PlannedVisitEndTime": "DateTimeValue", + "AddressId": "StringValue", + "Status": "StringValue" + }, + "swipeActions": { + "map": [ + { + "label": "Navigate", + "value": { + "address": "AddressId" + } + } + ] + } + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/timedRow", + "name": "component_view", + "properties": {}, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "last_modified_accounts", + "properties": { + "label": "Accounts" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/list", + "name": "accounts_list", + "properties": { + "size": 5, + "objectApiName": "Account", + "fieldMap": { + "mainField": "Name", + "subField1": "Phone" + }, + "fields": { + "Name": "StringValue", + "Phone": "StringValue" + }, + "orderBy": [ + { + "LastModifiedDate": "DESC" + } + ] + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/recordRow", + "name": "record_row", + "properties": {}, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "opportunities", + "properties": { + "label": "Opportunities" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/list", + "name": "opportunities_list", + "properties": { + "size": 5, + "objectApiName": "Opportunity", + "fieldMap": { + "mainField": "Name", + "subField1": "CloseDate", + "subField2": "Amount" + }, + "fields": { + "Name": "StringValue", + "CloseDate": "DateValue", + "Amount": "StringValue" + }, + "orderBy": [ + { + "CloseDate": "DESC" + } + ] + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/recordRow", + "name": "record_row", + "properties": {}, + "regions": {} + } + ] + } + } + } + ] + } + } + }, + { + "definition": "mcf/card", + "name": "last_modified_leads", + "properties": { + "label": "Leads" + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/list", + "name": "leads_list", + "properties": { + "size": 5, + "objectApiName": "Lead", + "fieldMap": { + "mainField": "Name", + "subField1": "Company", + "subField2": "Industry" + }, + "fields": { + "Name": "StringValue", + "Company": "StringValue", + "Industry": "StringValue", + "Phone": "StringValue", + "Email": "StringValue" + }, + "orderBy": [ + { + "LastModifiedDate": "DESC" + } + ], + "swipeActions": { + "call": [ + { + "label": "Call", + "value": "Phone" + } + ], + "email": [ + { + "label": "Email", + "value": "Email" + } + ] + } + }, + "regions": { + "components": { + "name": "components", + "components": [ + { + "definition": "mcf/recordRow", + "name": "record_row", + "properties": {}, + "regions": {} + } + ] + } + } + } + ] + } + } + } + ] + } + } + } + ] + } + } + }, + "target": "mcf__native", + "apiName": "landing_page", + "id": "8592e04f-f59b-4a19-9b1f-af7d55f2b491" +} \ No newline at end of file diff --git a/src/test/suite/utils/uemParser.test.ts b/src/test/suite/utils/uemParser.test.ts index 1e35c985..58d9adf7 100644 --- a/src/test/suite/utils/uemParser.test.ts +++ b/src/test/suite/utils/uemParser.test.ts @@ -6,97 +6,74 @@ */ import * as assert from 'assert'; +import * as path from 'path'; import { UEMParser } from '../../../utils/uemParser'; +import { CommonUtils } from '@salesforce/lwc-dev-mobile-core'; suite('UEM Parser Test Suite', () => { - test('Empty object returns empty array', async () => { + test('Empty object as input returns empty array', async () => { const sObjects = UEMParser.findSObjects({}); assert.equal(sObjects.length, 0); }); - test('Object with a target field returns array size of one', async () => { - const landingPage = { - definition: 'mcf/list', - properties: { - objectApiName: 'foo' - } - }; - + test('Default landing page as input returns correct sObjects', async () => { + const jsonPath = path.join( + __dirname, + 'data', + 'landing_page_default.json' + ); + const landingPage = CommonUtils.loadJsonFromFile(jsonPath); const sObjects = UEMParser.findSObjects(landingPage); - assert.equal(sObjects.length, 1); - assert.equal(sObjects[0], 'foo'); - }); - test('Nested object returns all values of the target field', async () => { - const landingPage = { - definition: 'mcf/list', - properties: { - objectApiName: 'foo' - }, - nested: { - definition: 'mcf/list', - properties: { - objectApiName: 'bar' - } - } - }; + assert.equal(sObjects.length, 3); + assert.equal(sObjects[0], 'Contact'); + assert.equal(sObjects[1], 'Account'); + assert.equal(sObjects[2], 'Opportunity'); + }); + test('Case management landing page as input returns correct sObjects.', async () => { + const jsonPath = path.join( + __dirname, + 'data', + 'landing_page_case_management.json' + ); + const landingPage = CommonUtils.loadJsonFromFile(jsonPath); const sObjects = UEMParser.findSObjects(landingPage); - assert.equal(sObjects.length, 2); - assert.equal(sObjects[0], 'foo'); - assert.equal(sObjects[1], 'bar'); - }); - test('Duplicate field values are omitted', async () => { - const landingPage = { - definition: 'mcf/list', - properties: { - objectApiName: 'foo' - }, - nested: { - definition: 'mcf/list', - properties: { - objectApiName: 'bar' - }, - anotherNested: { - definition: 'mcf/list', - properties: { - objectApiName: 'bar' - } - } - } - }; + assert.equal(sObjects.length, 3); + assert.equal(sObjects[0], 'Case'); + assert.equal(sObjects[1], 'Account'); + assert.equal(sObjects[2], 'Contact'); + }); + test('Healthcare landing page as input returns correct sObjects.', async () => { + const jsonPath = path.join( + __dirname, + 'data', + 'landing_page_healthcare.json' + ); + const landingPage = CommonUtils.loadJsonFromFile(jsonPath); const sObjects = UEMParser.findSObjects(landingPage); - assert.equal(sObjects.length, 2); - assert.equal(sObjects[0], 'foo'); - assert.equal(sObjects[1], 'bar'); - }); - test('Duplicat field values are omitted', async () => { - const landingPage = { - definition: 'mcf/list', - properties: { - objectApiName: 'plain' - }, - nested: { - definition: 'mcf/timedList', - properties: { - objectApiName: 'timed' - }, - anotherNested: { - definition: 'mcf/genericLists', - properties: { - objectApiName: 'generic' - } - } - } - }; + assert.equal(sObjects.length, 3); + assert.equal(sObjects[0], 'Visit'); + assert.equal(sObjects[1], 'Contact'); + assert.equal(sObjects[2], 'Visitor'); + }); + test('Retail execution landing page as input returns sObjects.', async () => { + const jsonPath = path.join( + __dirname, + 'data', + 'landing_page_retail_execution.json' + ); + const landingPage = CommonUtils.loadJsonFromFile(jsonPath); const sObjects = UEMParser.findSObjects(landingPage); - assert.equal(sObjects.length, 3); - assert.equal(sObjects[0], 'plain'); - assert.equal(sObjects[1], 'timed'); - assert.equal(sObjects[2], 'generic'); + + assert.equal(sObjects.length, 4); + assert.equal(sObjects[0], 'Visit'); + assert.equal(sObjects[1], 'Account'); + assert.equal(sObjects[2], 'Opportunity'); + assert.equal(sObjects[3], 'Lead'); }); }); diff --git a/src/utils/uemParser.ts b/src/utils/uemParser.ts index 0e3ca1b8..1f1ab68d 100644 --- a/src/utils/uemParser.ts +++ b/src/utils/uemParser.ts @@ -7,61 +7,68 @@ export class UEMParser { public static findSObjects(json: Object): Array { - const sObjects = UEMParser.findObjectsWithValues(json, [ - 'mcf/list', - 'mcf/timedList', - 'mcf/genericLists' - ]); - const results: string[] = []; - - sObjects.forEach((obj) => { - let properties = obj['properties' as keyof Object]; - let objectApiName = properties[ - 'objectApiName' as keyof Object - ] as unknown as string; - - // Only include unique values in the array. - if (!results.includes(objectApiName)) { - results.push(objectApiName); - } - }); + const results = UEMParser.queryJsonWithPath( + json, + 'view.regions.components.components.regions.components.components', + 'objectApiName' + ); return results; } - static findObjectsWithValues( - json: Object, - valuesToMatch: string[] - ): Array { - const results: Array = []; - - if (Array.isArray(json)) { - for (const item of json) { - results.push( - ...UEMParser.findObjectsWithValues(item, valuesToMatch) + private static findKeyValues(nestedJsonBlock: any, key: string): string[] { + if (Array.isArray(nestedJsonBlock)) { + return nestedJsonBlock.reduce((accumulator: any[], item) => { + return accumulator.concat(UEMParser.findKeyValues(item, key)); + }, []); + } else if (typeof nestedJsonBlock === 'object') { + let values: string[] = []; + for (const jsonKey in nestedJsonBlock) { + if (jsonKey === key) { + values.push(nestedJsonBlock[jsonKey]); + } + values = values.concat( + UEMParser.findKeyValues(nestedJsonBlock[jsonKey], key) ); } - } else { - const values = Object.values(json); - - const matched = valuesToMatch.some((value) => - values.includes(value) - ); + return values; + } + return []; + } - if (matched) { - results.push(json); - } + private static queryJsonWithPath( + json: Object, + path: string, + key: string + ): string[] { + const keys = path.split('.'); + let current = json; - for (const key in json) { - results.push( - ...UEMParser.findObjectsWithValues( - json[key as keyof Object], - valuesToMatch - ) - ); + for (const currentKey of keys) { + if (Array.isArray(current)) { + const results: Object[] = []; + for (const item of current) { + if ( + typeof item === 'object' && + item.hasOwnProperty(currentKey) + ) { + results.push(item[currentKey]); + } + } + if (results.length === 0) { + return []; + } + current = results; + } else if ( + typeof current === 'object' && + current.hasOwnProperty(currentKey) + ) { + current = current[currentKey as keyof Object]; + } else { + return []; } } - - return results; + + return UEMParser.findKeyValues(current, key); } }