Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
22 changes: 7 additions & 15 deletions .talismanrc
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
fileignoreconfig:

- filename: pnpm-lock.yaml
checksum: c3bcd614567a430c43ef8c3aa5a4ea2e006486137ba8397d58f01de89b858a1e
- filename: packages/contentstack-seed/tests/importer.test.ts
checksum: cf452b6bc7d3cfcef493ee64e1f5a4e97ac841292ff8ba3515375fc4e8ed049c
- filename: packages/contentstack-variants/test/unit/import/variant-entries.test.ts
checksum: 6aca150cf9656d27acb1811f478d298668ec28f610b2d4820a6d5115612d52c0
- filename: packages/contentstack-export/src/config/index.ts
checksum: 6fa4bba2174bbf33f5611098f49a02bf2fc789f59634e99be58de7e370f5fcd3
- filename: packages/contentstack-branches/test/unit/helpers/stub-auth.ts
checksum: 8cafd5994d3ec13ba9af74c80b330bfd14721ea4e0359b456598964a6c2913ce
- filename: packages/contentstack-seed/tests/contentstack.test.ts
checksum: 04196568bf29f4693e968079867e87d96219b022bfee0f4697dce1b9bc161ac3
- filename: packages/contentstack-export/src/utils/export-config-handler.ts
checksum: 362c1042a70958b52e73a7a3096152cf0259c55095c8b2c6f308b8f5fb90614e
- filename: packages/contentstack-import/src/utils/import-config-handler.ts
checksum: f310186b5ea1fc756bd200dbe01967bc07e5490dc5ed17018f0ca4b35f0fd86f
checksum: 31e333d6769adbaae042c92ea0930fab168a0e06fc1bda406d49fd1042a7a9c7
- filename: packages/contentstack-audit/src/audit-base-command.ts
checksum: 14275f241e4a194cfd1fb33d277df194011eba4458ccaab7e0d0bd3a1c9ccfe7
- filename: packages/contentstack-audit/src/modules/entries.ts
checksum: b0fa5f7b390ef2d64bd4834a5b848780b902373e2c644833842b42c6b767d54e
- filename: packages/contentstack-audit/test/unit/modules/entries.test.ts
checksum: ff448c79d436d5e8b141efcc76f19892bfe96039ea9a60fae4e995b5ccbc2960
version: '1.0'
2 changes: 1 addition & 1 deletion packages/contentstack-apps-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentstack/apps-cli",
"version": "1.7.2",
"version": "1.7.3",
"description": "App ClI",
"author": "Contentstack CLI",
"homepage": "https://github.com/contentstack/cli-plugins/tree/main/packages/contentstack-apps-cli",
Expand Down
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.19.5",
"version": "1.20.0",
"description": "Contentstack audit plugin",
"author": "Contentstack CLI",
"homepage": "https://github.com/contentstack/cli",
Expand Down
41 changes: 34 additions & 7 deletions packages/contentstack-audit/src/audit-base-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
missingFieldRules,
missingMultipleFields,
missingRefsInComposableStudio,
missingScanStatusAssets,
missingAssetRefsInEntries,
} = await this.scanAndFix();

if (this.flags['show-console-output']) {
Expand Down Expand Up @@ -125,6 +127,12 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
{ module: 'Entries Changed Multiple Fields', missingRefs: missingMultipleFields },
]);
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Studio', missingRefs: missingRefsInComposableStudio }]);
this.showOutputOnScreenWorkflowsAndExtension([
{ module: 'Assets Scan Status', missingRefs: missingScanStatusAssets },
]);
this.showOutputOnScreenWorkflowsAndExtension([
{ module: 'Entries Asset Field', missingRefs: missingAssetRefsInEntries },
]);
}
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Summary', missingRefs: this.summaryDataToPrint }]);

Expand All @@ -141,7 +149,9 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
!isEmpty(missingEnvLocalesInEntries) ||
!isEmpty(missingFieldRules) ||
!isEmpty(missingMultipleFields) ||
!isEmpty(missingRefsInComposableStudio)
!isEmpty(missingRefsInComposableStudio) ||
!isEmpty(missingScanStatusAssets) ||
!isEmpty(missingAssetRefsInEntries)
) {
if (this.currentCommand === 'cm:stacks:audit') {
log.warn(this.$t(auditMsg.FINAL_REPORT_PATH, { path: this.sharedConfig.reportPath }), this.auditContext);
Expand Down Expand Up @@ -176,7 +186,9 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
!isEmpty(missingEnvLocalesInAssets) ||
!isEmpty(missingEnvLocalesInEntries) ||
!isEmpty(missingFieldRules) ||
!isEmpty(missingRefsInComposableStudio)
!isEmpty(missingRefsInComposableStudio) ||
!isEmpty(missingScanStatusAssets) ||
!isEmpty(missingAssetRefsInEntries)
);
}

