@contentstack/cli-audit 1.16.2 → 2.0.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Contentstack
3
+ Copyright (c) 2024 Contentstack
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -19,7 +19,7 @@ $ npm install -g @contentstack/cli-audit
19
19
  $ csdx COMMAND
20
20
  running command...
21
21
  $ csdx (--version|-v)
22
- @contentstack/cli-audit/1.16.2 linux-x64 node-v22.21.1
22
+ @contentstack/cli-audit/2.0.0-beta linux-x64 node-v22.21.1
23
23
  $ csdx --help [COMMAND]
24
24
  USAGE
25
25
  $ csdx COMMAND
@@ -12,6 +12,10 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
12
12
  get: (row: any) => string;
13
13
  };
14
14
  };
15
+ /**
16
+ * Create audit context object similar to export command
17
+ */
18
+ private createAuditContext;
15
19
  /**
16
20
  * The `start` function performs an audit on content types, global fields, entries, and workflows and displays
17
21
  * any missing references.
@@ -33,6 +33,19 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
33
33
  },
34
34
  };
35
35
  }
36
+ /**
37
+ * Create audit context object similar to export command
38
+ */
39
+ createAuditContext(moduleName) {
40
+ var _a, _b, _c;
41
+ return {
42
+ command: ((_b = (_a = this.context) === null || _a === void 0 ? void 0 : _a.info) === null || _b === void 0 ? void 0 : _b.command) || 'cm:stacks:audit',
43
+ module: moduleName || 'audit',
44
+ email: cli_utilities_1.configHandler.get('email') || '',
45
+ sessionId: ((_c = this.context) === null || _c === void 0 ? void 0 : _c.sessionId) || '',
46
+ authenticationMethod: cli_utilities_1.configHandler.get('authenticationMethod') || '',
47
+ };
48
+ }
36
49
  /**
37
50
  * The `start` function performs an audit on content types, global fields, entries, and workflows and displays
38
51
  * any missing references.
@@ -40,13 +53,21 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
40
53
  * being executed.
41
54
  */
42
55
  async start(command) {
43
- var _a, _b;
44
56
  this.currentCommand = command;
45
- // Initialize audit context (reused, no need to call again in scanAndFix)
46
- (0, cli_utilities_1.createLogContext)((_b = (_a = this.context) === null || _a === void 0 ? void 0 : _a.info) === null || _b === void 0 ? void 0 : _b.command, '', cli_utilities_1.configHandler.get('authenticationMethod'));
47
- this.auditContext = { module: 'audit' };
57
+ // Set progress supported module and console logs setting BEFORE any log calls
58
+ // This ensures the logger respects the setting when it's initialized
59
+ const logConfig = cli_utilities_1.configHandler.get('log') || {};
60
+ // Default to false so progress bars are shown instead of console logs
61
+ if (logConfig.showConsoleLogs === undefined) {
62
+ cli_utilities_1.configHandler.set('log.showConsoleLogs', false);
63
+ }
64
+ cli_utilities_1.configHandler.set('log.progressSupportedModule', 'audit');
65
+ // Initialize audit context
66
+ this.auditContext = this.createAuditContext();
48
67
  cli_utilities_1.log.debug(`Starting audit command: ${command}`, this.auditContext);
49
68
  cli_utilities_1.log.info(`Starting audit command: ${command}`, this.auditContext);
69
+ // Initialize global summary for progress tracking
70
+ cli_utilities_1.CLIProgressManager.initializeGlobalSummary('AUDIT', '', 'Auditing content...');
50
71
  await this.promptQueue();
51
72
  await this.createBackUp();
52
73
  this.sharedConfig.reportPath = (0, path_1.resolve)(this.flags['report-path'] || process.cwd(), 'audit-report');
@@ -110,6 +131,10 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
110
131
  (0, fs_1.rmSync)(this.sharedConfig.basePath, { recursive: true });
111
132
  }
112
133
  }
