Skip to content

Commit

Permalink
Merge pull request #1389 from contentstack/feat/CS-44502
Browse files Browse the repository at this point in the history
feat: Added Audit and audit fix for Select fields in entries and minor version bump
  • Loading branch information
cs-raj authored Apr 29, 2024
2 parents 73e36f5 + fcd54b8 commit 6a7a823
Show file tree
Hide file tree
Showing 11 changed files with 613 additions and 501 deletions.
801 changes: 334 additions & 467 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/contentstack-audit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentstack/cli-audit",
"version": "1.5.4",
"version": "1.6.0",
"description": "Contentstack audit plugin",
"author": "Contentstack CLI",
"homepage": "https://github.com/contentstack/cli",
Expand Down
61 changes: 48 additions & 13 deletions packages/contentstack-audit/src/audit-base-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
await this.createBackUp();
this.sharedConfig.reportPath = resolve(this.flags['report-path'] || process.cwd(), 'audit-report');

const { missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow } =
await this.scanAndFix();
const {
missingCtRefs,
missingGfRefs,
missingEntryRefs,
missingCtRefsInExtensions,
missingCtRefsInWorkflow,
missingSelectFeild,
} = await this.scanAndFix();

this.showOutputOnScreen([
{ module: 'Content types', missingRefs: missingCtRefs },
Expand All @@ -58,12 +64,15 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
]);
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Extensions', missingRefs: missingCtRefsInExtensions }]);
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Workflows', missingRefs: missingCtRefsInWorkflow }]);
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Entries Select Field', missingRefs: missingSelectFeild }]);

if (
!isEmpty(missingCtRefs) ||
!isEmpty(missingGfRefs) ||
!isEmpty(missingEntryRefs) ||
!isEmpty(missingCtRefsInWorkflow) ||
!isEmpty(missingCtRefsInExtensions)
!isEmpty(missingCtRefsInExtensions) ||
!isEmpty(missingSelectFeild)
) {
if (this.currentCommand === 'cm:stacks:audit') {
this.log(this.$t(auditMsg.FINAL_REPORT_PATH, { path: this.sharedConfig.reportPath }), 'warn');
Expand All @@ -89,7 +98,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
!isEmpty(missingGfRefs) ||
!isEmpty(missingEntryRefs) ||
!isEmpty(missingCtRefsInWorkflow) ||
!isEmpty(missingCtRefsInExtensions)
!isEmpty(missingCtRefsInExtensions) ||
!isEmpty(missingSelectFeild)
);
}

Expand All @@ -101,7 +111,13 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
*/
async scanAndFix() {
let { ctSchema, gfSchema } = this.getCtAndGfSchema();
let missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow;
let missingCtRefs,
missingGfRefs,
missingEntryRefs,
missingCtRefsInExtensions,
missingCtRefsInWorkflow,
missingSelectFeild,
missingEntry;
for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) {
print([
{
Expand Down Expand Up @@ -129,8 +145,12 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
await this.prepareReport(module, missingGfRefs);
break;
case 'entries':
missingEntryRefs = await new Entries(cloneDeep(constructorParam)).run();
missingEntry = await new Entries(cloneDeep(constructorParam)).run();
missingEntryRefs = missingEntry.missingEntryRefs ?? {};
missingSelectFeild = missingEntry.missingSelectFeild ?? {};
await this.prepareReport(module, missingEntryRefs);

await this.prepareReport(`entries_Select_feild`, missingSelectFeild);
break;
case 'workflows':
missingCtRefsInWorkflow = await new Workflows({
Expand Down Expand Up @@ -162,7 +182,14 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
]);
}

return { missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow };
return {
missingCtRefs,
missingGfRefs,
missingEntryRefs,
missingCtRefsInExtensions,
missingCtRefsInWorkflow,
missingSelectFeild,
};
}

/**
Expand Down Expand Up @@ -297,26 +324,28 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
}
this.log(''); // Adding a new line

for (const { module, missingRefs } of allMissingRefs) {
for (let { module, missingRefs } of allMissingRefs) {
if (isEmpty(missingRefs)) {
continue;
}

print([{ bold: true, color: 'cyan', message: ` ${module}` }]);

const tableValues = Object.values(missingRefs).flat();

missingRefs = Object.values(missingRefs).flat();
const tableKeys = Object.keys(missingRefs[0]);
const arrayOfObjects = tableKeys.map((key) => {
if (['title', 'name', 'uid', 'content_types', 'branches', 'fixStatus'].includes(key)) {
if (
config.OutputTableKeys.includes(key)
) {
return {
[key]: {
minWidth: 7,
header: key,
get: (row: Record<string, unknown>) => {
if (key === 'fixStatus') {
return chalk.green(typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]);
} else if (key === 'content_types' || key === 'branches') {
} else if (key === 'content_types' || key === 'branches' || key === 'missingCTSelectFieldValues') {
return chalk.red(typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]);
} else {
return chalk.white(typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]);
Expand Down Expand Up @@ -344,7 +373,10 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
* reference name and the value represents additional information about the missing reference.
* @returns The function `prepareReport` returns a Promise that resolves to `void`.
*/
prepareReport(moduleName: keyof typeof config.moduleConfig, listOfMissingRefs: Record<string, any>): Promise<void> {
prepareReport(
moduleName: keyof typeof config.moduleConfig | 'entries_Select_feild',
listOfMissingRefs: Record<string, any>,
): Promise<void> {
if (isEmpty(listOfMissingRefs)) return Promise.resolve(void 0);

if (!existsSync(this.sharedConfig.reportPath)) {
Expand All @@ -368,7 +400,10 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
* corresponding value is an array of objects that contain details about the missing reference.
* @returns The function `prepareCSV` returns a Promise that resolves to `void`.
*/
prepareCSV(moduleName: keyof typeof config.moduleConfig, listOfMissingRefs: Record<string, any>): Promise<void> {
prepareCSV(
moduleName: keyof typeof config.moduleConfig | 'entries_Select_feild',
listOfMissingRefs: Record<string, any>,
): Promise<void> {
const csvPath = join(this.sharedConfig.reportPath, `${moduleName}.csv`);

return new Promise<void>((resolve, reject) => {
Expand Down
16 changes: 16 additions & 0 deletions packages/contentstack-audit/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,22 @@ const config = {
'publish_details',
],
},
//These keys will be used output the modules with issues and fixes on console
OutputTableKeys : [
'title',
'name',
'uid',
'content_types',
'branches',
'fixStatus',
'tree',
'display_name',
'display_type',
'missingRefs',
'treeStr',
'missingCTSelectFieldValues',
'min_instance',
]
};

export default config;
4 changes: 2 additions & 2 deletions packages/contentstack-audit/src/modules/content-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ export default class ContentType {
...this.validateReferenceField(
[...tree, { uid: field.uid, name: child.display_name }],
child as ReferenceFieldDataType,
),
);
),
);
break;
case 'global_field':
await this.validateGlobalField(
Expand Down
Loading

0 comments on commit 6a7a823

Please sign in to comment.