Skip to content

Commit cdce068

Browse files
authored
Merge pull request #1837 from contentstack/feat/DX-2295
Feat: Added Field Rules for Audit and Audit fix
2 parents 6406fca + 7be7eb7 commit cdce068

File tree

14 files changed

+562
-84
lines changed

14 files changed

+562
-84
lines changed

package-lock.json

Lines changed: 9 additions & 9 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: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@ import { join, resolve } from 'path';
77
import cloneDeep from 'lodash/cloneDeep';
88
import { cliux, sanitizePath, TableFlags, TableHeader } from '@contentstack/cli-utilities';
99
import { createWriteStream, existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from 'fs';
10-
1110
import config from './config';
1211
import { print } from './util/log';
1312
import { auditMsg } from './messages';
1413
import { BaseCommand } from './base-command';
15-
import { Entries, GlobalField, ContentType, Extensions, Workflows, Assets } from './modules';
14+
import { Entries, GlobalField, ContentType, Extensions, Workflows, Assets, FieldRule } from './modules';
1615
import {
1716
CommandNames,
1817
ContentTypeStruct,
@@ -61,6 +60,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
6160
missingRefInCustomRoles,
6261
missingEnvLocalesInAssets,
6362
missingEnvLocalesInEntries,
63+
missingFieldRules,
6464
missingMultipleFields
6565
} = await this.scanAndFix();
6666

@@ -71,6 +71,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
7171
]);
7272
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Extensions', missingRefs: missingCtRefsInExtensions }]);
7373
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Workflows', missingRefs: missingCtRefsInWorkflow }]);
74+
7475
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Entries Select Field', missingRefs: missingSelectFeild }]);
7576
this.showOutputOnScreenWorkflowsAndExtension([
7677
{ module: 'Entries Mandatory Field', missingRefs: missingMandatoryFields },
@@ -79,6 +80,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
7980
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Custom Roles', missingRefs: missingRefInCustomRoles }]);
8081
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Assets', missingRefs: missingEnvLocalesInAssets }]);
8182
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Entries Missing Locale and Environments', missingRefs: missingEnvLocalesInEntries }])
83+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Field Rules', missingRefs: missingFieldRules }])
84+
8285
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Entries Changed Multiple Fields', missingRefs: missingMultipleFields }])
8386
if (
8487
!isEmpty(missingCtRefs) ||
@@ -90,7 +93,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
9093
!isEmpty(missingTitleFields) ||
9194
!isEmpty(missingRefInCustomRoles) ||
9295
!isEmpty(missingEnvLocalesInAssets) ||
93-
!isEmpty(missingEnvLocalesInEntries) ||
96+
!isEmpty(missingEnvLocalesInEntries) ||
97+
!isEmpty(missingFieldRules) ||
9498
!isEmpty(missingMultipleFields)
9599
) {
96100
if (this.currentCommand === 'cm:stacks:audit') {
@@ -121,7 +125,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
121125
!isEmpty(missingSelectFeild) ||
122126
!isEmpty(missingRefInCustomRoles) ||
123127
!isEmpty(missingEnvLocalesInAssets) ||
124-
!isEmpty(missingEnvLocalesInEntries)
128+
!isEmpty(missingEnvLocalesInEntries) ||
129+
!isEmpty(missingFieldRules)
125130
);
126131
}
127132

@@ -145,6 +150,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
145150
missingRefInCustomRoles,
146151
missingEnvLocalesInAssets,
147152
missingEnvLocalesInEntries,
153+
missingFieldRules,
148154
missingMultipleFields;
149155

150156
for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) {
@@ -216,6 +222,10 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
216222
missingRefInCustomRoles = await new CustomRoles(cloneDeep(constructorParam)).run();
217223
await this.prepareReport(module, missingRefInCustomRoles);
218224
break;
225+
case 'field-rules':
226+
missingFieldRules = await new FieldRule(cloneDeep(constructorParam)).run();
227+
await this.prepareReport(module, missingFieldRules);
228+
break;
219229
}
220230

221231
print([
@@ -244,6 +254,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
244254
missingRefInCustomRoles,
245255
missingEnvLocalesInAssets,
246256
missingEnvLocalesInEntries,
257+
missingFieldRules,
247258
missingMultipleFields
248259
};
249260
}
@@ -404,7 +415,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
404415
key === 'content_types' ||
405416
key === 'branches' ||
406417
key === 'missingCTSelectFieldValues' ||
407-
key === 'missingFieldUid'
418+
key === 'missingFieldUid' ||
419+
key === 'action'
408420
) {
409421
return chalk.red(typeof cellValue === 'object' ? JSON.stringify(cellValue) : cellValue);
410422
} else {
@@ -429,7 +441,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
429441
* @returns The function `prepareReport` returns a Promise that resolves to `void`.
430442
*/
431443
prepareReport(
432-
moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries,
444+
moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries | 'field-rules',
433445
listOfMissingRefs: Record<string, any>,
434446
): Promise<void> {
435447
if (isEmpty(listOfMissingRefs)) return Promise.resolve(void 0);
@@ -459,7 +471,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
459471
* @returns The function `prepareCSV` returns a Promise that resolves to `void`.
460472
*/
461473
prepareCSV(
462-
moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries,
474+
moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries | 'field-rules',
463475
listOfMissingRefs: Record<string, any>,
464476
): Promise<void> {
465477
if (Object.keys(config.moduleConfig).includes(moduleName) || config.feild_level_modules.includes(moduleName)) {

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

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ const config = {
22
showTerminalOutput: true,
33
skipRefs: ['sys_assets'],
44
skipFieldTypes: ['taxonomy', 'group'],
5-
modules: ['content-types', 'global-fields', 'entries', 'extensions', 'workflows', 'custom-roles', 'assets'],
5+
modules: [
6+
'content-types',
7+
'global-fields',
8+
'entries',
9+
'extensions',
10+
'workflows',
11+
'custom-roles',
12+
'assets',
13+
'field-rules',
14+
],
615
'fix-fields': ['reference', 'global_field', 'json:rte', 'json:extension', 'blocks', 'group', 'content_types'],
716
moduleConfig: {
817
'content-types': {
@@ -95,17 +104,26 @@ const config = {
95104
'publish_environment',
96105
'asset_uid',
97106
'selectedValue',
107+
'ct_uid',
108+
'action',
98109
],
99110
ReportTitleForEntries: {
100111
Entries_Select_feild: 'Entries_Select_feild',
101112
Entries_Mandatory_feild: 'Entries_Mandatory_feild',
102113
Entries_Title_feild: 'Entries_Title_feild',
103114
Entry_Missing_Locale_and_Env: 'Entry_Missing_Locale_and_Env',
104115
Entry_Missing_Locale_and_Env_in_Publish_Details: 'Entry_Missing_Locale_and_Env_in_Publish_Details',
105-
Entry_Multiple_Fields: 'Entry_Multiple_Fields'
116+
Entry_Multiple_Fields:"Entry_Multiple_Fields"
106117
},
107-
feild_level_modules: ['Entries_Title_feild', 'Entries_Mandatory_feild', 'Entries_Select_feild', 'Entry_Missing_Locale_and_Env_in_Publish_Details', 'Entry_Multiple_Fields'],
108-
fixSelectField: false
118+
feild_level_modules: [
119+
'Entries_Title_feild',
120+
'Entries_Mandatory_feild',
121+
'Entries_Select_feild',
122+
'Entry_Missing_Locale_and_Env_in_Publish_Details',
123+
'field-rules',
124+
'Entry_Multiple_Fields'
125+
],
126+
fixSelectField: false,
109127
};
110128

111129
export default config;

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ const auditMsg = {
4343
CT_REFERENCE_FIELD: `The mentioned Reference field is not Array field reference is '{reference_to}' having display name '{display_name}''`,
4444
ASSET_NOT_EXIST: `The publish_details either does not exist or is not an array for asset uid '{uid}'`,
4545
ENTRY_PUBLISH_DETAILS_NOT_EXIST: `The publish_details either does not exist or is not an array for entry uid '{uid}'`,
46+
FIELD_RULE_CONDITION_ABSENT: `The operand field '{condition_field}' is not present in the schema of the content-type {ctUid}`,
47+
FIELD_RULE_TARGET_ABSENT: `The target field '{target_field}' is not present in the schema of the content-type {ctUid}`,
48+
FIELD_RULE_CONDITION_SCAN_MESSAGE: `Completed Scanning of Field Rule '{num}' condition of Content-type '{ctUid}'`,
49+
FIELD_RULE_TARGET_SCAN_MESSAGE: `Completed Scanning of Field Rule '{num}' target of Content-type '{ctUid}'`
4650
};
4751

4852
const auditFixMsg = {
@@ -56,6 +60,7 @@ const auditFixMsg = {
5660
ENTRY_MANDATORY_FIELD_FIX: `Removing the publish details from the entry with UID '{uid}' in Locale '{locale}'...`,
5761
ENTRY_SELECT_FIELD_FIX: `Adding the value '{value}' in the select field of entry UID '{uid}'...`,
5862
ASSET_FIX: `Fixed publish detials for Asset with UID '{uid}'`,
63+
FIELD_RULE_FIX_MESSAGE: `Fixed Field Rule '{num}' target of Content-type '{ctUid}`,
5964
};
6065

6166
const messages: typeof errors &

packages/contentstack-audit/src/modules/content-types.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ export default class ContentType {
4444
protected schema: ContentTypeStruct[] = [];
4545
protected missingRefs: Record<string, any> = {};
4646
public moduleName: keyof typeof auditConfig.moduleConfig;
47-
4847
constructor({ log, fix, config, moduleName, ctSchema, gfSchema }: ModuleConstructorParam & CtConstructorParam) {
4948
this.log = log;
5049
this.config = config;
@@ -185,8 +184,8 @@ export default class ContentType {
185184
if (this.fix) {
186185
field.schema = this.runFixOnSchema(tree, field.schema as ContentTypeSchemaType[]);
187186
}
188-
189187
for (let child of field.schema ?? []) {
188+
190189
if (!fixTypes.includes(child.data_type) && child.data_type !== 'json') continue;
191190

192191
switch (child.data_type) {

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ export default class Entries {
116116
const { uid, title } = entry;
117117
this.currentUid = uid;
118118
this.currentTitle = title;
119+
this.currentTitle = this.removeEmojiAndImages(this.currentTitle)
119120

120121
if (!this.missingRefs[this.currentUid]) {
121122
this.missingRefs[this.currentUid] = [];
@@ -132,7 +133,7 @@ export default class Entries {
132133
this.removeMissingKeysOnEntry(ctSchema.schema as ContentTypeSchemaType[], this.entries[entryUid]);
133134
}
134135

135-
this.lookForReference([{ locale: code, uid, name: title }], ctSchema, this.entries[entryUid]);
136+
this.lookForReference([{ locale: code, uid, name: this.removeEmojiAndImages(title) }], ctSchema, this.entries[entryUid]);
136137

137138
if (this.missingRefs[this.currentUid]?.length) {
138139
this.missingRefs[this.currentUid].forEach((entry: any) => {
@@ -840,6 +841,13 @@ export default class Entries {
840841
* @returns if there is missing field returns field and path
841842
* Else empty array
842843
*/
844+
removeEmojiAndImages(str: string) {
845+
return str.replace(
846+
/[\p{Emoji}\p{Emoji_Presentation}\p{Emoji_Modifier}\p{Emoji_Modifier_Base}\p{Emoji_Component}]+/gu,
847+
'',
848+
);
849+
}
850+
843851
validateSelectField(tree: Record<string, unknown>[], fieldStructure: SelectFeildStruct, field: any) {
844852
const { display_name, enum: selectOptions, multiple, min_instance, display_type, data_type } = fieldStructure;
845853
if (

0 commit comments

Comments
 (0)