134
+ // Print comprehensive summary at the end
135
+ cli_utilities_1.CLIProgressManager.printGlobalSummary();
136
+ // Clear progress module setting now that audit is complete
137
+ (0, cli_utilities_1.clearProgressModuleSetting)();
113
138
  return (!(0, isEmpty_1.default)(missingCtRefs) ||
114
139
  !(0, isEmpty_1.default)(missingGfRefs) ||
115
140
  !(0, isEmpty_1.default)(missingEntryRefs) ||
@@ -128,7 +153,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
128
153
  * and `missingEntryRefs`.
129
154
  */
130
155
  async scanAndFix() {
131
- var _a, _b, _c, _d, _e, _f;
156
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
132
157
  cli_utilities_1.log.debug('Starting scan and fix process', this.auditContext);
133
158
  let { ctSchema, gfSchema } = this.getCtAndGfSchema();
134
159
  cli_utilities_1.log.info(`Retrieved ${(ctSchema === null || ctSchema === void 0 ? void 0 : ctSchema.length) || 0} content types and ${(gfSchema === null || gfSchema === void 0 ? void 0 : gfSchema.length) || 0} global fields`, this.auditContext);
@@ -141,50 +166,60 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
141
166
  };
142
167
  let dataModuleWise = await new modules_1.ModuleDataReader((0, cloneDeep_1.default)(constructorParam)).run();
143
168
  cli_utilities_1.log.debug(`Data module wise: ${JSON.stringify(dataModuleWise)}`, this.auditContext);
169
+ // Extract logConfig and showConsoleLogs once before the loop to reuse throughout
170
+ const logConfig = cli_utilities_1.configHandler.get('log') || {};
171
+ const showConsoleLogs = (_a = logConfig.showConsoleLogs) !== null && _a !== void 0 ? _a : true;
144
172
  for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) {
145
173
  // Update audit context with current module
146
- this.auditContext = { module: module };
174
+ this.auditContext = this.createAuditContext(module);
147
175
  cli_utilities_1.log.debug(`Starting audit for module: ${module}`, this.auditContext);
148
176
  cli_utilities_1.log.info(`Starting audit for module: ${module}`, this.auditContext);
149
- (0, log_1.print)([
150
- {
151
- bold: true,
152
- color: 'whiteBright',
153
- message: this.$t(this.messages.AUDIT_START_SPINNER, { module }),
154
- },
155
- ]);
177
+ // Only show spinner message if console logs are enabled (compatible with line-by-line logs)
178
+ if (showConsoleLogs) {
179
+ (0, log_1.print)([
180
+ {
181
+ bold: true,
182
+ color: 'whiteBright',
183
+ message: this.$t(this.messages.AUDIT_START_SPINNER, { module }),
184
+ },
185
+ ]);
186
+ }
156
187
  constructorParam['moduleName'] = module;
157
188
  switch (module) {
158
189
  case 'assets':
159
190
  cli_utilities_1.log.info('Executing assets audit', this.auditContext);
160
- missingEnvLocalesInAssets = await new modules_1.Assets((0, cloneDeep_1.default)(constructorParam)).run();
191
+ const assetsTotalCount = ((_b = dataModuleWise['assets']) === null || _b === void 0 ? void 0 : _b.Total) || 0;
192
+ missingEnvLocalesInAssets = await new modules_1.Assets((0, cloneDeep_1.default)(constructorParam)).run(false, assetsTotalCount);
161
193
  await this.prepareReport(module, missingEnvLocalesInAssets);
162
194
  this.getAffectedData('assets', dataModuleWise['assets'], missingEnvLocalesInAssets);
163
195
  cli_utilities_1.log.success(`Assets audit completed. Found ${Object.keys(missingEnvLocalesInAssets || {}).length} issues`, this.auditContext);
164
196
  break;
165
197
  case 'content-types':
166
198
  cli_utilities_1.log.info('Executing content-types audit', this.auditContext);
167
- missingCtRefs = await new modules_1.ContentType((0, cloneDeep_1.default)(constructorParam)).run();
199
+ const contentTypesTotalCount = ((_c = dataModuleWise['content-types']) === null || _c === void 0 ? void 0 : _c.Total) || 0;
200
+ missingCtRefs = await new modules_1.ContentType((0, cloneDeep_1.default)(constructorParam)).run(false, contentTypesTotalCount);
168
201
  await this.prepareReport(module, missingCtRefs);
169
202
  this.getAffectedData('content-types', dataModuleWise['content-types'], missingCtRefs);
170
203
  cli_utilities_1.log.success(`Content-types audit completed. Found ${Object.keys(missingCtRefs || {}).length} issues`, this.auditContext);
171
204
  break;
172
205
  case 'global-fields':
173
206
  cli_utilities_1.log.info('Executing global-fields audit', this.auditContext);
174
- missingGfRefs = await new modules_1.GlobalField((0, cloneDeep_1.default)(constructorParam)).run();
207
+ const globalFieldsTotalCount = ((_d = dataModuleWise['global-fields']) === null || _d === void 0 ? void 0 : _d.Total) || 0;
208
+ missingGfRefs = await new modules_1.GlobalField((0, cloneDeep_1.default)(constructorParam)).run(false, globalFieldsTotalCount);
175
209
  await this.prepareReport(module, missingGfRefs);
176
210
  this.getAffectedData('global-fields', dataModuleWise['global-fields'], missingGfRefs);
177
211
  cli_utilities_1.log.success(`Global-fields audit completed. Found ${Object.keys(missingGfRefs || {}).length} issues`, this.auditContext);
178
212
  break;
179
213
  case 'entries':
180
214
  cli_utilities_1.log.info('Executing entries audit', this.auditContext);
181
- missingEntry = await new modules_1.Entries((0, cloneDeep_1.default)(constructorParam)).run();
182
- missingEntryRefs = (_a = missingEntry.missingEntryRefs) !== null && _a !== void 0 ? _a : {};
183
- missingSelectFeild = (_b = missingEntry.missingSelectFeild) !== null && _b !== void 0 ? _b : {};
184
- missingMandatoryFields = (_c = missingEntry.missingMandatoryFields) !== null && _c !== void 0 ? _c : {};
185
- missingTitleFields = (_d = missingEntry.missingTitleFields) !== null && _d !== void 0 ? _d : {};
186
- missingEnvLocalesInEntries = (_e = missingEntry.missingEnvLocale) !== null && _e !== void 0 ? _e : {};
187
- missingMultipleFields = (_f = missingEntry.missingMultipleFields) !== null && _f !== void 0 ? _f : {};
215
+ const entriesTotalCount = ((_e = dataModuleWise['entries']) === null || _e === void 0 ? void 0 : _e.Total) || 0;
216
+ missingEntry = await new modules_1.Entries((0, cloneDeep_1.default)(constructorParam)).run(entriesTotalCount);
217
+ missingEntryRefs = (_f = missingEntry.missingEntryRefs) !== null && _f !== void 0 ? _f : {};
218
+ missingSelectFeild = (_g = missingEntry.missingSelectFeild) !== null && _g !== void 0 ? _g : {};
219
+ missingMandatoryFields = (_h = missingEntry.missingMandatoryFields) !== null && _h !== void 0 ? _h : {};
220
+ missingTitleFields = (_j = missingEntry.missingTitleFields) !== null && _j !== void 0 ? _j : {};
221
+ missingEnvLocalesInEntries = (_k = missingEntry.missingEnvLocale) !== null && _k !== void 0 ? _k : {};
222
+ missingMultipleFields = (_l = missingEntry.missingMultipleFields) !== null && _l !== void 0 ? _l : {};
188
223
  await this.prepareReport(module, missingEntryRefs);
189
224
  await this.prepareReport(`Entries_Select_field`, missingSelectFeild);
190
225
  await this.prepareReport('Entries_Mandatory_field', missingMandatoryFields);
@@ -196,26 +231,29 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
196
231
  break;
197
232
  case 'workflows':
198
233
  cli_utilities_1.log.info('Executing workflows audit', this.auditContext);
234
+ const workflowsTotalCount = ((_m = dataModuleWise['workflows']) === null || _m === void 0 ? void 0 : _m.Total) || 0;
199
235
  missingCtRefsInWorkflow = await new modules_1.Workflows({
200
236
  ctSchema,
201
237
  moduleName: module,
202
238
  config: this.sharedConfig,
203
239
  fix: this.currentCommand === 'cm:stacks:audit:fix',
204
- }).run();
240
+ }).run(workflowsTotalCount);
205
241
  await this.prepareReport(module, missingCtRefsInWorkflow);
