@contentstack/cli-audit 1.11.0 → 1.12.1
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/README.md +17 -13
- package/lib/audit-base-command.d.ts +4 -2
- package/lib/audit-base-command.js +108 -31
- package/lib/base-command.js +4 -0
- package/lib/config/index.d.ts +1 -0
- package/lib/config/index.js +10 -1
- package/lib/messages/index.d.ts +1 -0
- package/lib/messages/index.js +1 -0
- package/lib/modules/content-types.js +4 -2
- package/lib/modules/field_rules.js +1 -1
- package/lib/modules/index.d.ts +2 -1
- package/lib/modules/index.js +3 -1
- package/lib/modules/modulesData.d.ts +18 -0
- package/lib/modules/modulesData.js +77 -0
- package/lib/types/content-types.d.ts +8 -1
- package/lib/types/content-types.js +7 -0
- package/oclif.manifest.json +15 -1
- package/package.json +9 -9
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.
|
|
22
|
+
@contentstack/cli-audit/1.12.1 linux-x64 node-v22.14.0
|
|
23
23
|
$ csdx --help [COMMAND]
|
|
24
24
|
USAGE
|
|
25
25
|
$ csdx COMMAND
|
|
@@ -52,7 +52,7 @@ Perform audits and find possible errors in the exported Contentstack data
|
|
|
52
52
|
|
|
53
53
|
```
|
|
54
54
|
USAGE
|
|
55
|
-
$ csdx audit [-c <value>] [-d <value>] [--report-path <value>] [--modules
|
|
55
|
+
$ csdx audit [-c <value>] [-d <value>] [--show-console-output] [--report-path <value>] [--modules
|
|
56
56
|
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules...] [--columns <value>]
|
|
57
57
|
[--sort <value>] [--filter <value>] [--csv] [--no-truncate] [--no-header] [--output csv|json|yaml]
|
|
58
58
|
|
|
@@ -63,8 +63,9 @@ FLAGS
|
|
|
63
63
|
--report-path=<value> Path to store the audit reports
|
|
64
64
|
|
|
65
65
|
COMMON FLAGS
|
|
66
|
-
-c, --config=<value>
|
|
67
|
-
-d, --data-dir=<value>
|
|
66
|
+
-c, --config=<value> Path of the external config
|
|
67
|
+
-d, --data-dir=<value> Path where the data is stored
|
|
68
|
+
--show-console-output Display the audit and audit fix result for individual modules
|
|
68
69
|
|
|
69
70
|
TABLE FLAGS
|
|
70
71
|
--columns=<value> Specify columns to display, comma-separated.
|
|
@@ -101,7 +102,7 @@ Perform audits and fix possible errors in the exported Contentstack data.
|
|
|
101
102
|
|
|
102
103
|
```
|
|
103
104
|
USAGE
|
|
104
|
-
$ csdx audit:fix [-c <value>] [-d <value>] [--report-path <value>] [--modules
|
|
105
|
+
$ csdx audit:fix [-c <value>] [-d <value>] [--show-console-output] [--report-path <value>] [--modules
|
|
105
106
|
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules...] [--copy-path <value>
|
|
106
107
|
--copy-dir] [--fix-only reference|global_field|json:rte|json:extension|blocks|group|content_types...] [--columns
|
|
107
108
|
<value>] [--sort <value>] [--filter <value>] [--csv] [--no-truncate] [--no-header] [--output csv|json|yaml]
|
|
@@ -117,8 +118,9 @@ FLAGS
|
|
|
117
118
|
--report-path=<value> Path to store the audit reports
|
|
118
119
|
|
|
119
120
|
COMMON FLAGS
|
|
120
|
-
-c, --config=<value>
|
|
121
|
-
-d, --data-dir=<value>
|
|
121
|
+
-c, --config=<value> Path of the external config
|
|
122
|
+
-d, --data-dir=<value> Path where the data is stored
|
|
123
|
+
--show-console-output Display the audit and audit fix result for individual modules
|
|
122
124
|
|
|
123
125
|
TABLE FLAGS
|
|
124
126
|
--columns=<value> Specify columns to display, comma-separated.
|
|
@@ -157,7 +159,7 @@ Perform audits and find possible errors in the exported Contentstack data
|
|
|
157
159
|
|
|
158
160
|
```
|
|
159
161
|
USAGE
|
|
160
|
-
$ csdx cm:stacks:audit [-c <value>] [-d <value>] [--report-path <value>] [--modules
|
|
162
|
+
$ csdx cm:stacks:audit [-c <value>] [-d <value>] [--show-console-output] [--report-path <value>] [--modules
|
|
161
163
|
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules...] [--columns <value>]
|
|
162
164
|
[--sort <value>] [--filter <value>] [--csv] [--no-truncate] [--no-header] [--output csv|json|yaml]
|
|
163
165
|
|
|
@@ -168,8 +170,9 @@ FLAGS
|
|
|
168
170
|
--report-path=<value> Path to store the audit reports
|
|
169
171
|
|
|
170
172
|
COMMON FLAGS
|
|
171
|
-
-c, --config=<value>
|
|
172
|
-
-d, --data-dir=<value>
|
|
173
|
+
-c, --config=<value> Path of the external config
|
|
174
|
+
-d, --data-dir=<value> Path where the data is stored
|
|
175
|
+
--show-console-output Display the audit and audit fix result for individual modules
|
|
173
176
|
|
|
174
177
|
TABLE FLAGS
|
|
175
178
|
--columns=<value> Specify columns to display, comma-separated.
|
|
@@ -208,7 +211,7 @@ Perform audits and fix possible errors in the exported Contentstack data.
|
|
|
208
211
|
|
|
209
212
|
```
|
|
210
213
|
USAGE
|
|
211
|
-
$ csdx cm:stacks:audit:fix [-c <value>] [-d <value>] [--report-path <value>] [--modules
|
|
214
|
+
$ csdx cm:stacks:audit:fix [-c <value>] [-d <value>] [--show-console-output] [--report-path <value>] [--modules
|
|
212
215
|
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules...] [--copy-path <value>
|
|
213
216
|
--copy-dir] [--fix-only reference|global_field|json:rte|json:extension|blocks|group|content_types...] [--columns
|
|
214
217
|
<value>] [--sort <value>] [--filter <value>] [--csv] [--no-truncate] [--no-header] [--output csv|json|yaml]
|
|
@@ -224,8 +227,9 @@ FLAGS
|
|
|
224
227
|
--report-path=<value> Path to store the audit reports
|
|
225
228
|
|
|
226
229
|
COMMON FLAGS
|
|
227
|
-
-c, --config=<value>
|
|
228
|
-
-d, --data-dir=<value>
|
|
230
|
+
-c, --config=<value> Path of the external config
|
|
231
|
+
-d, --data-dir=<value> Path where the data is stored
|
|
232
|
+
--show-console-output Display the audit and audit fix result for individual modules
|
|
229
233
|
|
|
230
234
|
TABLE FLAGS
|
|
231
235
|
--columns=<value> Specify columns to display, comma-separated.
|
|
@@ -3,6 +3,7 @@ import { BaseCommand } from './base-command';
|
|
|
3
3
|
import { CommandNames, ContentTypeStruct } from './types';
|
|
4
4
|
export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseCommand> {
|
|
5
5
|
private currentCommand;
|
|
6
|
+
private readonly summaryDataToPrint;
|
|
6
7
|
get fixStatus(): {
|
|
7
8
|
fixStatus: {
|
|
8
9
|
minWidth: number;
|
|
@@ -82,7 +83,7 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
|
|
|
82
83
|
* reference name and the value represents additional information about the missing reference.
|
|
83
84
|
* @returns The function `prepareReport` returns a Promise that resolves to `void`.
|
|
84
85
|
*/
|
|
85
|
-
prepareReport(moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries | 'field-rules', listOfMissingRefs: Record<string, any>): Promise<void>;
|
|
86
|
+
prepareReport(moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries | 'field-rules' | 'Summary', listOfMissingRefs: Record<string, any>): Promise<void>;
|
|
86
87
|
/**
|
|
87
88
|
* The function `prepareCSV` takes a module name and a list of missing references, and generates a
|
|
88
89
|
* CSV file with the specified columns and filtered rows.
|
|
@@ -93,5 +94,6 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
|
|
|
93
94
|
* corresponding value is an array of objects that contain details about the missing reference.
|
|
94
95
|
* @returns The function `prepareCSV` returns a Promise that resolves to `void`.
|
|
95
96
|
*/
|
|
96
|
-
prepareCSV(moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries | 'field-rules', listOfMissingRefs: Record<string, any>): Promise<void>;
|
|
97
|
+
prepareCSV(moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries | 'field-rules' | 'Summary', listOfMissingRefs: Record<string, any>): Promise<void>;
|
|
98
|
+
getAffectedData(module: string, dataExported: Record<string, any>, listOfMissingRefs: Record<string, any>, isFixable?: boolean): void;
|
|
97
99
|
}
|
|
@@ -17,8 +17,11 @@ const messages_1 = require("./messages");
|
|
|
17
17
|
const base_command_1 = require("./base-command");
|
|
18
18
|
const modules_1 = require("./modules");
|
|
19
19
|
const types_1 = require("./types");
|
|
20
|
-
const custom_roles_1 = tslib_1.__importDefault(require("./modules/custom-roles"));
|
|
21
20
|
class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
this.summaryDataToPrint = [];
|
|
24
|
+
}
|
|
22
25
|
get fixStatus() {
|
|
23
26
|
return {
|
|
24
27
|
fixStatus: {
|
|
@@ -41,24 +44,35 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
41
44
|
await this.promptQueue();
|
|
42
45
|
await this.createBackUp();
|
|
43
46
|
this.sharedConfig.reportPath = (0, path_1.resolve)(this.flags['report-path'] || process.cwd(), 'audit-report');
|
|
44
|
-
const { missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow, missingSelectFeild, missingMandatoryFields, missingTitleFields, missingRefInCustomRoles, missingEnvLocalesInAssets, missingEnvLocalesInEntries, missingFieldRules, missingMultipleFields } = await this.scanAndFix();
|
|
45
|
-
this.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
47
|
+
const { missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow, missingSelectFeild, missingMandatoryFields, missingTitleFields, missingRefInCustomRoles, missingEnvLocalesInAssets, missingEnvLocalesInEntries, missingFieldRules, missingMultipleFields, } = await this.scanAndFix();
|
|
48
|
+
if (this.flags['show-console-output']) {
|
|
49
|
+
this.showOutputOnScreen([
|
|
50
|
+
{ module: 'Content types', missingRefs: missingCtRefs },
|
|
51
|
+
{ module: 'Global Fields', missingRefs: missingGfRefs },
|
|
52
|
+
{ module: 'Entries', missingRefs: missingEntryRefs },
|
|
53
|
+
]);
|
|
54
|
+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Extensions', missingRefs: missingCtRefsInExtensions }]);
|
|
55
|
+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Workflows', missingRefs: missingCtRefsInWorkflow }]);
|
|
56
|
+
this.showOutputOnScreenWorkflowsAndExtension([
|
|
57
|
+
{ module: 'Entries Select Field', missingRefs: missingSelectFeild },
|
|
58
|
+
]);
|
|
59
|
+
this.showOutputOnScreenWorkflowsAndExtension([
|
|
60
|
+
{ module: 'Entries Mandatory Field', missingRefs: missingMandatoryFields },
|
|
61
|
+
]);
|
|
62
|
+
this.showOutputOnScreenWorkflowsAndExtension([
|
|
63
|
+
{ module: 'Entries Title Field', missingRefs: missingTitleFields },
|
|
64
|
+
]);
|
|
65
|
+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Custom Roles', missingRefs: missingRefInCustomRoles }]);
|
|
66
|
+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Assets', missingRefs: missingEnvLocalesInAssets }]);
|
|
67
|
+
this.showOutputOnScreenWorkflowsAndExtension([
|
|
68
|
+
{ module: 'Entries Missing Locale and Environments', missingRefs: missingEnvLocalesInEntries },
|
|
69
|
+
]);
|
|
70
|
+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Field Rules', missingRefs: missingFieldRules }]);
|
|
71
|
+
this.showOutputOnScreenWorkflowsAndExtension([
|
|
72
|
+
{ module: 'Entries Changed Multiple Fields', missingRefs: missingMultipleFields },
|
|
73
|
+
]);
|
|
74
|
+
}
|
|
75
|
+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Summary', missingRefs: this.summaryDataToPrint }]);
|
|
62
76
|
if (!(0, isEmpty_1.default)(missingCtRefs) ||
|
|
63
77
|
!(0, isEmpty_1.default)(missingGfRefs) ||
|
|
64
78
|
!(0, isEmpty_1.default)(missingEntryRefs) ||
|
|
@@ -109,6 +123,14 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
109
123
|
var _a, _b, _c, _d, _e, _f;
|
|
110
124
|
let { ctSchema, gfSchema } = this.getCtAndGfSchema();
|
|
111
125
|
let missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow, missingSelectFeild, missingEntry, missingMandatoryFields, missingTitleFields, missingRefInCustomRoles, missingEnvLocalesInAssets, missingEnvLocalesInEntries, missingFieldRules, missingMultipleFields;
|
|
126
|
+
const constructorParam = {
|
|
127
|
+
ctSchema,
|
|
128
|
+
gfSchema,
|
|
129
|
+
log: this.log,
|
|
130
|
+
config: this.sharedConfig,
|
|
131
|
+
fix: this.currentCommand === 'cm:stacks:audit:fix',
|
|
132
|
+
};
|
|
133
|
+
let dataModuleWise = await new modules_1.ModuleDataReader((0, cloneDeep_1.default)(constructorParam)).run();
|
|
112
134
|
for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) {
|
|
113
135
|
(0, log_1.print)([
|
|
114
136
|
{
|
|
@@ -117,26 +139,22 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
117
139
|
message: this.$t(this.messages.AUDIT_START_SPINNER, { module }),
|
|
118
140
|
},
|
|
119
141
|
]);
|
|
120
|
-
|
|
121
|
-
ctSchema,
|
|
122
|
-
gfSchema,
|
|
123
|
-
log: this.log,
|
|
124
|
-
moduleName: module,
|
|
125
|
-
config: this.sharedConfig,
|
|
126
|
-
fix: this.currentCommand === 'cm:stacks:audit:fix',
|
|
127
|
-
};
|
|
142
|
+
constructorParam['moduleName'] = module;
|
|
128
143
|
switch (module) {
|
|
129
144
|
case 'assets':
|
|
130
145
|
missingEnvLocalesInAssets = await new modules_1.Assets((0, cloneDeep_1.default)(constructorParam)).run();
|
|
131
146
|
await this.prepareReport(module, missingEnvLocalesInAssets);
|
|
147
|
+
this.getAffectedData('assets', dataModuleWise['assets'], missingEnvLocalesInAssets);
|
|
132
148
|
break;
|
|
133
149
|
case 'content-types':
|
|
134
150
|
missingCtRefs = await new modules_1.ContentType((0, cloneDeep_1.default)(constructorParam)).run();
|
|
135
151
|
await this.prepareReport(module, missingCtRefs);
|
|
152
|
+
this.getAffectedData('content-types', dataModuleWise['content-types'], missingCtRefs);
|
|
136
153
|
break;
|
|
137
154
|
case 'global-fields':
|
|
138
155
|
missingGfRefs = await new modules_1.GlobalField((0, cloneDeep_1.default)(constructorParam)).run();
|
|
139
156
|
await this.prepareReport(module, missingGfRefs);
|
|
157
|
+
this.getAffectedData('global-fields', dataModuleWise['global-fields'], missingGfRefs);
|
|
140
158
|
break;
|
|
141
159
|
case 'entries':
|
|
142
160
|
missingEntry = await new modules_1.Entries((0, cloneDeep_1.default)(constructorParam)).run();
|
|
@@ -152,6 +170,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
152
170
|
await this.prepareReport('Entries_Title_feild', missingTitleFields);
|
|
153
171
|
await this.prepareReport('Entry_Missing_Locale_and_Env_in_Publish_Details', missingEnvLocalesInEntries);
|
|
154
172
|
await this.prepareReport('Entry_Multiple_Fields', missingMultipleFields);
|
|
173
|
+
this.getAffectedData('entries', dataModuleWise['entries'], missingEntry);
|
|
155
174
|
break;
|
|
156
175
|
case 'workflows':
|
|
157
176
|
missingCtRefsInWorkflow = await new modules_1.Workflows({
|
|
@@ -162,18 +181,22 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
162
181
|
fix: this.currentCommand === 'cm:stacks:audit:fix',
|
|
163
182
|
}).run();
|
|
164
183
|
await this.prepareReport(module, missingCtRefsInWorkflow);
|
|
184
|
+
this.getAffectedData('workflows', dataModuleWise['workflows'], missingCtRefsInWorkflow);
|
|
165
185
|
break;
|
|
166
186
|
case 'extensions':
|
|
167
187
|
missingCtRefsInExtensions = await new modules_1.Extensions((0, cloneDeep_1.default)(constructorParam)).run();
|
|
168
188
|
await this.prepareReport(module, missingCtRefsInExtensions);
|
|
189
|
+
this.getAffectedData('extensions', dataModuleWise['extensions'], missingCtRefsInExtensions);
|
|
169
190
|
break;
|
|
170
191
|
case 'custom-roles':
|
|
171
|
-
missingRefInCustomRoles = await new
|
|
192
|
+
missingRefInCustomRoles = await new modules_1.CustomRoles((0, cloneDeep_1.default)(constructorParam)).run();
|
|
172
193
|
await this.prepareReport(module, missingRefInCustomRoles);
|
|
194
|
+
this.getAffectedData('custom-roles', dataModuleWise['custom-roles'], missingRefInCustomRoles);
|
|
173
195
|
break;
|
|
174
196
|
case 'field-rules':
|
|
175
197
|
missingFieldRules = await new modules_1.FieldRule((0, cloneDeep_1.default)(constructorParam)).run();
|
|
176
198
|
await this.prepareReport(module, missingFieldRules);
|
|
199
|
+
this.getAffectedData('field-rules', dataModuleWise['content-types'], missingFieldRules);
|
|
177
200
|
break;
|
|
178
201
|
}
|
|
179
202
|
(0, log_1.print)([
|
|
@@ -189,6 +212,8 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
189
212
|
},
|
|
190
213
|
]);
|
|
191
214
|
}
|
|
215
|
+
this.prepareReport('Summary', this.summaryDataToPrint);
|
|
216
|
+
this.prepareCSV('Summary', this.summaryDataToPrint);
|
|
192
217
|
return {
|
|
193
218
|
missingCtRefs,
|
|
194
219
|
missingGfRefs,
|
|
@@ -202,7 +227,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
202
227
|
missingEnvLocalesInAssets,
|
|
203
228
|
missingEnvLocalesInEntries,
|
|
204
229
|
missingFieldRules,
|
|
205
|
-
missingMultipleFields
|
|
230
|
+
missingMultipleFields,
|
|
206
231
|
};
|
|
207
232
|
}
|
|
208
233
|
/**
|
|
@@ -331,14 +356,16 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
331
356
|
.map((key) => ({
|
|
332
357
|
value: key,
|
|
333
358
|
formatter: (cellValue) => {
|
|
334
|
-
if (key === 'fixStatus') {
|
|
359
|
+
if (key === 'fixStatus' || key === 'Fixable' || key === 'Fixed') {
|
|
335
360
|
return chalk_1.default.green(typeof cellValue === 'object' ? JSON.stringify(cellValue) : cellValue);
|
|
336
361
|
}
|
|
337
362
|
else if (key === 'content_types' ||
|
|
338
363
|
key === 'branches' ||
|
|
339
364
|
key === 'missingCTSelectFieldValues' ||
|
|
340
365
|
key === 'missingFieldUid' ||
|
|
341
|
-
key === 'action'
|
|
366
|
+
key === 'action' ||
|
|
367
|
+
key === 'Non-Fixable' ||
|
|
368
|
+
key === 'Not-Fixed') {
|
|
342
369
|
return chalk_1.default.red(typeof cellValue === 'object' ? JSON.stringify(cellValue) : cellValue);
|
|
343
370
|
}
|
|
344
371
|
else {
|
|
@@ -428,5 +455,55 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
428
455
|
});
|
|
429
456
|
}
|
|
430
457
|
}
|
|
458
|
+
getAffectedData(module, dataExported, listOfMissingRefs, isFixable = true) {
|
|
459
|
+
const result = Object.assign({ Module: module }, dataExported);
|
|
460
|
+
if (module === 'entries') {
|
|
461
|
+
const missingRefs = Object.entries(listOfMissingRefs);
|
|
462
|
+
const uidSet = new Set();
|
|
463
|
+
const nonFixable = new Set();
|
|
464
|
+
for (const [key, refs] of missingRefs) {
|
|
465
|
+
const uids = Object.keys(refs);
|
|
466
|
+
if (key === 'missingTitleFields' ||
|
|
467
|
+
(!this.sharedConfig.fixSelectField &&
|
|
468
|
+
key === 'missingSelectFeild' &&
|
|
469
|
+
this.currentCommand === 'cm:stacks:audit:fix')) {
|
|
470
|
+
uids.forEach((uid) => {
|
|
471
|
+
if (uidSet.has(uid)) {
|
|
472
|
+
uidSet.delete(uid);
|
|
473
|
+
nonFixable.add(uid);
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
nonFixable.add(uid);
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
uids.forEach((uid) => uidSet.add(uid));
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
result.Passed = dataExported.Total - (uidSet.size + nonFixable.size);
|
|
485
|
+
if (this.currentCommand === 'cm:stacks:audit:fix') {
|
|
486
|
+
result.Fixed = uidSet.size;
|
|
487
|
+
result['Not-Fixed'] = nonFixable.size;
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
result.Fixable = uidSet.size;
|
|
491
|
+
result['Non-Fixable'] = nonFixable.size;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
const missingCount = Object.keys(listOfMissingRefs).length;
|
|
496
|
+
result.Passed = dataExported.Total - missingCount;
|
|
497
|
+
if (this.currentCommand === 'cm:stacks:audit:fix') {
|
|
498
|
+
result.Fixed = missingCount > 0 && isFixable ? missingCount : 0;
|
|
499
|
+
result['Not-Fixed'] = missingCount > 0 && !isFixable ? missingCount : 0;
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
result.Fixable = missingCount > 0 && isFixable ? missingCount : 0;
|
|
503
|
+
result['Non-Fixable'] = missingCount > 0 && !isFixable ? missingCount : 0;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
this.summaryDataToPrint.push(result);
|
|
507
|
+
}
|
|
431
508
|
}
|
|
432
509
|
exports.AuditBaseCommand = AuditBaseCommand;
|
package/lib/base-command.js
CHANGED
|
@@ -101,4 +101,8 @@ BaseCommand.baseFlags = {
|
|
|
101
101
|
helpGroup: 'COMMON',
|
|
102
102
|
description: messages_1.commonMsg.DATA_DIR,
|
|
103
103
|
}),
|
|
104
|
+
'show-console-output': cli_utilities_1.Flags.boolean({
|
|
105
|
+
helpGroup: 'COMMON',
|
|
106
|
+
description: messages_1.commonMsg.SHOW_CONSOLE_OUTPUT,
|
|
107
|
+
}),
|
|
104
108
|
};
|
package/lib/config/index.d.ts
CHANGED
package/lib/config/index.js
CHANGED
|
@@ -15,6 +15,7 @@ const config = {
|
|
|
15
15
|
'field-rules',
|
|
16
16
|
],
|
|
17
17
|
'fix-fields': ['reference', 'global_field', 'json:rte', 'json:extension', 'blocks', 'group', 'content_types'],
|
|
18
|
+
'schema-fields-data-type': ['blocks', 'group', 'global_field'],
|
|
18
19
|
moduleConfig: {
|
|
19
20
|
'content-types': {
|
|
20
21
|
name: 'content type',
|
|
@@ -108,6 +109,13 @@ const config = {
|
|
|
108
109
|
'selectedValue',
|
|
109
110
|
'ct_uid',
|
|
110
111
|
'action',
|
|
112
|
+
"Module",
|
|
113
|
+
"Total",
|
|
114
|
+
"Fixable",
|
|
115
|
+
"Non-Fixable",
|
|
116
|
+
"Fixed",
|
|
117
|
+
"Not-Fixed",
|
|
118
|
+
"Passed",
|
|
111
119
|
],
|
|
112
120
|
ReportTitleForEntries: {
|
|
113
121
|
Entries_Select_feild: 'Entries_Select_feild',
|
|
@@ -123,7 +131,8 @@ const config = {
|
|
|
123
131
|
'Entries_Select_feild',
|
|
124
132
|
'Entry_Missing_Locale_and_Env_in_Publish_Details',
|
|
125
133
|
'field-rules',
|
|
126
|
-
'Entry_Multiple_Fields'
|
|
134
|
+
'Entry_Multiple_Fields',
|
|
135
|
+
'Summary'
|
|
127
136
|
],
|
|
128
137
|
fixSelectField: false,
|
|
129
138
|
};
|
package/lib/messages/index.d.ts
CHANGED
package/lib/messages/index.js
CHANGED
|
@@ -24,6 +24,7 @@ const commonMsg = {
|
|
|
24
24
|
EXTENSION_FIX_CONFIRMATION: `Would you like to overwrite existing file?`,
|
|
25
25
|
WF_BRANCH_REMOVAL: `Removing the branch '{branch} from workflow with UID {uid} and name {name} will be removed.'`,
|
|
26
26
|
CR_BRANCH_REMOVAL: `Removing the branch '{branch} from custom role with UID {uid} and name {name} will be removed.'`,
|
|
27
|
+
SHOW_CONSOLE_OUTPUT: `Display the audit and audit fix result for individual modules`,
|
|
27
28
|
};
|
|
28
29
|
exports.commonMsg = commonMsg;
|
|
29
30
|
const auditMsg = {
|
|
@@ -381,9 +381,11 @@ class ContentType {
|
|
|
381
381
|
.filter((val) => {
|
|
382
382
|
if (this.config.skipFieldTypes.includes(val === null || val === void 0 ? void 0 : val.data_type))
|
|
383
383
|
return true;
|
|
384
|
-
if ((val === null || val === void 0 ? void 0 : val.schema) &&
|
|
384
|
+
if ((val === null || val === void 0 ? void 0 : val.schema) &&
|
|
385
|
+
(0, isEmpty_1.default)(val === null || val === void 0 ? void 0 : val.schema) &&
|
|
386
|
+
(!(val === null || val === void 0 ? void 0 : val.data_type) || this.config['schema-fields-data-type'].includes(val.data_type)))
|
|
385
387
|
return false;
|
|
386
|
-
if ((val === null || val === void 0 ? void 0 : val.reference_to) && (0, isEmpty_1.default)(val === null || val === void 0 ? void 0 : val.reference_to))
|
|
388
|
+
if ((val === null || val === void 0 ? void 0 : val.reference_to) && (0, isEmpty_1.default)(val === null || val === void 0 ? void 0 : val.reference_to) && val.data_type === 'reference')
|
|
387
389
|
return false;
|
|
388
390
|
return !!val;
|
|
389
391
|
});
|
package/lib/modules/index.d.ts
CHANGED
|
@@ -6,4 +6,5 @@ import Extensions from './extensions';
|
|
|
6
6
|
import CustomRoles from './custom-roles';
|
|
7
7
|
import Assets from './assets';
|
|
8
8
|
import FieldRule from './field_rules';
|
|
9
|
-
|
|
9
|
+
import ModuleDataReader from './modulesData';
|
|
10
|
+
export { Entries, GlobalField, ContentType, Workflows, Extensions, Assets, CustomRoles, FieldRule, ModuleDataReader };
|
package/lib/modules/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FieldRule = exports.CustomRoles = exports.Assets = exports.Extensions = exports.Workflows = exports.ContentType = exports.GlobalField = exports.Entries = void 0;
|
|
3
|
+
exports.ModuleDataReader = exports.FieldRule = exports.CustomRoles = exports.Assets = exports.Extensions = exports.Workflows = exports.ContentType = exports.GlobalField = exports.Entries = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const entries_1 = tslib_1.__importDefault(require("./entries"));
|
|
6
6
|
exports.Entries = entries_1.default;
|
|
@@ -18,3 +18,5 @@ const assets_1 = tslib_1.__importDefault(require("./assets"));
|
|
|
18
18
|
exports.Assets = assets_1.default;
|
|
19
19
|
const field_rules_1 = tslib_1.__importDefault(require("./field_rules"));
|
|
20
20
|
exports.FieldRule = field_rules_1.default;
|
|
21
|
+
const modulesData_1 = tslib_1.__importDefault(require("./modulesData"));
|
|
22
|
+
exports.ModuleDataReader = modulesData_1.default;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { LogFn, ConfigType, ContentTypeStruct, CtConstructorParam, ModuleConstructorParam } from '../types';
|
|
2
|
+
export default class ModuleDataReader {
|
|
3
|
+
log: LogFn;
|
|
4
|
+
config: ConfigType;
|
|
5
|
+
folderPath: string;
|
|
6
|
+
assets: Record<string, any>;
|
|
7
|
+
locales: any[];
|
|
8
|
+
gfSchema: ContentTypeStruct[];
|
|
9
|
+
ctSchema: ContentTypeStruct[];
|
|
10
|
+
environments: string[];
|
|
11
|
+
auditData: Record<string, unknown>;
|
|
12
|
+
protected schema: ContentTypeStruct[];
|
|
13
|
+
constructor({ log, config, ctSchema, gfSchema }: ModuleConstructorParam & CtConstructorParam);
|
|
14
|
+
getModuleItemCount(moduleName: string): Promise<number>;
|
|
15
|
+
readUsingFsModule(path: string): Promise<Record<string, any>>;
|
|
16
|
+
readEntryAssetsModule(basePath: string, module: string): Promise<number>;
|
|
17
|
+
run(): Promise<Object>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path_1 = require("path");
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
6
|
+
const lodash_1 = require("lodash");
|
|
7
|
+
class ModuleDataReader {
|
|
8
|
+
constructor({ log, config, ctSchema, gfSchema }) {
|
|
9
|
+
this.locales = [];
|
|
10
|
+
this.environments = [];
|
|
11
|
+
this.auditData = {};
|
|
12
|
+
this.schema = [];
|
|
13
|
+
this.log = log;
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.ctSchema = ctSchema;
|
|
16
|
+
this.gfSchema = gfSchema;
|
|
17
|
+
this.folderPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(config.basePath));
|
|
18
|
+
}
|
|
19
|
+
async getModuleItemCount(moduleName) {
|
|
20
|
+
let count = 0;
|
|
21
|
+
switch (moduleName) {
|
|
22
|
+
case "content-types":
|
|
23
|
+
count = this.ctSchema.length;
|
|
24
|
+
break;
|
|
25
|
+
case 'global-fields':
|
|
26
|
+
count = this.gfSchema.length;
|
|
27
|
+
break;
|
|
28
|
+
case 'assets':
|
|
29
|
+
count = await this.readEntryAssetsModule((0, path_1.join)(this.folderPath, 'assets'), 'assets') || 0;
|
|
30
|
+
break;
|
|
31
|
+
case 'entries':
|
|
32
|
+
{
|
|
33
|
+
const localesFolderPath = (0, path_1.resolve)(this.config.basePath, this.config.moduleConfig.locales.dirName);
|
|
34
|
+
const localesPath = (0, path_1.join)(localesFolderPath, this.config.moduleConfig.locales.fileName);
|
|
35
|
+
const masterLocalesPath = (0, path_1.join)(localesFolderPath, 'master-locale.json');
|
|
36
|
+
this.locales = (0, lodash_1.values)(await this.readUsingFsModule(masterLocalesPath));
|
|
37
|
+
if ((0, fs_1.existsSync)(localesPath)) {
|
|
38
|
+
this.locales.push(...(0, lodash_1.values)(JSON.parse((0, fs_1.readFileSync)(localesPath, 'utf8'))));
|
|
39
|
+
}
|
|
40
|
+
for (const { code } of this.locales) {
|
|
41
|
+
for (const ctSchema of this.ctSchema) {
|
|
42
|
+
const basePath = (0, path_1.join)(this.folderPath, 'entries', ctSchema.uid, code);
|
|
43
|
+
count = count + await this.readEntryAssetsModule(basePath, 'index') || 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
case 'custom-roles':
|
|
49
|
+
case 'extensions':
|
|
50
|
+
case 'workflows':
|
|
51
|
+
count = (0, lodash_1.keys)(await (this.readUsingFsModule((0, path_1.resolve)(this.folderPath, (0, cli_utilities_1.sanitizePath)(this.config.moduleConfig[moduleName].dirName), (0, cli_utilities_1.sanitizePath)(this.config.moduleConfig[moduleName].fileName))))).length;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
return count;
|
|
55
|
+
}
|
|
56
|
+
async readUsingFsModule(path) {
|
|
57
|
+
const data = (0, fs_1.existsSync)(path) ? (JSON.parse((0, fs_1.readFileSync)(path, 'utf-8'))) : [];
|
|
58
|
+
return data;
|
|
59
|
+
}
|
|
60
|
+
async readEntryAssetsModule(basePath, module) {
|
|
61
|
+
let fsUtility = new cli_utilities_1.FsUtility({ basePath, indexFileName: `${module}.json` });
|
|
62
|
+
let indexer = fsUtility.indexFileContent;
|
|
63
|
+
let count = 0;
|
|
64
|
+
for (const _ in indexer) {
|
|
65
|
+
const entries = (await fsUtility.readChunkFiles.next());
|
|
66
|
+
count = count + Object.keys(entries).length;
|
|
67
|
+
}
|
|
68
|
+
return count;
|
|
69
|
+
}
|
|
70
|
+
async run() {
|
|
71
|
+
await Promise.allSettled(Object.keys(this.config.moduleConfig).map(async (module) => {
|
|
72
|
+
this.auditData[module] = { Total: await this.getModuleItemCount(module) };
|
|
73
|
+
}));
|
|
74
|
+
return this.auditData;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.default = ModuleDataReader;
|
|
@@ -121,7 +121,14 @@ declare enum OutputColumn {
|
|
|
121
121
|
'Content_type_uid' = "ct_uid",
|
|
122
122
|
'action' = "action",
|
|
123
123
|
'field_uid' = "field_uid",
|
|
124
|
-
'multiple' = "multiple"
|
|
124
|
+
'multiple' = "multiple",
|
|
125
|
+
Module = "Module",
|
|
126
|
+
"Total" = "Total",
|
|
127
|
+
"Passed" = "Passed",
|
|
128
|
+
"Fixable" = "Fixable",
|
|
129
|
+
"Non-Fixable" = "Non-Fixable",
|
|
130
|
+
"Fixed" = "Fixed",
|
|
131
|
+
"Not-Fixed" = "Not-Fixed"
|
|
125
132
|
}
|
|
126
133
|
export { CtConstructorParam, ContentTypeStruct, ModuleConstructorParam, ReferenceFieldDataType, GlobalFieldDataType, ExtensionOrAppFieldDataType, JsonRTEFieldDataType, GroupFieldDataType, ModularBlocksDataType, RefErrorReturnType, ModularBlocksSchemaTypes, ModularBlockType, OutputColumn, ContentTypeSchemaType, GlobalFieldSchemaTypes, WorkflowExtensionsRefErrorReturnType, SelectFeildStruct, FieldRuleStruct, };
|
|
127
134
|
type FieldRuleStruct = {
|
|
@@ -35,4 +35,11 @@ var OutputColumn;
|
|
|
35
35
|
OutputColumn["action"] = "action";
|
|
36
36
|
OutputColumn["field_uid"] = "field_uid";
|
|
37
37
|
OutputColumn["multiple"] = "multiple";
|
|
38
|
+
OutputColumn["Module"] = "Module";
|
|
39
|
+
OutputColumn["Total"] = "Total";
|
|
40
|
+
OutputColumn["Passed"] = "Passed";
|
|
41
|
+
OutputColumn["Fixable"] = "Fixable";
|
|
42
|
+
OutputColumn["Non-Fixable"] = "Non-Fixable";
|
|
43
|
+
OutputColumn["Fixed"] = "Fixed";
|
|
44
|
+
OutputColumn["Not-Fixed"] = "Not-Fixed";
|
|
38
45
|
})(OutputColumn || (exports.OutputColumn = OutputColumn = {}));
|
package/oclif.manifest.json
CHANGED
|
@@ -34,6 +34,13 @@
|
|
|
34
34
|
"multiple": false,
|
|
35
35
|
"type": "option"
|
|
36
36
|
},
|
|
37
|
+
"show-console-output": {
|
|
38
|
+
"description": "Display the audit and audit fix result for individual modules",
|
|
39
|
+
"helpGroup": "COMMON",
|
|
40
|
+
"name": "show-console-output",
|
|
41
|
+
"allowNo": false,
|
|
42
|
+
"type": "boolean"
|
|
43
|
+
},
|
|
37
44
|
"report-path": {
|
|
38
45
|
"description": "Path to store the audit reports",
|
|
39
46
|
"name": "report-path",
|
|
@@ -222,6 +229,13 @@
|
|
|
222
229
|
"multiple": false,
|
|
223
230
|
"type": "option"
|
|
224
231
|
},
|
|
232
|
+
"show-console-output": {
|
|
233
|
+
"description": "Display the audit and audit fix result for individual modules",
|
|
234
|
+
"helpGroup": "COMMON",
|
|
235
|
+
"name": "show-console-output",
|
|
236
|
+
"allowNo": false,
|
|
237
|
+
"type": "boolean"
|
|
238
|
+
},
|
|
225
239
|
"report-path": {
|
|
226
240
|
"description": "Path to store the audit reports",
|
|
227
241
|
"name": "report-path",
|
|
@@ -330,5 +344,5 @@
|
|
|
330
344
|
]
|
|
331
345
|
}
|
|
332
346
|
},
|
|
333
|
-
"version": "1.
|
|
347
|
+
"version": "1.12.1"
|
|
334
348
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-audit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.1",
|
|
4
4
|
"description": "Contentstack audit plugin",
|
|
5
5
|
"author": "Contentstack CLI",
|
|
6
6
|
"homepage": "https://github.com/contentstack/cli",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@contentstack/cli-command": "~1.5.0",
|
|
22
|
-
"@oclif/plugin-help": "^6.2.
|
|
22
|
+
"@oclif/plugin-help": "^6.2.27",
|
|
23
23
|
"@contentstack/cli-utilities": "~1.11.0",
|
|
24
|
-
"@oclif/plugin-plugins": "^5.4.
|
|
24
|
+
"@oclif/plugin-plugins": "^5.4.36",
|
|
25
25
|
"chalk": "^4.1.2",
|
|
26
26
|
"fast-csv": "^4.3.6",
|
|
27
27
|
"fs-extra": "^11.3.0",
|
|
@@ -30,23 +30,23 @@
|
|
|
30
30
|
"winston": "^3.17.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@oclif/test": "^4.1.
|
|
33
|
+
"@oclif/test": "^4.1.12",
|
|
34
34
|
"@types/chai": "^4.3.20",
|
|
35
35
|
"@types/fs-extra": "^11.0.4",
|
|
36
36
|
"@types/mocha": "^10.0.10",
|
|
37
|
-
"@types/node": "^20.17.
|
|
37
|
+
"@types/node": "^20.17.30",
|
|
38
38
|
"@types/uuid": "^9.0.8",
|
|
39
39
|
"chai": "^4.5.0",
|
|
40
40
|
"eslint": "^8.57.1",
|
|
41
|
-
"eslint-config-oclif": "^6.0.
|
|
41
|
+
"eslint-config-oclif": "^6.0.42",
|
|
42
42
|
"eslint-config-oclif-typescript": "^3.1.14",
|
|
43
43
|
"mocha": "^10.8.2",
|
|
44
44
|
"nyc": "^15.1.0",
|
|
45
|
-
"oclif": "^4.17.
|
|
46
|
-
"shx": "^0.
|
|
45
|
+
"oclif": "^4.17.43",
|
|
46
|
+
"shx": "^0.4.0",
|
|
47
47
|
"sinon": "^19.0.5",
|
|
48
48
|
"ts-node": "^10.9.2",
|
|
49
|
-
"typescript": "^5.
|
|
49
|
+
"typescript": "^5.8.3"
|
|
50
50
|
},
|
|
51
51
|
"oclif": {
|
|
52
52
|
"bin": "csdx",
|