Skip to content

Commit a8774c5

Browse files
authored
Merge pull request #2285 from contentstack/feat/DX-3810
added composable studio validation in audit plugin
2 parents c6c700e + 584e628 commit a8774c5

27 files changed

+6322
-3540
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ node_modules
33
.env
44
.dccache
55
logs
6-
contents
6+
/contents
77
lerna-debug.log
88
.DS_Store
99
contentTest

.talismanrc

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
fileignoreconfig:
22
- filename: package-lock.json
3-
checksum: 25bcbb12c701b53f222c599fa8ce53f347853a1d96257cee79b5cf5878e50015
3+
checksum: 0cac869eb2f174e45751388de3eb46d48fbc8f5dbc56faf06000dbad7b5e8466
44
- filename: pnpm-lock.yaml
5-
checksum: 448638c016e13e936e2dfa8297076162b0662de198908d994665579bab8f4b36
5+
checksum: cf7ddbd499ceb5d26ceb94381db0ecd576745b96b4deedd7442d3c8aa820ba92
66
- filename: packages/contentstack-import-setup/test/unit/backup-handler.test.ts
77
checksum: 0582d62b88834554cf12951c8690a73ef3ddbb78b82d2804d994cf4148e1ef93
88
- filename: packages/contentstack-import-setup/test/config.json
@@ -95,8 +95,6 @@ fileignoreconfig:
9595
checksum: bbe1130f5f5ebf2fa452daef743fe4d40ae9f8fc05c7f8c59c82a3d3d1ed69e8
9696
- filename: packages/contentstack-audit/src/modules/extensions.ts
9797
checksum: 32af019f0df8288448d11559fe9f7ef61d3e43c3791d45eeec25fd0937c6baad
98-
- filename: packages/contentstack-audit/src/modules/modulesData.ts
99-
checksum: bac8f1971ac2e39bc04d9297b81951fe34ed265dfc985137135f9bbe775cd63c
10098
- filename: packages/contentstack-audit/src/modules/assets.ts
10199
checksum: 5a007804c75976dd192ed2284b7b7edbc5b5fc269fc0e883908b52e4d4f206a8
102100
- filename: packages/contentstack-audit/src/modules/workflows.ts
@@ -118,7 +116,7 @@ fileignoreconfig:
118116
- filename: packages/contentstack-import/test/unit/import/modules/mock-data/entries/environments.json
119117
checksum: 17f94f500dcb265575b60f8d2cb7464372a234e452527b3bdec6052c606cee28
120118
- filename: packages/contentstack-import/test/unit/import/modules/entries.test.ts
121-
checksum: 7b984d292a534f9d075d801de2aeff802b2832bc5e2efadf8613a7059f4317fc
119+
checksum: d8e4f6ad185b36b6f84b38dce169144e7d5a195668aac11f914eed5e1e4b5478
122120
- filename: packages/contentstack-import/test/unit/import/modules/labels.test.ts
123121
checksum: 46fe0d1602ab386f7eaee9839bc376b98ab8d4262f823784eda9cfa2bf893758
124122
- filename: packages/contentstack-export/test/unit/export/modules/assets.test.ts
@@ -269,4 +267,10 @@ fileignoreconfig:
269267
checksum: e8714ef41940f3a9be782dfaa43a15df57bd1eb4c3f0e4d5f305e68681c1bd93
270268
- filename: packages/contentstack-import/src/import/modules-js/environments.js
271269
checksum: d484342c25462a7052c8aae6cad0baed9a01e1eaa67d6a09f175981c53092301
270+
- filename: packages/contentstack-audit/test/unit/mock/contents/composable_studio/environments/environments.json
271+
checksum: 0402604e5919a7e38ecb5ff0916d6ae5ab7d98fe78ff6ac9eba8a9b8130af34d
272+
- filename: packages/contentstack-audit/test/unit/mock/contents/composable_studio/composable_studio.json
273+
checksum: 6912e5ea32b4456ad04d1645750c72bbb29ab1895368c3a242ab39e9350ec531
274+
- filename: packages/contentstack-audit/test/unit/mock/contents/composable_studio/invalid_composable_studio.json
275+
checksum: e6465aa0011d1565a2de848d9cca74395d11419e6ac840e7dfb52e1d255b1c4f
272276
version: '1.0'

package-lock.json

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

packages/contentstack-audit/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/cli-audit",
3-
"version": "1.16.2",
3+
"version": "1.17.0",
44
"description": "Contentstack audit plugin",
55
"author": "Contentstack CLI",
66
"homepage": "https://github.com/contentstack/cli",

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

