@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 +1 -1
- package/README.md +1 -1
- package/lib/audit-base-command.d.ts +4 -0
- package/lib/audit-base-command.js +81 -39
- package/lib/modules/assets.d.ts +6 -4
- package/lib/modules/assets.js +51 -30
- package/lib/modules/base-class.d.ts +24 -0
- package/lib/modules/base-class.js +54 -0
- package/lib/modules/content-types.d.ts +6 -4
- package/lib/modules/content-types.js +62 -40
- package/lib/modules/custom-roles.d.ts +4 -4
- package/lib/modules/custom-roles.js +82 -61
- package/lib/modules/entries.d.ts +5 -4
- package/lib/modules/entries.js +190 -168
- package/lib/modules/extensions.d.ts +4 -4
- package/lib/modules/extensions.js +78 -58
- package/lib/modules/field_rules.d.ts +4 -4
- package/lib/modules/field_rules.js +69 -52
- package/lib/modules/global-fields.d.ts +3 -1
- package/lib/modules/global-fields.js +4 -2
- package/lib/modules/index.d.ts +2 -1
- package/lib/modules/index.js +3 -1
- package/lib/modules/workflows.d.ts +4 -4
- package/lib/modules/workflows.js +85 -68
- package/lib/types/context.d.ts +5 -0
- package/oclif.manifest.json +1 -1
- package/package.json +4 -4
package/LICENSE
CHANGED
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/
|
|
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
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
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 =
|
|
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
|
-
(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
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);
|
package/lib/modules/assets.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ContentTypeStruct, CtConstructorParam, ModuleConstructorParam, EntryStruct } from '../types';
|
|
2
2
|
import auditConfig from '../config';
|
|
3
|
-
|
|
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
|
package/lib/modules/assets.js
CHANGED
|
@@ -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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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 {
|
|
1
|
+
import { ModularBlockType, ContentTypeStruct, GroupFieldDataType, RefErrorReturnType, CtConstructorParam, GlobalFieldDataType, JsonRTEFieldDataType, ModularBlocksDataType, ModuleConstructorParam, ReferenceFieldDataType, ContentTypeSchemaType, ExtensionOrAppFieldDataType } from '../types';
|
|
2
2
|
import auditConfig from '../config';
|
|
3
|
-
|
|
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
|