Skip to content

Commit afa8e08

Browse files
committed
Feat: Added a summary view of the audited Data
1 parent b9927cd commit afa8e08

10 files changed

Lines changed: 812 additions & 583 deletions

File tree

package-lock.json

Lines changed: 99 additions & 99 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/contentstack-audit/src/audit-base-command.ts

Lines changed: 145 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,30 @@ import config from './config';
1111
import { print } from './util/log';
1212
import { auditMsg } from './messages';
1313
import { BaseCommand } from './base-command';
14-
import { Entries, GlobalField, ContentType, Extensions, Workflows, Assets, FieldRule } from './modules';
14+
import {
15+
Entries,
16+
GlobalField,
17+
ContentType,
18+
Extensions,
19+
Workflows,
20+
Assets,
21+
FieldRule,
22+
ReadModulesAndGetData,
23+
CustomRoles,
24+
} from './modules';
25+
1526
import {
1627
CommandNames,
1728
ContentTypeStruct,
1829
OutputColumn,
1930
RefErrorReturnType,
2031
WorkflowExtensionsRefErrorReturnType,
2132
} from './types';
22-
import CustomRoles from './modules/custom-roles';
33+
import { size } from 'lodash';
2334

2435
export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseCommand> {
2536
private currentCommand!: CommandNames;
26-
37+
private summaryDataToPrint: Record<string,any> = [];
2738
get fixStatus() {
2839
return {
2940
fixStatus: {
@@ -61,28 +72,41 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
6172
missingEnvLocalesInAssets,
6273
missingEnvLocalesInEntries,
6374
missingFieldRules,
64-
missingMultipleFields
75+
missingMultipleFields,
6576
} = await this.scanAndFix();
6677

67-
this.showOutputOnScreen([
68-
{ module: 'Content types', missingRefs: missingCtRefs },
69-
{ module: 'Global Fields', missingRefs: missingGfRefs },
70-
{ module: 'Entries', missingRefs: missingEntryRefs },
71-
]);
72-
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Extensions', missingRefs: missingCtRefsInExtensions }]);
73-
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Workflows', missingRefs: missingCtRefsInWorkflow }]);
74-
75-
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Entries Select Field', missingRefs: missingSelectFeild }]);
76-
this.showOutputOnScreenWorkflowsAndExtension([
77-
{ module: 'Entries Mandatory Field', missingRefs: missingMandatoryFields },
78-
]);
79-
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Entries Title Field', missingRefs: missingTitleFields }]);
80-
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Custom Roles', missingRefs: missingRefInCustomRoles }]);
81-
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Assets', missingRefs: missingEnvLocalesInAssets }]);
82-
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Entries Missing Locale and Environments', missingRefs: missingEnvLocalesInEntries }])
83-
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Field Rules', missingRefs: missingFieldRules }])
84-
85-
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Entries Changed Multiple Fields', missingRefs: missingMultipleFields }])
78+
if (this.flags['show-console-output'] || this.flags['s']) {
79+
this.showOutputOnScreen([
80+
{ module: 'Content types', missingRefs: missingCtRefs },
81+
{ module: 'Global Fields', missingRefs: missingGfRefs },
82+
{ module: 'Entries', missingRefs: missingEntryRefs },
83+
]);
84+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Extensions', missingRefs: missingCtRefsInExtensions }]);
85+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Workflows', missingRefs: missingCtRefsInWorkflow }]);
86+
87+
this.showOutputOnScreenWorkflowsAndExtension([
88+
{ module: 'Entries Select Field', missingRefs: missingSelectFeild },
89+
]);
90+
this.showOutputOnScreenWorkflowsAndExtension([
91+
{ module: 'Entries Mandatory Field', missingRefs: missingMandatoryFields },
92+
]);
93+
this.showOutputOnScreenWorkflowsAndExtension([
94+
{ module: 'Entries Title Field', missingRefs: missingTitleFields },
95+
]);
96+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Custom Roles', missingRefs: missingRefInCustomRoles }]);
97+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Assets', missingRefs: missingEnvLocalesInAssets }]);
98+
this.showOutputOnScreenWorkflowsAndExtension([
99+
{ module: 'Entries Missing Locale and Environments', missingRefs: missingEnvLocalesInEntries },
100+
]);
101+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Field Rules', missingRefs: missingFieldRules }]);
102+
103+
this.showOutputOnScreenWorkflowsAndExtension([
104+
{ module: 'Entries Changed Multiple Fields', missingRefs: missingMultipleFields },
105+
]);
106+
107+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Summary', missingRefs: this.summaryDataToPrint }]);
108+
}
109+
86110
if (
87111
!isEmpty(missingCtRefs) ||
88112
!isEmpty(missingGfRefs) ||
@@ -93,8 +117,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
93117
!isEmpty(missingTitleFields) ||
94118
!isEmpty(missingRefInCustomRoles) ||
95119
!isEmpty(missingEnvLocalesInAssets) ||
96-
!isEmpty(missingEnvLocalesInEntries) ||
97-
!isEmpty(missingFieldRules) ||
120+
!isEmpty(missingEnvLocalesInEntries) ||
121+
!isEmpty(missingFieldRules) ||
98122
!isEmpty(missingMultipleFields)
99123
) {
100124
if (this.currentCommand === 'cm:stacks:audit') {
@@ -151,8 +175,18 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
151175
missingEnvLocalesInAssets,
152176
missingEnvLocalesInEntries,
153177
missingFieldRules,
154-
missingMultipleFields;
178+
missingMultipleFields,
179+
DataModuleWise: Record<string, any>;
180+
181+
const constructorParam: any = {
182+
ctSchema,
183+
gfSchema,
184+
log: this.log,
185+
config: this.sharedConfig,
186+
fix: this.currentCommand === 'cm:stacks:audit:fix',
187+
};
155188

189+
DataModuleWise = await new ReadModulesAndGetData(cloneDeep(constructorParam)).run();
156190
for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) {
157191
print([
158192
{
@@ -162,35 +196,32 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
162196
},
163197
]);
164198

165-
const constructorParam = {
166-
ctSchema,
167-
gfSchema,
168-
log: this.log,
169-
moduleName: module,
170-
config: this.sharedConfig,
171-
fix: this.currentCommand === 'cm:stacks:audit:fix',
172-
};
199+
constructorParam['moduleName'] = module;
200+
173201
switch (module) {
174202
case 'assets':
175203
missingEnvLocalesInAssets = await new Assets(cloneDeep(constructorParam)).run();
176204
await this.prepareReport(module, missingEnvLocalesInAssets);
205+
await this.getAffectedData('assets', DataModuleWise['assets'], missingEnvLocalesInAssets);
177206
break;
178207
case 'content-types':
179208
missingCtRefs = await new ContentType(cloneDeep(constructorParam)).run();
180209
await this.prepareReport(module, missingCtRefs);
210+
await this.getAffectedData('content-types', DataModuleWise['content-types'], missingCtRefs);
181211
break;
182212
case 'global-fields':
183213
missingGfRefs = await new GlobalField(cloneDeep(constructorParam)).run();
184214
await this.prepareReport(module, missingGfRefs);
215+
await this.getAffectedData('global-fields', DataModuleWise['global-fields'], missingGfRefs);
185216
break;
186217
case 'entries':
187218
missingEntry = await new Entries(cloneDeep(constructorParam)).run();
188219
missingEntryRefs = missingEntry.missingEntryRefs ?? {};
189220
missingSelectFeild = missingEntry.missingSelectFeild ?? {};
190221
missingMandatoryFields = missingEntry.missingMandatoryFields ?? {};
191222
missingTitleFields = missingEntry.missingTitleFields ?? {};
192-
missingEnvLocalesInEntries = missingEntry.missingEnvLocale??{};
193-
missingMultipleFields = missingEntry.missingMultipleFields??{};
223+
missingEnvLocalesInEntries = missingEntry.missingEnvLocale ?? {};
224+
missingMultipleFields = missingEntry.missingMultipleFields ?? {};
194225
await this.prepareReport(module, missingEntryRefs);
195226

196227
await this.prepareReport(`Entries_Select_feild`, missingSelectFeild);
@@ -202,6 +233,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
202233
await this.prepareReport('Entry_Missing_Locale_and_Env_in_Publish_Details', missingEnvLocalesInEntries);
203234

204235
await this.prepareReport('Entry_Multiple_Fields', missingMultipleFields);
236+
await this.getAffectedData('entries', DataModuleWise['entries'], missingEntry);
205237

206238
break;
207239
case 'workflows':
@@ -213,21 +245,26 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
213245
fix: this.currentCommand === 'cm:stacks:audit:fix',
214246
}).run();
215247
await this.prepareReport(module, missingCtRefsInWorkflow);
248+
await this.getAffectedData('workflows', DataModuleWise['workflows'], missingCtRefsInWorkflow);
249+
216250
break;
217251
case 'extensions':
218252
missingCtRefsInExtensions = await new Extensions(cloneDeep(constructorParam)).run();
219253
await this.prepareReport(module, missingCtRefsInExtensions);
254+
await this.getAffectedData('extensions', DataModuleWise['extensions'], missingCtRefsInExtensions);
220255
break;
221256
case 'custom-roles':
222257
missingRefInCustomRoles = await new CustomRoles(cloneDeep(constructorParam)).run();
223258
await this.prepareReport(module, missingRefInCustomRoles);
259+
await this.getAffectedData('custom-roles', DataModuleWise['custom-roles'], missingRefInCustomRoles);
260+
224261
break;
225262
case 'field-rules':
226263
missingFieldRules = await new FieldRule(cloneDeep(constructorParam)).run();
227264
await this.prepareReport(module, missingFieldRules);
265+
await this.getAffectedData('field-rules', DataModuleWise['content-types'], missingFieldRules);
228266
break;
229267
}
230-
231268
print([
232269
{
233270
bold: true,
@@ -242,6 +279,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
242279
]);
243280
}
244281

282+
this.prepareReport('Summary', this.summaryDataToPrint);
283+
this.prepareCSV('Summary', this.summaryDataToPrint);
245284
return {
246285
missingCtRefs,
247286
missingGfRefs,
@@ -255,7 +294,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
255294
missingEnvLocalesInAssets,
256295
missingEnvLocalesInEntries,
257296
missingFieldRules,
258-
missingMultipleFields
297+
missingMultipleFields,
259298
};
260299
}
261300

@@ -409,14 +448,15 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
409448
.map((key: string) => ({
410449
value: key,
411450
formatter: (cellValue: any) => {
412-
if (key === 'fixStatus') {
451+
if (key === 'fixStatus' || key === 'Fixable') {
413452
return chalk.green(typeof cellValue === 'object' ? JSON.stringify(cellValue) : cellValue);
414453
} else if (
415454
key === 'content_types' ||
416455
key === 'branches' ||
417456
key === 'missingCTSelectFieldValues' ||
418457
key === 'missingFieldUid' ||
419-
key === 'action'
458+
key === 'action' ||
459+
key === 'Non-Fixable'
420460
) {
421461
return chalk.red(typeof cellValue === 'object' ? JSON.stringify(cellValue) : cellValue);
422462
} else {
@@ -441,7 +481,11 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
441481
* @returns The function `prepareReport` returns a Promise that resolves to `void`.
442482
*/
443483
prepareReport(
444-
moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries | 'field-rules',
484+
moduleName:
485+
| keyof typeof config.moduleConfig
486+
| keyof typeof config.ReportTitleForEntries
487+
| 'field-rules'
488+
| 'Summary',
445489
listOfMissingRefs: Record<string, any>,
446490
): Promise<void> {
447491
if (isEmpty(listOfMissingRefs)) return Promise.resolve(void 0);
@@ -471,7 +515,11 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
471515
* @returns The function `prepareCSV` returns a Promise that resolves to `void`.
472516
*/
473517
prepareCSV(
474-
moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries | 'field-rules',
518+
moduleName:
519+
| keyof typeof config.moduleConfig
520+
| keyof typeof config.ReportTitleForEntries
521+
| 'field-rules'
522+
| 'Summary',
475523
listOfMissingRefs: Record<string, any>,
476524
): Promise<void> {
477525
if (Object.keys(config.moduleConfig).includes(moduleName) || config.feild_level_modules.includes(moduleName)) {
@@ -525,4 +573,59 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
525573
});
526574
}
527575
}
576+
577+
async getAffectedData(
578+
Module: string,
579+
dataExported: any,
580+
listOfMissingRefs: Record<string, any>,
581+
isFixable: boolean = true,
582+
) {
583+
if (Module === 'entries') {
584+
const key = Object.keys(listOfMissingRefs);
585+
const uidSet = new Set();
586+
const nonFixable = new Set();
587+
key.forEach((k) => {
588+
if (k != 'missingTitleFields') Object.keys(listOfMissingRefs[k]).forEach((kv2) => uidSet.add(kv2));
589+
else
590+
Object.keys(listOfMissingRefs[k]).forEach((kv) => {
591+
if (uidSet.has(kv)) {
592+
uidSet.delete(kv);
593+
nonFixable.add(kv);
594+
}
595+
});
596+
});
597+
dataExported = {
598+
Module,
599+
...dataExported,
600+
Passed: dataExported['Total'] - size(uidSet),
601+
Fixable: size(uidSet) - size(nonFixable),
602+
'Non-Fixable': size(nonFixable),
603+
};
604+
} else {
605+
if (Object.keys(listOfMissingRefs).length) {
606+
const uidSet = new Set(Object.keys(listOfMissingRefs));
607+
dataExported = {
608+
Module,
609+
...dataExported,
610+
Passed: dataExported['Total'] - size(uidSet),
611+
};
612+
if (isFixable) {
613+
dataExported['Fixable'] = size(uidSet);
614+
dataExported['Non-Fixable'] = 0;
615+
} else {
616+
dataExported['Fixable'] = 0;
617+
dataExported['Non-Fixable'] = size(uidSet);
618+
}
619+
} else {
620+
dataExported = {
621+
Module,
622+
...dataExported,
623+
Passed: dataExported['Total'],
624+
};
625+
(dataExported['Fixable'] = 0), (dataExported['Non-Fixable'] = 0);
626+
}
627+
}
628+
629+
this.summaryDataToPrint.push(dataExported);
630+
}
528631
}

packages/contentstack-audit/src/base-command.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ export abstract class BaseCommand<T extends typeof Command> extends Command {
3939
helpGroup: 'COMMON',
4040
description: commonMsg.DATA_DIR,
4141
}),
42+
'show-console-output': Flags.boolean({
43+
char: 's',
44+
helpGroup: 'COMMON',
45+
description: commonMsg.SHOW_CONSOLE_OUTPUT,
46+
}),
4247
};
4348

4449
/**

packages/contentstack-audit/src/config/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ const config = {
106106
'selectedValue',
107107
'ct_uid',
108108
'action',
109+
"Module",
110+
"Total",
111+
"Fixable",
112+
"Non-Fixable",
113+
"Passed",
109114
],
110115
ReportTitleForEntries: {
111116
Entries_Select_feild: 'Entries_Select_feild',
@@ -121,7 +126,8 @@ const config = {
121126
'Entries_Select_feild',
122127
'Entry_Missing_Locale_and_Env_in_Publish_Details',
123128
'field-rules',
124-
'Entry_Multiple_Fields'
129+
'Entry_Multiple_Fields',
130+
'Summary'
125131
],
126132
fixSelectField: false,
127133
};

packages/contentstack-audit/src/messages/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const commonMsg = {
2020
EXTENSION_FIX_CONFIRMATION: `Would you like to overwrite existing file?`,
2121
WF_BRANCH_REMOVAL: `Removing the branch '{branch} from workflow with UID {uid} and name {name} will be removed.'`,
2222
CR_BRANCH_REMOVAL: `Removing the branch '{branch} from custom role with UID {uid} and name {name} will be removed.'`,
23+
SHOW_CONSOLE_OUTPUT: `Display the audit and audit fix result for individual modules`,
2324
};
2425

2526
const auditMsg = {

packages/contentstack-audit/src/modules/field_rules.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ export default class FieldRule {
241241
fixStatus: 'Fixed',
242242
});
243243
} else {
244-
this.missingRefs[this.currentUid].push({ action: actions, ctUid: this.currentUid });
244+
this.missingRefs[this.currentUid].push({ ctUid: this.currentUid, action: actions });
245245
}
246246
}
247247
/**

packages/contentstack-audit/src/modules/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ import Extensions from './extensions';
66
import CustomRoles from './custom-roles';
77
import Assets from './assets';
88
import FieldRule from './field_rules';
9-
export { Entries, GlobalField, ContentType, Workflows, Extensions, Assets, CustomRoles, FieldRule };
9+
import ReadModulesAndGetData from './modulesData';
10+
11+
export { Entries, GlobalField, ContentType, Workflows, Extensions, Assets, CustomRoles, FieldRule, ReadModulesAndGetData };

0 commit comments

Comments
 (0)