Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ fileignoreconfig:
checksum: bbe1130f5f5ebf2fa452daef743fe4d40ae9f8fc05c7f8c59c82a3d3d1ed69e8
- filename: packages/contentstack-audit/src/modules/extensions.ts
checksum: 32af019f0df8288448d11559fe9f7ef61d3e43c3791d45eeec25fd0937c6baad
- filename: packages/contentstack-audit/src/modules/modulesData.ts
checksum: bac8f1971ac2e39bc04d9297b81951fe34ed265dfc985137135f9bbe775cd63c
- filename: packages/contentstack-audit/src/modules/assets.ts
checksum: 5a007804c75976dd192ed2284b7b7edbc5b5fc269fc0e883908b52e4d4f206a8
- filename: packages/contentstack-audit/src/modules/workflows.ts
Expand All @@ -118,7 +116,7 @@ fileignoreconfig:
- filename: packages/contentstack-import/test/unit/import/modules/mock-data/entries/environments.json
checksum: 17f94f500dcb265575b60f8d2cb7464372a234e452527b3bdec6052c606cee28
- filename: packages/contentstack-import/test/unit/import/modules/entries.test.ts
checksum: 7b984d292a534f9d075d801de2aeff802b2832bc5e2efadf8613a7059f4317fc
checksum: d8e4f6ad185b36b6f84b38dce169144e7d5a195668aac11f914eed5e1e4b5478
- filename: packages/contentstack-import/test/unit/import/modules/labels.test.ts
checksum: 46fe0d1602ab386f7eaee9839bc376b98ab8d4262f823784eda9cfa2bf893758
- filename: packages/contentstack-export/test/unit/export/modules/assets.test.ts
Expand Down Expand Up @@ -273,4 +271,8 @@ fileignoreconfig:
checksum: 9d7df9d79cec75f238a0072bf79c4934b4724bf1466451ea6f923adfd5c0b75b
- filename: packages/contentstack-utilities/test/unit/logger.test.ts
checksum: a1939dea16166b1893a248179524a76f2ed20b04b99c83bd1a5a13fcf6f0dadc
- filename: packages/contentstack-audit/src/modules/modulesData.ts
checksum: 1e6c1fba1172512401038d5454c8d218201ec62262449c5c878609592e0124c4
- filename: packages/contentstack-audit/src/modules/composable-studio.ts
checksum: e2f67d6b383415fe503ca22514fea38f53cc99647a9a73551772ab1082572cfa
version: '1.0'
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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.16.2",
"version": "1.17.0",
"description": "Contentstack audit plugin",
"author": "Contentstack CLI",
"homepage": "https://github.com/contentstack/cli",
Expand Down
99 changes: 79 additions & 20 deletions packages/contentstack-audit/src/audit-base-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ import { v4 as uuid } from 'uuid';
import isEmpty from 'lodash/isEmpty';
import { join, resolve } from 'path';
import cloneDeep from 'lodash/cloneDeep';
import { cliux, sanitizePath, TableFlags, TableHeader, log, configHandler, createLogContext } from '@contentstack/cli-utilities';
import {
cliux,
sanitizePath,
TableFlags,
TableHeader,
log,
configHandler,
createLogContext,
} from '@contentstack/cli-utilities';
import { createWriteStream, existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from 'fs';
import config from './config';
import { print } from './util/log';
Expand All @@ -21,6 +29,7 @@ import {
FieldRule,
ModuleDataReader,
CustomRoles,
ComposableStudio,
} from './modules';

import {
Expand Down Expand Up @@ -50,7 +59,6 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
};
}