Lines changed: 79 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@ import { v4 as uuid } from 'uuid';
55
import isEmpty from 'lodash/isEmpty';
66
import { join, resolve } from 'path';
77
import cloneDeep from 'lodash/cloneDeep';
8-
import { cliux, sanitizePath, TableFlags, TableHeader, log, configHandler, createLogContext } from '@contentstack/cli-utilities';
8+
import {
9+
cliux,
10+
sanitizePath,
11+
TableFlags,
12+
TableHeader,
13+
log,
14+
configHandler,
15+
createLogContext,
16+
} from '@contentstack/cli-utilities';
917
import { createWriteStream, existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from 'fs';
1018
import config from './config';
1119
import { print } from './util/log';
@@ -21,6 +29,7 @@ import {
2129
FieldRule,
2230
ModuleDataReader,
2331
CustomRoles,
32+
ComposableStudio,
2433
} from './modules';
2534

2635
import {
@@ -50,7 +59,6 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
5059
};
5160
}
5261

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

68-
6976
await this.promptQueue();
7077
await this.createBackUp();
7178
this.sharedConfig.reportPath = resolve(this.flags['report-path'] || process.cwd(), 'audit-report');
@@ -86,6 +93,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
8693
missingEnvLocalesInEntries,
8794
missingFieldRules,
8895
missingMultipleFields,
96+
missingRefsInComposableStudio,
8997
} = await this.scanAndFix();
9098

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

@@ -131,12 +140,16 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
131140
!isEmpty(missingEnvLocalesInAssets) ||
132141
!isEmpty(missingEnvLocalesInEntries) ||
133142
!isEmpty(missingFieldRules) ||
134-
!isEmpty(missingMultipleFields)
143+
!isEmpty(missingMultipleFields) ||
144+
!isEmpty(missingRefsInComposableStudio)
135145
) {
136146
if (this.currentCommand === 'cm:stacks:audit') {
137147
log.warn(this.$t(auditMsg.FINAL_REPORT_PATH, { path: this.sharedConfig.reportPath }), this.auditContext);
138148
} else {
139-
log.warn(this.$t(this.messages.FIXED_CONTENT_PATH_MAG, { path: this.sharedConfig.basePath }), this.auditContext);
149+
log.warn(
150+
this.$t(this.messages.FIXED_CONTENT_PATH_MAG, { path: this.sharedConfig.basePath }),
151+
this.auditContext,
152+
);
140153
}
141154
} else {
142155
log.info(this.messages.NO_MISSING_REF_FOUND, this.auditContext);
@@ -162,7 +175,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
162175
!isEmpty(missingRefInCustomRoles) ||
163176
!isEmpty(missingEnvLocalesInAssets) ||
164177
!isEmpty(missingEnvLocalesInEntries) ||
165-
!isEmpty(missingFieldRules)
178+
!isEmpty(missingFieldRules) ||
179+
!isEmpty(missingRefsInComposableStudio)
166180
);
167181
}
168182