206
242
  this.getAffectedData('workflows', dataModuleWise['workflows'], missingCtRefsInWorkflow);
207
243
  cli_utilities_1.log.success(`Workflows audit completed. Found ${Object.keys(missingCtRefsInWorkflow || {}).length} issues`, this.auditContext);
208
244
  break;
209
245
  case 'extensions':
210
246
  cli_utilities_1.log.info('Executing extensions audit', this.auditContext);
211
- missingCtRefsInExtensions = await new modules_1.Extensions((0, cloneDeep_1.default)(constructorParam)).run();
247
+ const extensionsTotalCount = ((_o = dataModuleWise['extensions']) === null || _o === void 0 ? void 0 : _o.Total) || 0;
248
+ missingCtRefsInExtensions = await new modules_1.Extensions((0, cloneDeep_1.default)(constructorParam)).run(extensionsTotalCount);
212
249
  await this.prepareReport(module, missingCtRefsInExtensions);
213
250
  this.getAffectedData('extensions', dataModuleWise['extensions'], missingCtRefsInExtensions);
214
251
  cli_utilities_1.log.success(`Extensions audit completed. Found ${Object.keys(missingCtRefsInExtensions || {}).length} issues`, this.auditContext);
215
252
  break;
216
253
  case 'custom-roles':