/**
* The `start` function performs an audit on content types, global fields, entries, and workflows and displays
* any missing references.
Expand All @@ -65,7 +73,6 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
log.debug(`Starting audit command: ${command}`, this.auditContext);
log.info(`Starting audit command: ${command}`, this.auditContext);


await this.promptQueue();
await this.createBackUp();
this.sharedConfig.reportPath = resolve(this.flags['report-path'] || process.cwd(), 'audit-report');
Expand All @@ -86,6 +93,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
missingEnvLocalesInEntries,
missingFieldRules,
missingMultipleFields,
missingRefsInComposableStudio,
} = await this.scanAndFix();

if (this.flags['show-console-output']) {
Expand Down Expand Up @@ -116,6 +124,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
this.showOutputOnScreenWorkflowsAndExtension([
{ module: 'Entries Changed Multiple Fields', missingRefs: missingMultipleFields },
]);
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Studio', missingRefs: missingRefsInComposableStudio }]);
}
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Summary', missingRefs: this.summaryDataToPrint }]);

Expand All @@ -131,12 +140,16 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
!isEmpty(missingEnvLocalesInAssets) ||
!isEmpty(missingEnvLocalesInEntries) ||
!isEmpty(missingFieldRules) ||
!isEmpty(missingMultipleFields)
!isEmpty(missingMultipleFields) ||
!isEmpty(missingRefsInComposableStudio)
) {
if (this.currentCommand === 'cm:stacks:audit') {
log.warn(this.$t(auditMsg.FINAL_REPORT_PATH, { path: this.sharedConfig.reportPath }), this.auditContext);
} else {
log.warn(this.$t(this.messages.FIXED_CONTENT_PATH_MAG, { path: this.sharedConfig.basePath }), this.auditContext);
log.warn(
this.$t(this.messages.FIXED_CONTENT_PATH_MAG, { path: this.sharedConfig.basePath }),
this.auditContext,
);
}
} else {
log.info(this.messages.NO_MISSING_REF_FOUND, this.auditContext);
Expand All @@ -162,7 +175,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
!isEmpty(missingRefInCustomRoles) ||
!isEmpty(missingEnvLocalesInAssets) ||
!isEmpty(missingEnvLocalesInEntries) ||
!isEmpty(missingFieldRules)
!isEmpty(missingFieldRules) ||
!isEmpty(missingRefsInComposableStudio)
);
}

Expand All @@ -175,8 +189,11 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
async scanAndFix() {
log.debug('Starting scan and fix process', this.auditContext);
let { ctSchema, gfSchema } = this.getCtAndGfSchema();
log.info(`Retrieved ${ctSchema?.length || 0} content types and ${gfSchema?.length || 0} global fields`, this.auditContext);

log.info(
`Retrieved ${ctSchema?.length || 0} content types and ${gfSchema?.length || 0} global fields`,
this.auditContext,
);

let missingCtRefs,
missingGfRefs,
missingEntryRefs,
Expand All @@ -197,7 +214,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
missingEnvLocalesInAssets,
missingEnvLocalesInEntries,
missingFieldRules,
missingMultipleFields;
missingMultipleFields,
missingRefsInComposableStudio;

const constructorParam: ModuleConstructorParam & CtConstructorParam = {
ctSchema,
Expand Down Expand Up @@ -233,21 +251,30 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
missingEnvLocalesInAssets = await new Assets(cloneDeep(constructorParam)).run();
await this.prepareReport(module, missingEnvLocalesInAssets);
this.getAffectedData('assets', dataModuleWise['assets'], missingEnvLocalesInAssets);
log.success(`Assets audit completed. Found ${Object.keys(missingEnvLocalesInAssets || {}).length} issues`, this.auditContext);
log.success(
`Assets audit completed. Found ${Object.keys(missingEnvLocalesInAssets || {}).length} issues`,
this.auditContext,
);
break;
case 'content-types':
log.info('Executing content-types audit', this.auditContext);
missingCtRefs = await new ContentType(cloneDeep(constructorParam)).run();
await this.prepareReport(module, missingCtRefs);
this.getAffectedData('content-types', dataModuleWise['content-types'], missingCtRefs);
log.success(`Content-types audit completed. Found ${Object.keys(missingCtRefs || {}).length} issues`, this.auditContext);
log.success(
`Content-types audit completed. Found ${Object.keys(missingCtRefs || {}).length} issues`,
this.auditContext,
);
break;
case 'global-fields':
log.info('Executing global-fields audit', this.auditContext);
missingGfRefs = await new GlobalField(cloneDeep(constructorParam)).run();
await this.prepareReport(module, missingGfRefs);
this.getAffectedData('global-fields', dataModuleWise['global-fields'], missingGfRefs);
log.success(`Global-fields audit completed. Found ${Object.keys(missingGfRefs || {}).length} issues`, this.auditContext);
log.success(
`Global-fields audit completed. Found ${Object.keys(missingGfRefs || {}).length} issues`,
this.auditContext,
);
break;
case 'entries':
log.info('Executing entries audit', this.auditContext);
Expand All @@ -270,7 +297,10 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma

await this.prepareReport('Entry_Multiple_Fields', missingMultipleFields);
this.getAffectedData('entries', dataModuleWise['entries'], missingEntry);
log.success(`Entries audit completed. Found ${Object.keys(missingEntryRefs || {}).length} reference issues`, this.auditContext);
log.success(
`Entries audit completed. Found ${Object.keys(missingEntryRefs || {}).length} reference issues`,
this.auditContext,
);

break;
case 'workflows':
Expand All @@ -283,34 +313,62 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
}).run();
await this.prepareReport(module, missingCtRefsInWorkflow);
this.getAffectedData('workflows', dataModuleWise['workflows'], missingCtRefsInWorkflow);
log.success(`Workflows audit completed. Found ${Object.keys(missingCtRefsInWorkflow || {}).length} issues`, this.auditContext);
log.success(
`Workflows audit completed. Found ${Object.keys(missingCtRefsInWorkflow || {}).length} issues`,
this.auditContext,
);

break;
case 'extensions':
log.info('Executing extensions audit', this.auditContext);
missingCtRefsInExtensions = await new Extensions(cloneDeep(constructorParam)).run();
await this.prepareReport(module, missingCtRefsInExtensions);
this.getAffectedData('extensions', dataModuleWise['extensions'], missingCtRefsInExtensions);
log.success(`Extensions audit completed. Found ${Object.keys(missingCtRefsInExtensions || {}).length} issues`, this.auditContext);
log.success(
`Extensions audit completed. Found ${Object.keys(missingCtRefsInExtensions || {}).length} issues`,
this.auditContext,
);
break;
case 'custom-roles':
log.info('Executing custom-roles audit', this.auditContext);
missingRefInCustomRoles = await new CustomRoles(cloneDeep(constructorParam)).run();
await this.prepareReport(module, missingRefInCustomRoles);
this.getAffectedData('custom-roles', dataModuleWise['custom-roles'], missingRefInCustomRoles);
log.success(`Custom-roles audit completed. Found ${Object.keys(missingRefInCustomRoles || {}).length} issues`, this.auditContext);
log.success(
`Custom-roles audit completed. Found ${Object.keys(missingRefInCustomRoles || {}).length} issues`,
this.auditContext,
);

break;
case 'field-rules':
log.info('Executing field-rules audit', this.auditContext);
// NOTE: We are using the fixed content-type for validation of field rules
const data = this.getCtAndGfSchema();
const data = this.getCtAndGfSchema();
constructorParam.ctSchema = data.ctSchema;
constructorParam.gfSchema = data.gfSchema;
missingFieldRules = await new FieldRule(cloneDeep(constructorParam)).run();
await this.prepareReport(module, missingFieldRules);
this.getAffectedData('field-rules', dataModuleWise['content-types'], missingFieldRules);
log.success(`Field-rules audit completed. Found ${Object.keys(missingFieldRules || {}).length} issues`, this.auditContext);
log.success(
`Field-rules audit completed. Found ${Object.keys(missingFieldRules || {}).length} issues`,
this.auditContext,
);
break;
case 'composable-studio':
log.info('Executing composable-studio audit', this.auditContext);
missingRefsInComposableStudio = await new ComposableStudio(cloneDeep(constructorParam)).run();
await this.prepareReport(module, missingRefsInComposableStudio);
this.getAffectedData(
'composable-studio',
dataModuleWise['composable-studio'] || { Total: Object.keys(missingRefsInComposableStudio || {}).length },
missingRefsInComposableStudio,
);
log.success(
`Composable-studio audit completed. Found ${
Object.keys(missingRefsInComposableStudio || {}).length
} issues`,
this.auditContext,
);
break;
}

Expand Down Expand Up @@ -345,6 +403,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
missingEnvLocalesInEntries,
missingFieldRules,
missingMultipleFields,
missingRefsInComposableStudio,
};
}

Expand Down Expand Up @@ -488,7 +547,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
}

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

const tableValues = Object.values(missingRefs).flat();
missingRefs = Object.values(missingRefs).flat();
const tableKeys = Object.keys(missingRefs[0]);
Expand Down Expand Up @@ -542,7 +601,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
log.debug(`Preparing report for module: ${moduleName}`, this.auditContext);
log.debug(`Report path: ${this.sharedConfig.reportPath}`, this.auditContext);
log.info(`Missing references count: ${Object.keys(listOfMissingRefs).length}`, this.auditContext);

if (isEmpty(listOfMissingRefs)) {
log.debug(`No missing references found for ${moduleName}, skipping report generation`, this.auditContext);
return Promise.resolve(void 0);
Expand Down
27 changes: 17 additions & 10 deletions packages/contentstack-audit/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ const config = {
'custom-roles',
'assets',
'field-rules',
'composable-studio',
],
'fix-fields': ['reference', 'global_field', 'json:rte', 'json:extension', 'blocks', 'group', 'content_types'],
'schema-fields-data-type': ['blocks','group','global_field'],
'schema-fields-data-type': ['blocks', 'group', 'global_field'],
moduleConfig: {
'content-types': {
name: 'content type',
Expand Down Expand Up @@ -60,6 +61,11 @@ const config = {
dirName: 'environments',
fileName: 'environments.json',
},
'composable-studio': {
name: 'composable-studio',
dirName: 'composable_studio',
fileName: 'composable_studio.json',
},
},
entries: {
systemKeys: [
Expand Down Expand Up @@ -107,21 +113,22 @@ const config = {
'selectedValue',
'ct_uid',
'action',
"Module",
"Total",
"Fixable",
"Non-Fixable",
"Fixed",
"Not-Fixed",
"Passed",
'Module',
'Total',
'Fixable',
'Non-Fixable',
'Fixed',
'Not-Fixed',
'Passed',
'issues',
],
ReportTitleForEntries: {
Entries_Select_field: 'Entries_Select_field',
Entries_Mandatory_field: 'Entries_Mandatory_field',
Entries_Title_field: 'Entries_Title_field',
Entry_Missing_Locale_and_Env: 'Entry_Missing_Locale_and_Env',
Entry_Missing_Locale_and_Env_in_Publish_Details: 'Entry_Missing_Locale_and_Env_in_Publish_Details',
Entry_Multiple_Fields:"Entry_Multiple_Fields"
Entry_Multiple_Fields: 'Entry_Multiple_Fields',
},
feild_level_modules: [
'Entries_Title_field',
Expand All @@ -130,7 +137,7 @@ const config = {
'Entry_Missing_Locale_and_Env_in_Publish_Details',
'field-rules',
'Entry_Multiple_Fields',
'Summary'
'Summary',
],
fixSelectField: false,
};
Expand Down
3 changes: 2 additions & 1 deletion packages/contentstack-audit/src/messages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const auditMsg = {
AUDIT_CMD_DESCRIPTION: 'Perform audits and find possible errors in the exported Contentstack data',
SCAN_WF_SUCCESS_MSG: 'Successfully completed the scanning of workflow with UID {uid} and name {name}.',
SCAN_CR_SUCCESS_MSG: 'Successfully completed the scanning of custom role with UID {uid} and name {name}.',
SCAN_CS_SUCCESS_MSG: 'Successfully completed the scanning of studio project with UID {uid} and name {name}.',
SCAN_ASSET_SUCCESS_MSG: `Successfully completed the scanning of Asset with UID '{uid}'.`,
SCAN_ASSET_WARN_MSG: `The locale '{locale}' or environment '{environment}' are not present for asset with uid '{uid}'`,
ENTRY_PUBLISH_DETAILS: `Removing the publish detials for entry '{uid}' of ct '{ctuid}' in locale '{locale}' as locale '{publocale}' or environment '{environment}' does not exist`,
Expand All @@ -47,7 +48,7 @@ const auditMsg = {
FIELD_RULE_CONDITION_ABSENT: `The operand field '{condition_field}' is not present in the schema of the content-type {ctUid}`,
FIELD_RULE_TARGET_ABSENT: `The target field '{target_field}' is not present in the schema of the content-type {ctUid}`,
FIELD_RULE_CONDITION_SCAN_MESSAGE: `Completed Scanning of Field Rule '{num}' condition of Content-type '{ctUid}'`,
FIELD_RULE_TARGET_SCAN_MESSAGE: `Completed Scanning of Field Rule '{num}' target of Content-type '{ctUid}'`
FIELD_RULE_TARGET_SCAN_MESSAGE: `Completed Scanning of Field Rule '{num}' target of Content-type '{ctUid}'`,
};

const auditFixMsg = {
Expand Down
Loading
Loading