From b26cb56f23d7008425f70295c4d8c8afde632d7c Mon Sep 17 00:00:00 2001 From: Arthur Date: Mon, 13 Jan 2025 03:50:20 +0000 Subject: [PATCH] done --- src/oneTrust/constants.ts | 7 +- src/oneTrust/flattenOneTrustAssessment.ts | 87 +++++++---------------- src/oneTrust/writeOneTrustAssessment.ts | 20 ++++-- 3 files changed, 49 insertions(+), 65 deletions(-) diff --git a/src/oneTrust/constants.ts b/src/oneTrust/constants.ts index 47738c8b..bb34c2d2 100644 --- a/src/oneTrust/constants.ts +++ b/src/oneTrust/constants.ts @@ -1,10 +1,15 @@ import { createDefaultCodec } from '../helpers'; import { OneTrustCombinedAssessmentCodec } from './codecs'; +import { flattenOneTrustAssessment } from './flattenOneTrustAssessment'; /** * An object with default values of type OneTrustCombinedAssessmentCodec. It's very * valuable when converting assessments to CSV. When we flatten it, the resulting * value always contains all keys that eventually we add to the header. */ -export const DEFAULT_ONE_TRUST_COMBINED_ASSESSMENT: OneTrustCombinedAssessmentCodec = +const DEFAULT_ONE_TRUST_COMBINED_ASSESSMENT: OneTrustCombinedAssessmentCodec = createDefaultCodec(OneTrustCombinedAssessmentCodec); + +export const DEFAULT_ONE_TRUST_ASSESSMENT_CSV_KEYS = Object.keys( + flattenOneTrustAssessment(DEFAULT_ONE_TRUST_COMBINED_ASSESSMENT), +); diff --git a/src/oneTrust/flattenOneTrustAssessment.ts b/src/oneTrust/flattenOneTrustAssessment.ts index 361ece51..6fd45cbb 100644 --- a/src/oneTrust/flattenOneTrustAssessment.ts +++ b/src/oneTrust/flattenOneTrustAssessment.ts @@ -15,7 +15,6 @@ import { OneTrustEnrichedRiskCodec, OneTrustRiskCategories, } from './codecs'; -import { DEFAULT_ONE_TRUST_COMBINED_ASSESSMENT } from './constants'; // import { DEFAULT_ONE_TRUST_COMBINED_ASSESSMENT } from './constants'; // TODO: will have to use something like csv-stringify @@ -240,68 +239,36 @@ const flattenOneTrustSections = ( export const flattenOneTrustAssessment = ( combinedAssessment: OneTrustCombinedAssessmentCodec, ): any => { - /** - * TODO: experiment creating a default assessment with - * const result = createDefaultCodec(OneTrustGetAssessmentResponseCodec); - * Then, flatten it and aggregate it with the actual assessment. This way, every - * assessment will always have the same fields! - */ - - const flatten = (assessment: OneTrustCombinedAssessmentCodec): any => { - const { - approvers, - primaryEntityDetails, - respondents, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - respondent, - sections, - ...rest - } = assessment; - - const flatApprovers = approvers.map((approver) => - flattenObject(approver, 'approvers'), - ); - const flatRespondents = respondents.map((respondent) => - flattenObject(respondent, 'respondents'), - ); - const flatPrimaryEntityDetails = primaryEntityDetails.map( - (primaryEntityDetail) => - flattenObject(primaryEntityDetail, 'primaryEntityDetails'), - ); - - return { - ...flattenObject(rest), - ...aggregateObjects({ objs: flatApprovers }), - ...aggregateObjects({ objs: flatRespondents }), - ...aggregateObjects({ objs: flatPrimaryEntityDetails }), - ...flattenOneTrustSections(sections, 'sections'), - }; - }; - // add default values to assessments const combinedAssessmentWithDefaults = enrichCombinedAssessmentWithDefaults(combinedAssessment); - const combinedAssessmentFlat = flatten(combinedAssessmentWithDefaults); - const defaultAssessmentFlat = flatten(DEFAULT_ONE_TRUST_COMBINED_ASSESSMENT); - - // TODO: test that both have the same keys - const keysOne = Object.keys(combinedAssessmentFlat); - const keysTwo = Object.keys(defaultAssessmentFlat); - - const keysInCombinedOnly = keysOne.filter((k) => !keysTwo.includes(k)); + const { + approvers, + primaryEntityDetails, + respondents, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + respondent, + sections, + ...rest + } = combinedAssessmentWithDefaults; + + const flatApprovers = approvers.map((approver) => + flattenObject(approver, 'approvers'), + ); + const flatRespondents = respondents.map((respondent) => + flattenObject(respondent, 'respondents'), + ); + const flatPrimaryEntityDetails = primaryEntityDetails.map( + (primaryEntityDetail) => + flattenObject(primaryEntityDetail, 'primaryEntityDetails'), + ); - console.log({ - keysInCombinedOnly, - }); - return combinedAssessmentFlat; + return { + ...flattenObject(rest), + ...aggregateObjects({ objs: flatApprovers }), + ...aggregateObjects({ objs: flatRespondents }), + ...aggregateObjects({ objs: flatPrimaryEntityDetails }), + ...flattenOneTrustSections(sections, 'sections'), + }; }; -/** - * - * - * TODO: convert to camelCase -> Title Case - * TODO: section -> header is spread - * TODO: section -> questions -> question is spread - * TODO: section -> questions -> question -> questionOptions are aggregated - * TODO: section -> questions -> question -> questionResponses -> responses are spread - */ diff --git a/src/oneTrust/writeOneTrustAssessment.ts b/src/oneTrust/writeOneTrustAssessment.ts index 1372a7e2..da9f9747 100644 --- a/src/oneTrust/writeOneTrustAssessment.ts +++ b/src/oneTrust/writeOneTrustAssessment.ts @@ -9,6 +9,7 @@ import { } from './codecs'; import fs from 'fs'; import { flattenOneTrustAssessment } from './flattenOneTrustAssessment'; +import { DEFAULT_ONE_TRUST_ASSESSMENT_CSV_KEYS } from './constants'; /** * Write the assessment to disk at the specified file path. @@ -114,21 +115,32 @@ export const writeOneTrustAssessment = ({ fs.writeFileSync('./oneTrust.json', '[\n'); } - const flattened = flattenOneTrustAssessment({ + // flatten the assessment object so it does not have nested properties + const flatAssessment = flattenOneTrustAssessment({ ...assessment, ...enrichedAssessment, }); - const stringifiedFlattened = JSON.stringify(flattened, null, 2); - // TODO: do not forget to ensure we have the same set of keys!!! + + // transform the flat assessment to have all CSV keys in the expected order + const flatAssessmentWithCsvKeys = + DEFAULT_ONE_TRUST_ASSESSMENT_CSV_KEYS.reduce( + (acc, key) => ({ + ...acc, + [key]: flatAssessment[key] ?? '', + }), + {}, + ); + const csvEntry = JSON.stringify(flatAssessmentWithCsvKeys, null, 2); // const stringifiedAssessment = JSON.stringify(enrichedAssessment, null, 2); // Add comma for all items except the last one const comma = index < total - 1 ? ',' : ''; + // TODO: might be better not to convert it to CSV at all! The importOneTrustAssessments does not actually accept CSV. // write to file // fs.appendFileSync(file, stringifiedAssessment + comma); - fs.appendFileSync('./oneTrust.json', stringifiedFlattened + comma); + fs.appendFileSync('./oneTrust.json', csvEntry + comma); // end with closing bracket if (index === total - 1) {