217
254
  cli_utilities_1.log.info('Executing custom-roles audit', this.auditContext);
218
- missingRefInCustomRoles = await new modules_1.CustomRoles((0, cloneDeep_1.default)(constructorParam)).run();
255
+ const customRolesTotalCount = ((_p = dataModuleWise['custom-roles']) === null || _p === void 0 ? void 0 : _p.Total) || 0;
256
+ missingRefInCustomRoles = await new modules_1.CustomRoles((0, cloneDeep_1.default)(constructorParam)).run(customRolesTotalCount);
219
257
  await this.prepareReport(module, missingRefInCustomRoles);
220
258
  this.getAffectedData('custom-roles', dataModuleWise['custom-roles'], missingRefInCustomRoles);
221
259
  cli_utilities_1.log.success(`Custom-roles audit completed. Found ${Object.keys(missingRefInCustomRoles || {}).length} issues`, this.auditContext);
@@ -226,24 +264,28 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
226
264
  const data = this.getCtAndGfSchema();
227
265
  constructorParam.ctSchema = data.ctSchema;
228
266
  constructorParam.gfSchema = data.gfSchema;
229
- missingFieldRules = await new modules_1.FieldRule((0, cloneDeep_1.default)(constructorParam)).run();
267
+ const fieldRulesTotalCount = ((_q = dataModuleWise['content-types']) === null || _q === void 0 ? void 0 : _q.Total) || 0;
268
+ missingFieldRules = await new modules_1.FieldRule((0, cloneDeep_1.default)(constructorParam)).run(fieldRulesTotalCount);
230
269
  await this.prepareReport(module, missingFieldRules);
231
270
  this.getAffectedData('field-rules', dataModuleWise['content-types'], missingFieldRules);