Expand Down Expand Up @@ -207,6 +219,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
missingTitleFields?: Record<string, any>;
missingEnvLocale?: Record<string, any>;
missingMultipleFields?: Record<string, any>;
missingAssetRefs?: Record<string, any>;
} = {},
missingMandatoryFields,
missingTitleFields,
Expand All @@ -215,6 +228,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
missingEnvLocalesInEntries,
missingFieldRules,
missingMultipleFields,
missingAssetRefsInEntries,
missingScanStatusAssets,
missingRefsInComposableStudio;

const constructorParam: ModuleConstructorParam & CtConstructorParam = {
Expand Down Expand Up @@ -246,16 +261,21 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
constructorParam['moduleName'] = module;

switch (module) {
case 'assets':
case 'assets': {
log.info('Executing assets audit', this.auditContext);
missingEnvLocalesInAssets = await new Assets(cloneDeep(constructorParam)).run();
const assetsModule = new Assets(cloneDeep(constructorParam));
missingEnvLocalesInAssets = await assetsModule.run();
missingScanStatusAssets = assetsModule.missingScanStatusAssets ?? {};
await this.prepareReport(module, missingEnvLocalesInAssets);
await this.prepareReport('asset-scan-status', missingScanStatusAssets);
this.getAffectedData('assets', dataModuleWise['assets'], missingEnvLocalesInAssets);
this.getAffectedData('asset-scan-status', dataModuleWise['assets'], missingScanStatusAssets);
log.success(
`Assets audit completed. Found ${Object.keys(missingEnvLocalesInAssets || {}).length} issues`,
`Assets audit completed. Found ${Object.keys(missingEnvLocalesInAssets || {}).length} issues, ${Object.keys(missingScanStatusAssets).length} non-clean scan status assets`,
this.auditContext,
);
break;
}
case 'content-types':
log.info('Executing content-types audit', this.auditContext);
missingCtRefs = await new ContentType(cloneDeep(constructorParam)).run();
Expand Down Expand Up @@ -285,6 +305,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
missingTitleFields = missingEntry.missingTitleFields ?? {};
missingEnvLocalesInEntries = missingEntry.missingEnvLocale ?? {};
missingMultipleFields = missingEntry.missingMultipleFields ?? {};
missingAssetRefsInEntries = missingEntry.missingAssetRefs ?? {};
await this.prepareReport(module, missingEntryRefs);

await this.prepareReport(`Entries_Select_field`, missingSelectFeild);
Expand All @@ -296,6 +317,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
await this.prepareReport('Entry_Missing_Locale_and_Env_in_Publish_Details', missingEnvLocalesInEntries);

await this.prepareReport('Entry_Multiple_Fields', missingMultipleFields);

await this.prepareReport('Entries_Asset_field', missingAssetRefsInEntries);
this.getAffectedData('entries', dataModuleWise['entries'], missingEntry);
log.success(
`Entries audit completed. Found ${Object.keys(missingEntryRefs || {}).length} reference issues`,
Expand Down Expand Up @@ -421,6 +444,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
missingFieldRules,
missingMultipleFields,
missingRefsInComposableStudio,
missingScanStatusAssets,
missingAssetRefsInEntries,
};
}

Expand Down Expand Up @@ -612,7 +637,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
| keyof typeof config.moduleConfig
| keyof typeof config.ReportTitleForEntries
| 'field-rules'
| 'Summary',
| 'Summary'
| 'asset-scan-status',
listOfMissingRefs: Record<string, any>,
): Promise<void> {
log.debug(`Preparing report for module: ${moduleName}`, this.auditContext);
Expand Down Expand Up @@ -656,7 +682,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
| keyof typeof config.moduleConfig
| keyof typeof config.ReportTitleForEntries
| 'field-rules'
| 'Summary',
| 'Summary'
| 'asset-scan-status',
listOfMissingRefs: Record<string, any>,
): Promise<void> {
if (Object.keys(config.moduleConfig).includes(moduleName) || config.feild_level_modules.includes(moduleName)) {
Expand Down
5 changes: 5 additions & 0 deletions packages/contentstack-audit/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ const config = {
'publish_locale',
'publish_environment',
'asset_uid',
'scan_status',
'mandatory',
'selectedValue',
'ct_uid',
'action',
Expand All @@ -129,6 +131,7 @@ const config = {
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',
Entries_Asset_field: 'Entries_Asset_field',
},
feild_level_modules: [
'Entries_Title_field',
Expand All @@ -137,6 +140,8 @@ const config = {
'Entry_Missing_Locale_and_Env_in_Publish_Details',
'field-rules',
'Entry_Multiple_Fields',
'Entries_Asset_field',
'asset-scan-status',
'Summary',
],
fixSelectField: false,
Expand Down
4 changes: 4 additions & 0 deletions packages/contentstack-audit/src/messages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ const auditMsg = {
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}'`,
SCAN_ASSET_QUARANTINE_MSG: `Asset with UID '{uid}' has a non-clean scan status ('{status}') and will be excluded from import.`,
ENTRY_ASSET_REF_WARN_MSG: `Entry '{uid}' field '{field}' references asset '{asset_uid}' with scan status '{status}'; it will be removed on fix.`,
};

const auditFixMsg = {
Expand All @@ -63,6 +65,8 @@ const auditFixMsg = {
ENTRY_SELECT_FIELD_FIX: `Adding the value '{value}' in the select field of entry UID '{uid}'...`,
ASSET_FIX: `Fixed publish detials for Asset with UID '{uid}'`,
FIELD_RULE_FIX_MESSAGE: `Fixed Field Rule '{num}' target of Content-type '{ctUid}`,
ASSET_SCAN_STATUS_FIX: `Removed asset with UID '{uid}' (scan status: '{status}') from assets.json.`,
ENTRY_ASSET_REF_FIX: `Removed reference to asset '{asset_uid}' from entry '{uid}' field '{field}'.`,
};

const messages: typeof errors &
Expand Down
30 changes: 26 additions & 4 deletions packages/contentstack-audit/src/modules/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export default class Assets {
public environments: string[] = [];
protected schema: ContentTypeStruct[] = [];
protected missingEnvLocales: Record<string, any> = {};
public missingScanStatusAssets: Record<string, any> = {};
public moduleName: keyof typeof auditConfig.moduleConfig;

constructor({ fix, config, moduleName }: ModuleConstructorParam & CtConstructorParam) {
Expand Down Expand Up @@ -184,7 +185,24 @@ export default class Assets {

for (const assetUid in assets) {
log.debug(`Processing asset: ${assetUid}`, this.config.auditContext);


const scanStatus = this.assets[assetUid]?._asset_scan_status;
if (scanStatus && scanStatus !== 'clean') {
log.debug(`Asset ${assetUid} has a non-clean scan status: ${scanStatus}`, this.config.auditContext);
cliux.print($t(auditMsg.SCAN_ASSET_QUARANTINE_MSG, { uid: assetUid, status: scanStatus }), {
color: 'yellow',
});
this.missingScanStatusAssets[assetUid] = [
{ asset_uid: assetUid, filename: this.assets[assetUid].filename, scan_status: scanStatus },
];

if (this.fix) {
log.info($t(auditFixMsg.ASSET_SCAN_STATUS_FIX, { uid: assetUid, status: scanStatus }), this.config.auditContext);
delete this.assets[assetUid];
continue;
}
}

if (this.assets[assetUid]?.publish_details && !Array.isArray(this.assets[assetUid].publish_details)) {
log.debug(`Asset ${assetUid} has invalid publish_details format`, this.config.auditContext);
cliux.print($t(auditMsg.ASSET_NOT_EXIST, { uid: assetUid }), { color: 'red' });
Expand Down Expand Up @@ -226,15 +244,19 @@ export default class Assets {

const remainingPublishDetails = this.assets[assetUid].publish_details?.length || 0;
log.debug(`Asset ${assetUid} now has ${remainingPublishDetails} valid publish details`, this.config.auditContext);

if (this.fix) {
log.debug(`Fixing asset ${assetUid}`, this.config.auditContext);
log.info($t(auditFixMsg.ASSET_FIX, { uid: assetUid }), this.config.auditContext);
await this.writeFixContent(`${basePath}/${indexer[fileIndex]}`, this.assets);
}
}

if (this.fix) {
log.debug(`Writing fixed assets chunk to: ${basePath}/${indexer[fileIndex]}`, this.config.auditContext);
await this.writeFixContent(`${basePath}/${indexer[fileIndex]}`, this.assets);
}
}

log.debug(`Asset reference validation completed. Processed ${Object.keys(this.missingEnvLocales).length} assets with issues`, this.config.auditContext);
}
}
Loading
Loading