@@ -175,8 +189,11 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
175189
async scanAndFix() {
176190
log.debug('Starting scan and fix process', this.auditContext);
177191
let { ctSchema, gfSchema } = this.getCtAndGfSchema();
178-
log.info(`Retrieved ${ctSchema?.length || 0} content types and ${gfSchema?.length || 0} global fields`, this.auditContext);
179-
192+
log.info(
193+
`Retrieved ${ctSchema?.length || 0} content types and ${gfSchema?.length || 0} global fields`,
194+
this.auditContext,
195+
);
196+
180197
let missingCtRefs,
181198
missingGfRefs,
182199
missingEntryRefs,
@@ -197,7 +214,8 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
197214
missingEnvLocalesInAssets,
198215
missingEnvLocalesInEntries,
199216
missingFieldRules,
200-
missingMultipleFields;
217+
missingMultipleFields,
218+
missingRefsInComposableStudio;
201219

202220
const constructorParam: ModuleConstructorParam & CtConstructorParam = {
203221
ctSchema,
@@ -233,21 +251,30 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
233251
missingEnvLocalesInAssets = await new Assets(cloneDeep(constructorParam)).run();
234252
await this.prepareReport(module, missingEnvLocalesInAssets);
235253
this.getAffectedData('assets', dataModuleWise['assets'], missingEnvLocalesInAssets);
236-
log.success(`Assets audit completed. Found ${Object.keys(missingEnvLocalesInAssets || {}).length} issues`, this.auditContext);
254+
log.success(
255+
`Assets audit completed. Found ${Object.keys(missingEnvLocalesInAssets || {}).length} issues`,
256+
this.auditContext,
257+
);
237258
break;
238259
case 'content-types':
239260
log.info('Executing content-types audit', this.auditContext);
240261
missingCtRefs = await new ContentType(cloneDeep(constructorParam)).run();
241262
await this.prepareReport(module, missingCtRefs);
242263
this.getAffectedData('content-types', dataModuleWise['content-types'], missingCtRefs);
243-
log.success(`Content-types audit completed. Found ${Object.keys(missingCtRefs || {}).length} issues`, this.auditContext);
264+
log.success(
265+
`Content-types audit completed. Found ${Object.keys(missingCtRefs || {}).length} issues`,
266+
this.auditContext,
267+
);
244268
break;
245269
case 'global-fields':
246270
log.info('Executing global-fields audit', this.auditContext);
247271
missingGfRefs = await new GlobalField(cloneDeep(constructorParam)).run();
248272
await this.prepareReport(module, missingGfRefs);
249273
this.getAffectedData('global-fields', dataModuleWise['global-fields'], missingGfRefs);
250-
log.success(`Global-fields audit completed. Found ${Object.keys(missingGfRefs || {}).length} issues`, this.auditContext);
274+
log.success(
275+
`Global-fields audit completed. Found ${Object.keys(missingGfRefs || {}).length} issues`,
276+
this.auditContext,
277+
);
251278
break;
252279
case 'entries':
253280
log.info('Executing entries audit', this.auditContext);
@@ -270,7 +297,10 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
270297

271298
await this.prepareReport('Entry_Multiple_Fields', missingMultipleFields);
272299
this.getAffectedData('entries', dataModuleWise['entries'], missingEntry);
273-
log.success(`Entries audit completed. Found ${Object.keys(missingEntryRefs || {}).length} reference issues`, this.auditContext);
300+
log.success(
301+
`Entries audit completed. Found ${Object.keys(missingEntryRefs || {}).length} reference issues`,
302+
this.auditContext,
303+
);
274304

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

288321
break;
289322
case 'extensions':
290323
log.info('Executing extensions audit', this.auditContext);
291324
missingCtRefsInExtensions = await new Extensions(cloneDeep(constructorParam)).run();
292325
await this.prepareReport(module, missingCtRefsInExtensions);
293326
this.getAffectedData('extensions', dataModuleWise['extensions'], missingCtRefsInExtensions);
294-
log.success(`Extensions audit completed. Found ${Object.keys(missingCtRefsInExtensions || {}).length} issues`, this.auditContext);
327+
log.success(
328+
`Extensions audit completed. Found ${Object.keys(missingCtRefsInExtensions || {}).length} issues`,
329+
this.auditContext,
330+
);
295331
break;
296332
case 'custom-roles':
297333
log.info('Executing custom-roles audit', this.auditContext);
298334
missingRefInCustomRoles = await new CustomRoles(cloneDeep(constructorParam)).run();
299335
await this.prepareReport(module, missingRefInCustomRoles);
300336
this.getAffectedData('custom-roles', dataModuleWise['custom-roles'], missingRefInCustomRoles);
301-
log.success(`Custom-roles audit completed. Found ${Object.keys(missingRefInCustomRoles || {}).length} issues`, this.auditContext);
337+
log.success(
338+
`Custom-roles audit completed. Found ${Object.keys(missingRefInCustomRoles || {}).length} issues`,
339+
this.auditContext,
340+
);
302341

303342
break;
304343
case 'field-rules':
305344
log.info('Executing field-rules audit', this.auditContext);
306345
// NOTE: We are using the fixed content-type for validation of field rules
307-
const data = this.getCtAndGfSchema();
346+
const data = this.getCtAndGfSchema();
308347
constructorParam.ctSchema = data.ctSchema;
309348
constructorParam.gfSchema = data.gfSchema;
310349
missingFieldRules = await new FieldRule(cloneDeep(constructorParam)).run();
311350
await this.prepareReport(module, missingFieldRules);
312351
this.getAffectedData('field-rules', dataModuleWise['content-types'], missingFieldRules);
313-
log.success(`Field-rules audit completed. Found ${Object.keys(missingFieldRules || {}).length} issues`, this.auditContext);
352+
log.success(
353+
`Field-rules audit completed. Found ${Object.keys(missingFieldRules || {}).length} issues`,
354+
this.auditContext,
355+
);
356+
break;
357+
case 'composable-studio':
358+
log.info('Executing composable-studio audit', this.auditContext);
359+
missingRefsInComposableStudio = await new ComposableStudio(cloneDeep(constructorParam)).run();
360+
await this.prepareReport(module, missingRefsInComposableStudio);
361+
this.getAffectedData(
362+
'composable-studio',
363+
dataModuleWise['composable-studio'] || { Total: Object.keys(missingRefsInComposableStudio || {}).length },
364+
missingRefsInComposableStudio,
365+
);
366+
log.success(
367+
`Composable-studio audit completed. Found ${
368+
Object.keys(missingRefsInComposableStudio || {}).length
369+
} issues`,
370+
this.auditContext,
371+
);
314372
break;
315373
}
316374

@@ -345,6 +403,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
345403
missingEnvLocalesInEntries,
346404
missingFieldRules,
347405
missingMultipleFields,
406+
missingRefsInComposableStudio,
348407
};
349408
}
350409