232
271
  cli_utilities_1.log.success(`Field-rules audit completed. Found ${Object.keys(missingFieldRules || {}).length} issues`, this.auditContext);
233
272
  break;
234
273
  }
235
- (0, log_1.print)([
236
- {
237
- bold: true,
238
- color: 'whiteBright',
239
- message: this.$t(this.messages.AUDIT_START_SPINNER, { module }),
240
- },
241
- {
242
- bold: true,
243
- message: ' done',
244
- color: 'whiteBright',
245
- },
246
- ]);
274
+ // Only show completion message if console logs are enabled
275
+ if (showConsoleLogs) {
276
+ (0, log_1.print)([
277
+ {
278
+ bold: true,
279
+ color: 'whiteBright',
280
+ message: this.$t(this.messages.AUDIT_START_SPINNER, { module }),
281
+ },
282
+ {
283
+ bold: true,
284
+ message: ' done',
285
+ color: 'whiteBright',
286
+ },
287
+ ]);
288
+ }
247
289
  }
248
290
  cli_utilities_1.log.debug('Scan and fix process completed', this.auditContext);
249
291
  this.prepareReport('Summary', this.summaryDataToPrint);
@@ -1,9 +1,9 @@
1
- import { ConfigType, ContentTypeStruct, CtConstructorParam, ModuleConstructorParam, EntryStruct } from '../types';
1
+ import { ContentTypeStruct, CtConstructorParam, ModuleConstructorParam, EntryStruct } from '../types';
2
2
  import auditConfig from '../config';