@@ -488,7 +547,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
488547
}
489548

490549
print([{ bold: true, color: 'cyan', message: ` ${module}` }]);
491-
550+
492551
const tableValues = Object.values(missingRefs).flat();
493552
missingRefs = Object.values(missingRefs).flat();
494553
const tableKeys = Object.keys(missingRefs[0]);
@@ -542,7 +601,7 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
542601
log.debug(`Preparing report for module: ${moduleName}`, this.auditContext);
543602
log.debug(`Report path: ${this.sharedConfig.reportPath}`, this.auditContext);
544603
log.info(`Missing references count: ${Object.keys(listOfMissingRefs).length}`, this.auditContext);
545-
604+
546605
if (isEmpty(listOfMissingRefs)) {
547606
log.debug(`No missing references found for ${moduleName}, skipping report generation`, this.auditContext);
548607
return Promise.resolve(void 0);

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

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ const config = {
1111
'custom-roles',
1212
'assets',
1313
'field-rules',
14+
'composable-studio',
1415
],
1516
'fix-fields': ['reference', 'global_field', 'json:rte', 'json:extension', 'blocks', 'group', 'content_types'],
16-
'schema-fields-data-type': ['blocks','group','global_field'],
17+
'schema-fields-data-type': ['blocks', 'group', 'global_field'],
1718
moduleConfig: {
1819
'content-types': {
1920
name: 'content type',
@@ -60,6 +61,11 @@ const config = {
6061
dirName: 'environments',
6162
fileName: 'environments.json',
6263
},
64+
'composable-studio': {
65+
name: 'composable-studio',
66+
dirName: 'composable_studio',
67+
fileName: 'composable_studio.json',
68+
},
6369
},
6470
entries: {
6571
systemKeys: [
@@ -107,21 +113,22 @@ const config = {
107113
'selectedValue',
108114
'ct_uid',
109115
'action',
110-
"Module",
111-
"Total",
112-
"Fixable",
113-
"Non-Fixable",
114-
"Fixed",
115-
"Not-Fixed",
116-
"Passed",
116+
'Module',
117+
'Total',
118+
'Fixable',
119+
'Non-Fixable',
120+
'Fixed',
121+
'Not-Fixed',
122+
'Passed',
123+
'issues',
117124
],
118125
ReportTitleForEntries: {
119126
Entries_Select_field: 'Entries_Select_field',
120127
Entries_Mandatory_field: 'Entries_Mandatory_field',
121128
Entries_Title_field: 'Entries_Title_field',
122129
Entry_Missing_Locale_and_Env: 'Entry_Missing_Locale_and_Env',
123130
Entry_Missing_Locale_and_Env_in_Publish_Details: 'Entry_Missing_Locale_and_Env_in_Publish_Details',
124-
Entry_Multiple_Fields:"Entry_Multiple_Fields"
131+
Entry_Multiple_Fields: 'Entry_Multiple_Fields',
125132
},
126133
feild_level_modules: [
127134
'Entries_Title_field',
@@ -130,7 +137,7 @@ const config = {
130137
'Entry_Missing_Locale_and_Env_in_Publish_Details',
131138
'field-rules',
132139
'Entry_Multiple_Fields',
133-
'Summary'
140+
'Summary',
134141
],
135142
fixSelectField: false,
136143
};

0 commit comments

Comments
 (0)