3
- export default class Assets {
3
+ import BaseClass from './base-class';
4
+ export default class Assets extends BaseClass {
4
5
  protected fix: boolean;
5
6
  fileName: string;
6
- config: ConfigType;
7
7
  folderPath: string;
8
8
  currentUid: string;
9
9
  currentTitle: string;
@@ -18,9 +18,11 @@ export default class Assets {
18
18
  /**
19
19
  * The `run` function checks if a folder path exists, sets the schema based on the module name,
20
20
  * iterates over the schema and looks for references, and returns a list of missing references.
21
+ * @param returnFixSchema - If true, returns the fixed schema instead of missing references
22
+ * @param totalCount - Total number of assets to process (for progress tracking)
21
23
  * @returns the `missingEnvLocales` object.
22
24
  */
23
- run(returnFixSchema?: boolean): Promise<Record<string, any> | ContentTypeStruct[]>;
25
+ run(returnFixSchema?: boolean, totalCount?: number): Promise<Record<string, any> | ContentTypeStruct[]>;
24
26
  /**
25
27
  * @method prerequisiteData
26
28
  * The `prerequisiteData` function reads and parses JSON files to retrieve extension and marketplace
@@ -7,15 +7,16 @@ const cli_utilities_1 = require("@contentstack/cli-utilities");
7
7
  const messages_1 = require("../messages");
8
8
  const values_1 = tslib_1.__importDefault(require("lodash/values"));
9
9
  const lodash_1 = require("lodash");
10
- /* The `ContentType` class is responsible for scanning content types, looking for references, and
11
- generating a report in JSON and CSV formats. */
12
- class Assets {
10
+ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
11
+ /* The `Assets` class is responsible for scanning assets, looking for missing environment/locale references,
12
+ and generating a report in JSON and CSV formats. */
13
+ class Assets extends base_class_1.default {
13
14
  constructor({ fix, config, moduleName }) {
15
+ super({ config });
14
16
  this.locales = [];
15
17
  this.environments = [];
16
18
  this.schema = [];
17
19
  this.missingEnvLocales = {};
18
- this.config = config;
19
20
  this.fix = fix !== null && fix !== void 0 ? fix : false;
20
21
  this.moduleName = this.validateModules(moduleName, this.config.moduleConfig);
21
22
  this.fileName = config.moduleConfig[this.moduleName].fileName;
@@ -30,38 +31,54 @@ class Assets {
30
31
  /**
31
32
  * The `run` function checks if a folder path exists, sets the schema based on the module name,
32
33
  * iterates over the schema and looks for references, and returns a list of missing references.
34
+ * @param returnFixSchema - If true, returns the fixed schema instead of missing references
35
+ * @param totalCount - Total number of assets to process (for progress tracking)
33
36
  * @returns the `missingEnvLocales` object.
34
37
  */
35
- async run(returnFixSchema = false) {
38
+ async run(returnFixSchema = false, totalCount) {
36
39
  var _a;
37
- cli_utilities_1.log.debug(`Starting ${this.moduleName} audit process`, this.config.auditContext);
38
- cli_utilities_1.log.debug(`Data directory: ${this.folderPath}`, this.config.auditContext);
39
- cli_utilities_1.log.debug(`Fix mode: ${this.fix}`, this.config.auditContext);
40
- if (!(0, fs_1.existsSync)(this.folderPath)) {
41
- cli_utilities_1.log.debug(`Skipping ${this.moduleName} audit - path does not exist`, this.config.auditContext);
42
- cli_utilities_1.log.warn(`Skipping ${this.moduleName} audit`, this.config.auditContext);
43
- cli_utilities_1.cliux.print((0, messages_1.$t)(messages_1.auditMsg.NOT_VALID_PATH, { path: this.folderPath }), { color: 'yellow' });
44
- return returnFixSchema ? [] : {};
45
- }
46
- cli_utilities_1.log.debug('Loading prerequisite data (locales and environments)', this.config.auditContext);
47
- await this.prerequisiteData();
48
- cli_utilities_1.log.debug('Starting asset Reference, Environment and Locale validation', this.config.auditContext);
49
- await this.lookForReference();
50
- if (returnFixSchema) {
51
- cli_utilities_1.log.debug(`Returning fixed schema with ${((_a = this.schema) === null || _a === void 0 ? void 0 : _a.length) || 0} items`, this.config.auditContext);
52
- return this.schema;
53
- }
54
- cli_utilities_1.log.debug('Cleaning up empty missing environment/locale references', this.config.auditContext);
55
- for (let propName in this.missingEnvLocales) {
56
- if (Array.isArray(this.missingEnvLocales[propName])) {
57
- if (!this.missingEnvLocales[propName].length) {
58
- delete this.missingEnvLocales[propName];
40
+ try {
41
+ cli_utilities_1.log.debug(`Starting ${this.moduleName} audit process`, this.config.auditContext);
42
+ cli_utilities_1.log.debug(`Data directory: ${this.folderPath}`, this.config.auditContext);
43
+ cli_utilities_1.log.debug(`Fix mode: ${this.fix}`, this.config.auditContext);
44
+ if (!(0, fs_1.existsSync)(this.folderPath)) {
45
+ cli_utilities_1.log.debug(`Skipping ${this.moduleName} audit - path does not exist`, this.config.auditContext);
46
+ cli_utilities_1.log.warn(`Skipping ${this.moduleName} audit`, this.config.auditContext);
47
+ cli_utilities_1.cliux.print((0, messages_1.$t)(messages_1.auditMsg.NOT_VALID_PATH, { path: this.folderPath }), { color: 'yellow' });
48
+ return returnFixSchema ? [] : {};
49
+ }
50
+ // Load prerequisite data with loading spinner
51
+ await this.withLoadingSpinner('ASSETS: Loading prerequisite data (locales and environments)...', async () => {
52
+ await this.prerequisiteData();
53
+ });
54
+ // Create progress manager if we have a total count
55
+ if (totalCount && totalCount > 0) {
56
+ const progress = this.createSimpleProgress(this.moduleName, totalCount);
57
+ progress.updateStatus('Validating asset references...');
58
+ }
59
+ cli_utilities_1.log.debug('Starting asset Reference, Environment and Locale validation', this.config.auditContext);
60
+ await this.lookForReference();
61
+ if (returnFixSchema) {
62
+ cli_utilities_1.log.debug(`Returning fixed schema with ${((_a = this.schema) === null || _a === void 0 ? void 0 : _a.length) || 0} items`, this.config.auditContext);
63
+ return this.schema;
64
+ }
65
+ cli_utilities_1.log.debug('Cleaning up empty missing environment/locale references', this.config.auditContext);
66
+ for (let propName in this.missingEnvLocales) {
67
+ if (Array.isArray(this.missingEnvLocales[propName])) {
68
+ if (!this.missingEnvLocales[propName].length) {
69
+ delete this.missingEnvLocales[propName];
70
+ }
59
71
  }
60
72
  }
73
+ const totalIssues = Object.keys(this.missingEnvLocales).length;
74
+ cli_utilities_1.log.debug(`${this.moduleName} audit completed. Found ${totalIssues} assets with missing environment/locale references`, this.config.auditContext);
75
+ this.completeProgress(true);
76
+ return this.missingEnvLocales;
77
+ }
78
+ catch (error) {
79
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Assets audit failed');
80
+ throw error;
61
81
  }
62
- const totalIssues = Object.keys(this.missingEnvLocales).length;
63
- cli_utilities_1.log.debug(`${this.moduleName} audit completed. Found ${totalIssues} assets with missing environment/locale references`, this.config.auditContext);
64
- return this.missingEnvLocales;
65
82
  }
66
83
  /**
67
84
  * @method prerequisiteData
@@ -182,6 +199,10 @@ class Assets {
182
199
  });
183
200
  const remainingPublishDetails = ((_d = this.assets[assetUid].publish_details) === null || _d === void 0 ? void 0 : _d.length) || 0;
184
201
  cli_utilities_1.log.debug(`Asset ${assetUid} now has ${remainingPublishDetails} valid publish details`, this.config.auditContext);
202
+ // Track progress for each asset processed
203
+ if (this.progressManager) {
204
+ this.progressManager.tick(true, `asset: ${assetUid}`, null);
205
+ }
185
206
  if (this.fix) {
186
207
  cli_utilities_1.log.debug(`Fixing asset ${assetUid}`, this.config.auditContext);
187
208
  cli_utilities_1.log.info((0, messages_1.$t)(messages_1.auditFixMsg.ASSET_FIX, { uid: assetUid }), this.config.auditContext);
@@ -0,0 +1,24 @@
1
+ import { CLIProgressManager } from '@contentstack/cli-utilities';
2
+ import { ConfigType, ModuleConstructorParam } from '../types';
3
+ export default abstract class BaseClass {
4
+ protected progressManager: CLIProgressManager | null;
5
+ protected currentModuleName: string;
6
+ config: ConfigType;
7
+ constructor({ config }: ModuleConstructorParam);
8
+ /**
9
+ * Create simple progress manager
10
+ */
11
+ protected createSimpleProgress(moduleName: string, total?: number): CLIProgressManager;
12
+ /**
13
+ * Create nested progress manager
14
+ */
15
+ protected createNestedProgress(moduleName: string): CLIProgressManager;
16
+ /**
17
+ * Complete progress manager
18
+ */
19
+ protected completeProgress(success?: boolean, error?: string): void;
20
+ /**
21
+ * Execute action with loading spinner (if console logs are disabled)
22
+ */
23
+ protected withLoadingSpinner<T>(message: string, action: () => Promise<T>): Promise<T>;
24
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const cli_utilities_1 = require("@contentstack/cli-utilities");
4
+ class BaseClass {
5
+ constructor({ config }) {
6
+ this.progressManager = null;
7
+ this.currentModuleName = '';
8
+ this.config = config;
9
+ }
10
+ /**
11
+ * Create simple progress manager
12
+ */
13
+ createSimpleProgress(moduleName, total) {
14
+ var _a;
15
+ this.currentModuleName = moduleName;
16
+ const logConfig = cli_utilities_1.configHandler.get('log') || {};
17
+ const showConsoleLogs = (_a = logConfig.showConsoleLogs) !== null && _a !== void 0 ? _a : false;
18
+ this.progressManager = cli_utilities_1.CLIProgressManager.createSimple(moduleName, total, showConsoleLogs);
19
+ return this.progressManager;
20
+ }
21
+ /**
22
+ * Create nested progress manager
23
+ */
24
+ createNestedProgress(moduleName) {
25
+ var _a;
26
+ this.currentModuleName = moduleName;
27
+ const logConfig = cli_utilities_1.configHandler.get('log') || {};
28
+ const showConsoleLogs = (_a = logConfig.showConsoleLogs) !== null && _a !== void 0 ? _a : false;
29
+ this.progressManager = cli_utilities_1.CLIProgressManager.createNested(moduleName, showConsoleLogs);
30
+ return this.progressManager;
31
+ }
32
+ /**
33
+ * Complete progress manager
34
+ */
35
+ completeProgress(success = true, error) {
36
+ var _a;
37
+ (_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.complete(success, error);
38
+ this.progressManager = null;
39
+ }
40
+ /**
41
+ * Execute action with loading spinner (if console logs are disabled)
42
+ */
43
+ async withLoadingSpinner(message, action) {
44
+ var _a;
45
+ const logConfig = cli_utilities_1.configHandler.get('log') || {};
46
+ const showConsoleLogs = (_a = logConfig.showConsoleLogs) !== null && _a !== void 0 ? _a : false;
47
+ if (showConsoleLogs) {
48
+ // If console logs are enabled, don't show spinner, just execute the action
49
+ return await action();
50
+ }
51
+ return await cli_utilities_1.CLIProgressManager.withLoadingSpinner(message, action);
52
+ }
53
+ }
54
+ exports.default = BaseClass;
@@ -1,9 +1,9 @@
1
- import { ConfigType, ModularBlockType, ContentTypeStruct, GroupFieldDataType, RefErrorReturnType, CtConstructorParam, GlobalFieldDataType, JsonRTEFieldDataType, ModularBlocksDataType, ModuleConstructorParam, ReferenceFieldDataType, ContentTypeSchemaType, ExtensionOrAppFieldDataType } from '../types';
1
+ import { ModularBlockType, ContentTypeStruct, GroupFieldDataType, RefErrorReturnType, CtConstructorParam, GlobalFieldDataType, JsonRTEFieldDataType, ModularBlocksDataType, ModuleConstructorParam, ReferenceFieldDataType, ContentTypeSchemaType, ExtensionOrAppFieldDataType } from '../types';
2
2
  import auditConfig from '../config';
3
- export default class ContentType {
3
+ import BaseClass from './base-class';
4
+ export default class ContentType extends BaseClass {
4
5
  protected fix: boolean;
5
6
  fileName: string;
6
- config: ConfigType;
7
7
  folderPath: string;
8
8
  currentUid: string;
9
9
  currentTitle: string;
@@ -19,9 +19,11 @@ export default class ContentType {
19
19
  /**
20
20
  * The `run` function checks if a folder path exists, sets the schema based on the module name,
21
21
  * iterates over the schema and looks for references, and returns a list of missing references.
22
+ * @param returnFixSchema - If true, returns the fixed schema instead of missing references
23
+ * @param totalCount - Total number of items to process (for progress tracking)
22
24
  * @returns the `missingRefs` object.
23
25
  */
24
- run(returnFixSchema?: boolean): Promise<Record<string, any> | ContentTypeStruct[]>;
26
+ run(returnFixSchema?: boolean, totalCount?: number): Promise<Record<string, any> | ContentTypeStruct[]>;
25
27
  /**
26
28
  * @method prerequisiteData
27
29
  * The `prerequisiteData` function reads and parses JSON files to retrieve extension and marketplace