@contentstack/cli-audit 1.5.4 → 1.6.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 +16 -34
- package/bin/dev.js +6 -0
- package/bin/run.js +7 -0
- package/lib/audit-base-command.d.ts +4 -2
- package/lib/audit-base-command.js +34 -9
- package/lib/config/index.d.ts +5 -0
- package/lib/config/index.js +22 -0
- package/lib/messages/index.d.ts +2 -0
- package/lib/messages/index.js +2 -0
- package/lib/modules/entries.d.ts +60 -2
- package/lib/modules/entries.js +252 -5
- package/lib/types/content-types.d.ts +24 -7
- package/lib/types/content-types.js +5 -0
- package/lib/types/entries.d.ts +9 -2
- package/oclif.manifest.json +1 -33
- package/package.json +4 -4
- package/bin/dev +0 -5
- package/bin/run +0 -5
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.6.1 linux-x64 node-v18.20.2
|
|
23
23
|
$ csdx --help [COMMAND]
|
|
24
24
|
USAGE
|
|
25
25
|
$ csdx COMMAND
|
|
@@ -52,19 +52,14 @@ Perform audits and find possible errors in the exported Contentstack data
|
|
|
52
52
|
|
|
53
53
|
```
|
|
54
54
|
USAGE
|
|
55
|
-
$ csdx audit [
|
|
56
|
-
|
|
57
|
-
[--csv | --no-truncate]
|
|
55
|
+
$ csdx audit [--report-path <value>] [--modules content-types|global-fields|entries|extensions|workflows]
|
|
56
|
+
[--columns <value> | ] [--sort <value>] [--filter <value>] [--csv | --no-truncate]
|
|
58
57
|
|
|
59
58
|
FLAGS
|
|
60
59
|
--modules=<option>... Provide the list of modules to be audited
|
|
61
60
|
<options: content-types|global-fields|entries|extensions|workflows>
|
|
62
61
|
--report-path=<value> Path to store the audit reports
|
|
63
62
|
|
|
64
|
-
COMMON FLAGS
|
|
65
|
-
-c, --config=<value> Path of the external config
|
|
66
|
-
-d, --data-dir=<value> Path where the data is stored
|
|
67
|
-
|
|
68
63
|
TABLE FLAGS
|
|
69
64
|
--columns=<value> Show only the specified columns (comma-separated)
|
|
70
65
|
--csv The output is in the CSV format [alias: --output=csv]
|
|
@@ -97,8 +92,8 @@ Perform audits and fix possible errors in the exported Contentstack data.
|
|
|
97
92
|
|
|
98
93
|
```
|
|
99
94
|
USAGE
|
|
100
|
-
$ csdx audit:fix [
|
|
101
|
-
|
|
95
|
+
$ csdx audit:fix [--report-path <value>] [--modules content-types|global-fields|entries|extensions|workflows]
|
|
96
|
+
[--copy-path <value> --copy-dir] [--fix-only
|
|
102
97
|
reference|global_field|json:rte|json:extension|blocks|group|content_types] [--columns <value> | ] [--sort <value>]
|
|
103
98
|
[--filter <value>] [--csv | --no-truncate]
|
|
104
99
|
|
|
@@ -111,10 +106,6 @@ FLAGS
|
|
|
111
106
|
<options: content-types|global-fields|entries|extensions|workflows>
|
|
112
107
|
--report-path=<value> Path to store the audit reports
|
|
113
108
|
|
|
114
|
-
COMMON FLAGS
|
|
115
|
-
-c, --config=<value> Path of the external config
|
|
116
|
-
-d, --data-dir=<value> Path where the data is stored
|
|
117
|
-
|
|
118
109
|
TABLE FLAGS
|
|
119
110
|
--columns=<value> Show only the specified columns (comma-separated)
|
|
120
111
|
--csv The output is in the CSV format [alias: --output=csv]
|
|
@@ -149,19 +140,14 @@ Perform audits and find possible errors in the exported Contentstack data
|
|
|
149
140
|
|
|
150
141
|
```
|
|
151
142
|
USAGE
|
|
152
|
-
$ csdx cm:stacks:audit [
|
|
153
|
-
|
|
154
|
-
[--csv | --no-truncate]
|
|
143
|
+
$ csdx cm:stacks:audit [--report-path <value>] [--modules content-types|global-fields|entries|extensions|workflows]
|
|
144
|
+
[--columns <value> | ] [--sort <value>] [--filter <value>] [--csv | --no-truncate]
|
|
155
145
|
|
|
156
146
|
FLAGS
|
|
157
147
|
--modules=<option>... Provide the list of modules to be audited
|
|
158
148
|
<options: content-types|global-fields|entries|extensions|workflows>
|
|
159
149
|
--report-path=<value> Path to store the audit reports
|
|
160
150
|
|
|
161
|
-
COMMON FLAGS
|
|
162
|
-
-c, --config=<value> Path of the external config
|
|
163
|
-
-d, --data-dir=<value> Path where the data is stored
|
|
164
|
-
|
|
165
151
|
TABLE FLAGS
|
|
166
152
|
--columns=<value> Show only the specified columns (comma-separated)
|
|
167
153
|
--csv The output is in the CSV format [alias: --output=csv]
|
|
@@ -196,8 +182,8 @@ Perform audits and fix possible errors in the exported Contentstack data.
|
|
|
196
182
|
|
|
197
183
|
```
|
|
198
184
|
USAGE
|
|
199
|
-
$ csdx cm:stacks:audit:fix [
|
|
200
|
-
|
|
185
|
+
$ csdx cm:stacks:audit:fix [--report-path <value>] [--modules content-types|global-fields|entries|extensions|workflows]
|
|
186
|
+
[--copy-path <value> --copy-dir] [--fix-only
|
|
201
187
|
reference|global_field|json:rte|json:extension|blocks|group|content_types] [--columns <value> | ] [--sort <value>]
|
|
202
188
|
[--filter <value>] [--csv | --no-truncate]
|
|
203
189
|
|
|
@@ -210,10 +196,6 @@ FLAGS
|
|
|
210
196
|
<options: content-types|global-fields|entries|extensions|workflows>
|
|
211
197
|
--report-path=<value> Path to store the audit reports
|
|
212
198
|
|
|
213
|
-
COMMON FLAGS
|
|
214
|
-
-c, --config=<value> Path of the external config
|
|
215
|
-
-d, --data-dir=<value> Path where the data is stored
|
|
216
|
-
|
|
217
199
|
TABLE FLAGS
|
|
218
200
|
--columns=<value> Show only the specified columns (comma-separated)
|
|
219
201
|
--csv The output is in the CSV format [alias: --output=csv]
|
|
@@ -285,7 +267,7 @@ EXAMPLES
|
|
|
285
267
|
$ csdx plugins
|
|
286
268
|
```
|
|
287
269
|
|
|
288
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.
|
|
270
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.21/src/commands/plugins/index.ts)_
|
|
289
271
|
|
|
290
272
|
## `csdx plugins:add PLUGIN`
|
|
291
273
|
|
|
@@ -359,7 +341,7 @@ EXAMPLES
|
|
|
359
341
|
$ csdx plugins:inspect myplugin
|
|
360
342
|
```
|
|
361
343
|
|
|
362
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.
|
|
344
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.21/src/commands/plugins/inspect.ts)_
|
|
363
345
|
|
|
364
346
|
## `csdx plugins:install PLUGIN`
|
|
365
347
|
|
|
@@ -408,7 +390,7 @@ EXAMPLES
|
|
|
408
390
|
$ csdx plugins:install someuser/someplugin
|
|
409
391
|
```
|
|
410
392
|
|
|
411
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.
|
|
393
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.21/src/commands/plugins/install.ts)_
|
|
412
394
|
|
|
413
395
|
## `csdx plugins:link PATH`
|
|
414
396
|
|
|
@@ -438,7 +420,7 @@ EXAMPLES
|
|
|
438
420
|
$ csdx plugins:link myplugin
|
|
439
421
|
```
|
|
440
422
|
|
|
441
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.
|
|
423
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.21/src/commands/plugins/link.ts)_
|
|
442
424
|
|
|
443
425
|
## `csdx plugins:remove [PLUGIN]`
|
|
444
426
|
|
|
@@ -479,7 +461,7 @@ FLAGS
|
|
|
479
461
|
--reinstall Reinstall all plugins after uninstalling.
|
|
480
462
|
```
|
|
481
463
|
|
|
482
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.
|
|
464
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.21/src/commands/plugins/reset.ts)_
|
|
483
465
|
|
|
484
466
|
## `csdx plugins:uninstall [PLUGIN]`
|
|
485
467
|
|
|
@@ -507,7 +489,7 @@ EXAMPLES
|
|
|
507
489
|
$ csdx plugins:uninstall myplugin
|
|
508
490
|
```
|
|
509
491
|
|
|
510
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.
|
|
492
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.21/src/commands/plugins/uninstall.ts)_
|
|
511
493
|
|
|
512
494
|
## `csdx plugins:unlink [PLUGIN]`
|
|
513
495
|
|
|
@@ -551,5 +533,5 @@ DESCRIPTION
|
|
|
551
533
|
Update installed plugins.
|
|
552
534
|
```
|
|
553
535
|
|
|
554
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.
|
|
536
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.21/src/commands/plugins/update.ts)_
|
|
555
537
|
<!-- commandsstop -->
|
package/bin/dev.js
ADDED
package/bin/run.js
ADDED
|
@@ -29,6 +29,8 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
|
|
|
29
29
|
missingEntryRefs: Record<string, any> | undefined;
|
|
30
30
|
missingCtRefsInExtensions: {} | undefined;
|
|
31
31
|
missingCtRefsInWorkflow: {} | undefined;
|
|
32
|
+
missingSelectFeild: Record<string, any> | undefined;
|
|
33
|
+
missingMandatoryFields: Record<string, any> | undefined;
|
|
32
34
|
}>;
|
|
33
35
|
/**
|
|
34
36
|
* The `promptQueue` function prompts the user to enter a data directory path if the `data-dir` flag
|
|
@@ -74,7 +76,7 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
|
|
|
74
76
|
* reference name and the value represents additional information about the missing reference.
|
|
75
77
|
* @returns The function `prepareReport` returns a Promise that resolves to `void`.
|
|
76
78
|
*/
|
|
77
|
-
prepareReport(moduleName: keyof typeof config.moduleConfig, listOfMissingRefs: Record<string, any>): Promise<void>;
|
|
79
|
+
prepareReport(moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries, listOfMissingRefs: Record<string, any>): Promise<void>;
|
|
78
80
|
/**
|
|
79
81
|
* The function `prepareCSV` takes a module name and a list of missing references, and generates a
|
|
80
82
|
* CSV file with the specified columns and filtered rows.
|
|
@@ -85,5 +87,5 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
|
|
|
85
87
|
* corresponding value is an array of objects that contain details about the missing reference.
|
|
86
88
|
* @returns The function `prepareCSV` returns a Promise that resolves to `void`.
|
|
87
89
|
*/
|
|
88
|
-
prepareCSV(moduleName: keyof typeof config.moduleConfig, listOfMissingRefs: Record<string, any>): Promise<void>;
|
|
90
|
+
prepareCSV(moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries, listOfMissingRefs: Record<string, any>): Promise<void>;
|
|
89
91
|
}
|
|
@@ -11,6 +11,7 @@ const path_1 = require("path");
|
|
|
11
11
|
const cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
|
|
12
12
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
13
13
|
const fs_1 = require("fs");
|
|
14
|
+
const config_1 = tslib_1.__importDefault(require("./config"));
|
|
14
15
|
const log_1 = require("./util/log");
|
|
15
16
|
const messages_1 = require("./messages");
|
|
16
17
|
const base_command_1 = require("./base-command");
|
|
@@ -39,7 +40,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
39
40
|
await this.promptQueue();
|
|
40
41
|
await this.createBackUp();
|
|
41
42
|
this.sharedConfig.reportPath = (0, path_1.resolve)(this.flags['report-path'] || process.cwd(), 'audit-report');
|
|
42
|
-
const { missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow } = await this.scanAndFix();
|
|
43
|
+
const { missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow, missingSelectFeild, missingMandatoryFields, } = await this.scanAndFix();
|
|
43
44
|
this.showOutputOnScreen([
|
|
44
45
|
{ module: 'Content types', missingRefs: missingCtRefs },
|
|
45
46
|
{ module: 'Global Fields', missingRefs: missingGfRefs },
|
|
@@ -47,11 +48,16 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
47
48
|
]);
|
|
48
49
|
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Extensions', missingRefs: missingCtRefsInExtensions }]);
|
|
49
50
|
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Workflows', missingRefs: missingCtRefsInWorkflow }]);
|
|
51
|
+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Entries Select Field', missingRefs: missingSelectFeild }]);
|
|
52
|
+
this.showOutputOnScreenWorkflowsAndExtension([
|
|
53
|
+
{ module: 'Entries Mandatory Field', missingRefs: missingMandatoryFields },
|
|
54
|
+
]);
|
|
50
55
|
if (!(0, isEmpty_1.default)(missingCtRefs) ||
|
|
51
56
|
!(0, isEmpty_1.default)(missingGfRefs) ||
|
|
52
57
|
!(0, isEmpty_1.default)(missingEntryRefs) ||
|
|
53
58
|
!(0, isEmpty_1.default)(missingCtRefsInWorkflow) ||
|
|
54
|
-
!(0, isEmpty_1.default)(missingCtRefsInExtensions)
|
|
59
|
+
!(0, isEmpty_1.default)(missingCtRefsInExtensions) ||
|
|
60
|
+
!(0, isEmpty_1.default)(missingSelectFeild)) {
|
|
55
61
|
if (this.currentCommand === 'cm:stacks:audit') {
|
|
56
62
|
this.log(this.$t(messages_1.auditMsg.FINAL_REPORT_PATH, { path: this.sharedConfig.reportPath }), 'warn');
|
|
57
63
|
}
|
|
@@ -73,7 +79,8 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
73
79
|
!(0, isEmpty_1.default)(missingGfRefs) ||
|
|
74
80
|
!(0, isEmpty_1.default)(missingEntryRefs) ||
|
|
75
81
|
!(0, isEmpty_1.default)(missingCtRefsInWorkflow) ||
|
|
76
|
-
!(0, isEmpty_1.default)(missingCtRefsInExtensions)
|
|
82
|
+
!(0, isEmpty_1.default)(missingCtRefsInExtensions) ||
|
|
83
|
+
!(0, isEmpty_1.default)(missingSelectFeild));
|
|
77
84
|
}
|
|
78
85
|
/**
|
|
79
86
|
* The `scan` function performs an audit on different modules (content-types, global-fields, and
|
|
@@ -82,8 +89,9 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
82
89
|
* and `missingEntryRefs`.
|
|
83
90
|
*/
|
|
84
91
|
async scanAndFix() {
|
|
92
|
+
var _a, _b, _c;
|
|
85
93
|
let { ctSchema, gfSchema } = this.getCtAndGfSchema();
|
|
86
|
-
let missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow;
|
|
94
|
+
let missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow, missingSelectFeild, missingEntry, missingMandatoryFields;
|
|
87
95
|
for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) {
|
|
88
96
|
(0, log_1.print)([
|
|
89
97
|
{
|
|
@@ -110,8 +118,13 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
110
118
|
await this.prepareReport(module, missingGfRefs);
|
|
111
119
|
break;
|
|
112
120
|
case 'entries':
|
|
113
|
-
|
|
121
|
+
missingEntry = await new modules_1.Entries((0, cloneDeep_1.default)(constructorParam)).run();
|
|
122
|
+
missingEntryRefs = (_a = missingEntry.missingEntryRefs) !== null && _a !== void 0 ? _a : {};
|
|
123
|
+
missingSelectFeild = (_b = missingEntry.missingSelectFeild) !== null && _b !== void 0 ? _b : {};
|
|
124
|
+
missingMandatoryFields = (_c = missingEntry.missingMandatoryFields) !== null && _c !== void 0 ? _c : {};
|
|
114
125
|
await this.prepareReport(module, missingEntryRefs);
|
|
126
|
+
await this.prepareReport(`Entries_Select_feild`, missingSelectFeild);
|
|
127
|
+
await this.prepareReport('Entries_Mandatory_feild', missingMandatoryFields);
|
|
115
128
|
break;
|
|
116
129
|
case 'workflows':
|
|
117
130
|
missingCtRefsInWorkflow = await new modules_1.Workflows({
|
|
@@ -141,7 +154,15 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
141
154
|
},
|
|
142
155
|
]);
|
|
143
156
|
}
|
|
144
|
-
return {
|
|
157
|
+
return {
|
|
158
|
+
missingCtRefs,
|
|
159
|
+
missingGfRefs,
|
|
160
|
+
missingEntryRefs,
|
|
161
|
+
missingCtRefsInExtensions,
|
|
162
|
+
missingCtRefsInWorkflow,
|
|
163
|
+
missingSelectFeild,
|
|
164
|
+
missingMandatoryFields,
|
|
165
|
+
};
|
|
145
166
|
}
|
|
146
167
|
/**
|
|
147
168
|
* The `promptQueue` function prompts the user to enter a data directory path if the `data-dir` flag
|
|
@@ -241,15 +262,16 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
241
262
|
return;
|
|
242
263
|
}
|
|
243
264
|
this.log(''); // Adding a new line
|
|
244
|
-
for (
|
|
265
|
+
for (let { module, missingRefs } of allMissingRefs) {
|
|
245
266
|
if ((0, isEmpty_1.default)(missingRefs)) {
|
|
246
267
|
continue;
|
|
247
268
|
}
|
|
248
269
|
(0, log_1.print)([{ bold: true, color: 'cyan', message: ` ${module}` }]);
|
|
249
270
|
const tableValues = Object.values(missingRefs).flat();
|
|
271
|
+
missingRefs = Object.values(missingRefs).flat();
|
|
250
272
|
const tableKeys = Object.keys(missingRefs[0]);
|
|
251
273
|
const arrayOfObjects = tableKeys.map((key) => {
|
|
252
|
-
if (
|
|
274
|
+
if (config_1.default.OutputTableKeys.includes(key)) {
|
|
253
275
|
return {
|
|
254
276
|
[key]: {
|
|
255
277
|
minWidth: 7,
|
|
@@ -258,7 +280,10 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
258
280
|
if (key === 'fixStatus') {
|
|
259
281
|
return chalk_1.default.green(typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]);
|
|
260
282
|
}
|
|
261
|
-
else if (key === 'content_types' ||
|
|
283
|
+
else if (key === 'content_types' ||
|
|
284
|
+
key === 'branches' ||
|
|
285
|
+
key === 'missingCTSelectFieldValues' ||
|
|
286
|
+
key === 'missingFieldUid') {
|
|
262
287
|
return chalk_1.default.red(typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]);
|
|
263
288
|
}
|
|
264
289
|
else {
|
package/lib/config/index.d.ts
CHANGED
package/lib/config/index.js
CHANGED
|
@@ -56,5 +56,27 @@ const config = {
|
|
|
56
56
|
'publish_details',
|
|
57
57
|
],
|
|
58
58
|
},
|
|
59
|
+
//These keys will be used output the modules with issues and fixes on console
|
|
60
|
+
OutputTableKeys: [
|
|
61
|
+
'title',
|
|
62
|
+
'name',
|
|
63
|
+
'uid',
|
|
64
|
+
'content_types',
|
|
65
|
+
'branches',
|
|
66
|
+
'fixStatus',
|
|
67
|
+
'tree',
|
|
68
|
+
'display_name',
|
|
69
|
+
'display_type',
|
|
70
|
+
'missingRefs',
|
|
71
|
+
'treeStr',
|
|
72
|
+
'missingCTSelectFieldValues',
|
|
73
|
+
'min_instance',
|
|
74
|
+
'missingFieldUid',
|
|
75
|
+
'isPublished',
|
|
76
|
+
],
|
|
77
|
+
ReportTitleForEntries: {
|
|
78
|
+
Entries_Select_feild: 'Entries_Select_feild',
|
|
79
|
+
Entries_Mandatory_feild: 'Entries_Mandatory_feild',
|
|
80
|
+
},
|
|
59
81
|
};
|
|
60
82
|
exports.default = config;
|
package/lib/messages/index.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ declare const auditFixMsg: {
|
|
|
39
39
|
EMPTY_FIX_MSG: string;
|
|
40
40
|
AUDIT_FIX_CMD_DESCRIPTION: string;
|
|
41
41
|
WF_FIX_MSG: string;
|
|
42
|
+
ENTRY_MANDATORY_FIELD_FIX: string;
|
|
43
|
+
ENTRY_SELECT_FIELD_FIX: string;
|
|
42
44
|
};
|
|
43
45
|
declare const messages: typeof errors & typeof commonMsg & typeof auditMsg & typeof auditFixMsg & typeof tableColumnDescriptions;
|
|
44
46
|
/**
|
package/lib/messages/index.js
CHANGED
|
@@ -49,6 +49,8 @@ const auditFixMsg = {
|
|
|
49
49
|
EMPTY_FIX_MSG: 'Successfully removed the empty field/block found at {path} from the schema.',
|
|
50
50
|
AUDIT_FIX_CMD_DESCRIPTION: 'Perform audits and fix possible errors in the exported Contentstack data.',
|
|
51
51
|
WF_FIX_MSG: 'Successfully removed the workflow {uid} named {name}.',
|
|
52
|
+
ENTRY_MANDATORY_FIELD_FIX: `Removing the publish details from entry uid '{uid}' from locale '{locale}'`,
|
|
53
|
+
ENTRY_SELECT_FIELD_FIX: `Adding the value '{value}' in select field of uid '{uid}'`
|
|
52
54
|
};
|
|
53
55
|
exports.auditFixMsg = auditFixMsg;
|
|
54
56
|
const messages = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, errors), commonMsg), auditMsg), auditFixMsg), tableColumnDescriptions);
|
package/lib/modules/entries.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import auditConfig from '../config';
|
|
2
|
-
import { LogFn, Locale, ConfigType, EntryStruct, EntryFieldType, ModularBlockType, ContentTypeStruct, CtConstructorParam, GroupFieldDataType, GlobalFieldDataType, JsonRTEFieldDataType, ContentTypeSchemaType, ModularBlocksDataType, ModuleConstructorParam, ReferenceFieldDataType, EntryRefErrorReturnType, EntryGroupFieldDataType, EntryGlobalFieldDataType, EntryJsonRTEFieldDataType, EntryModularBlocksDataType, EntryReferenceFieldDataType, ExtensionOrAppFieldDataType, EntryExtensionOrAppFieldDataType } from '../types';
|
|
2
|
+
import { LogFn, Locale, ConfigType, EntryStruct, EntryFieldType, ModularBlockType, ContentTypeStruct, CtConstructorParam, GroupFieldDataType, GlobalFieldDataType, JsonRTEFieldDataType, ContentTypeSchemaType, ModularBlocksDataType, ModuleConstructorParam, ReferenceFieldDataType, EntryRefErrorReturnType, EntryGroupFieldDataType, EntryGlobalFieldDataType, EntryJsonRTEFieldDataType, EntryModularBlocksDataType, EntryReferenceFieldDataType, ExtensionOrAppFieldDataType, EntryExtensionOrAppFieldDataType, SelectFeildStruct } from '../types';
|
|
3
3
|
export default class Entries {
|
|
4
4
|
log: LogFn;
|
|
5
5
|
protected fix: boolean;
|
|
@@ -14,6 +14,8 @@ export default class Entries {
|
|
|
14
14
|
ctSchema: ContentTypeStruct[];
|
|
15
15
|
protected entries: Record<string, EntryStruct>;
|
|
16
16
|
protected missingRefs: Record<string, any>;
|
|
17
|
+
protected missingSelectFeild: Record<string, any>;
|
|
18
|
+
protected missingMandatoryFields: Record<string, any>;
|
|
17
19
|
entryMetaData: Record<string, any>[];
|
|
18
20
|
moduleName: keyof typeof auditConfig.moduleConfig;
|
|
19
21
|
isEntryWithoutTitleField: boolean;
|
|
@@ -23,7 +25,15 @@ export default class Entries {
|
|
|
23
25
|
* iterates over the schema and looks for references, and returns a list of missing references.
|
|
24
26
|
* @returns the `missingRefs` object.
|
|
25
27
|
*/
|
|
26
|
-
run(): Promise<
|
|
28
|
+
run(): Promise<{
|
|
29
|
+
missingEntryRefs?: undefined;
|
|
30
|
+
missingSelectFeild?: undefined;
|
|
31
|
+
missingMandatoryFields?: undefined;
|
|
32
|
+
} | {
|
|
33
|
+
missingEntryRefs: Record<string, any>;
|
|
34
|
+
missingSelectFeild: Record<string, any>;
|
|
35
|
+
missingMandatoryFields: Record<string, any>;
|
|
36
|
+
}>;
|
|
27
37
|
/**
|
|
28
38
|
* The function removes any properties from the `missingRefs` object that have an empty array value.
|
|
29
39
|
*/
|
|
@@ -169,6 +179,54 @@ export default class Entries {
|
|
|
169
179
|
* `schema`.
|
|
170
180
|
*/
|
|
171
181
|
runFixOnSchema(tree: Record<string, unknown>[], schema: ContentTypeSchemaType[], entry: EntryFieldType): EntryFieldType;
|
|
182
|
+
/**
|
|
183
|
+
* We check for the select field with condition in order of multiple -> Array
|
|
184
|
+
* We find the missing values i.e. the values present in entry but not in the options of the content-type
|
|
185
|
+
* @param tree : Contains all the tree where the select field is located used for getting the path to it
|
|
186
|
+
* @param fieldStructure it contains the Content-type structure of the field
|
|
187
|
+
* @param field It contains the value that is present in the entry it can be array or value of number | string
|
|
188
|
+
* @returns if there is missing field returns field and path
|
|
189
|
+
* Else empty array
|
|
190
|
+
*/
|
|
191
|
+
validateSelectField(tree: Record<string, unknown>[], fieldStructure: SelectFeildStruct, field: any): {
|
|
192
|
+
uid: string;
|
|
193
|
+
name: string;
|
|
194
|
+
display_name: string;
|
|
195
|
+
display_type: string;
|
|
196
|
+
missingCTSelectFieldValues: any;
|
|
197
|
+
min_instance: string | number;
|
|
198
|
+
tree: Record<string, unknown>[];
|
|
199
|
+
treeStr: string;
|
|
200
|
+
}[];
|
|
201
|
+
/**
|
|
202
|
+
* This functions check which of the select values used in entry is/are not present in the Content-type
|
|
203
|
+
* Then removes those values from entry
|
|
204
|
+
* If the entry is empty then adds the first value of the options
|
|
205
|
+
* If the entry has multiple choices and min_instances then adds that number of instances
|
|
206
|
+
* @param {Record<string, unknown>}tree Contains the path where the select field can be found
|
|
207
|
+
* @param field : It contains the content-type structure of the select field
|
|
208
|
+
* @param entry : it contains the value in the entry of select field one of the options of the CT.
|
|
209
|
+
* @returns
|
|
210
|
+
*/
|
|
211
|
+
fixSelectField(tree: Record<string, unknown>[], field: SelectFeildStruct, entry: any): any;
|
|
212
|
+
validateMandatoryFields(tree: Record<string, unknown>[], fieldStructure: any, entry: any): {
|
|
213
|
+
uid: string;
|
|
214
|
+
name: string;
|
|
215
|
+
display_name: any;
|
|
216
|
+
missingFieldUid: any;
|
|
217
|
+
tree: Record<string, unknown>[];
|
|
218
|
+
treeStr: string;
|
|
219
|
+
}[];
|
|
220
|
+
/**
|
|
221
|
+
*
|
|
222
|
+
* @param field It contains the value to be searched
|
|
223
|
+
* @param selectOptions It contains the options that were added in CT
|
|
224
|
+
* @returns An Array of entry containing only the values that were present in CT, An array of not present entries
|
|
225
|
+
*/
|
|
226
|
+
findNotPresentSelectField(field: any, selectOptions: any): {
|
|
227
|
+
filteredFeild: any[];
|
|
228
|
+
notPresent: any[];
|
|
229
|
+
};
|
|
172
230
|
/**
|
|
173
231
|
* The function `fixGlobalFieldReferences` adds a new entry to a tree data structure and runs a fix
|
|
174
232
|
* on the schema.
|
package/lib/modules/entries.js
CHANGED
|
@@ -16,6 +16,8 @@ class Entries {
|
|
|
16
16
|
constructor({ log, fix, config, moduleName, ctSchema, gfSchema }) {
|
|
17
17
|
this.extensions = [];
|
|
18
18
|
this.missingRefs = {};
|
|
19
|
+
this.missingSelectFeild = {};
|
|
20
|
+
this.missingMandatoryFields = {};
|
|
19
21
|
this.entryMetaData = [];
|
|
20
22
|
this.moduleName = 'entries';
|
|
21
23
|
this.isEntryWithoutTitleField = false;
|
|
@@ -57,10 +59,34 @@ class Entries {
|
|
|
57
59
|
if (!this.missingRefs[this.currentUid]) {
|
|
58
60
|
this.missingRefs[this.currentUid] = [];
|
|
59
61
|
}
|
|
62
|
+
if (!this.missingSelectFeild[this.currentUid]) {
|
|
63
|
+
this.missingSelectFeild[this.currentUid] = [];
|
|
64
|
+
}
|
|
65
|
+
if (!this.missingMandatoryFields[this.currentUid]) {
|
|
66
|
+
this.missingMandatoryFields[this.currentUid] = [];
|
|
67
|
+
}
|
|
60
68
|
if (this.fix) {
|
|
61
69
|
this.removeMissingKeysOnEntry(ctSchema.schema, this.entries[entryUid]);
|
|
62
70
|
}
|
|
63
71
|
this.lookForReference([{ locale: code, uid, name: title }], ctSchema, this.entries[entryUid]);
|
|
72
|
+
const fields = this.missingMandatoryFields[uid];
|
|
73
|
+
const isPublished = entry.publish_details.length > 0;
|
|
74
|
+
if ((this.fix && fields.length && isPublished) || (!this.fix && fields)) {
|
|
75
|
+
const fixStatus = this.fix ? 'Fixed' : '';
|
|
76
|
+
fields === null || fields === void 0 ? void 0 : fields.forEach((field) => {
|
|
77
|
+
field.isPublished = isPublished;
|
|
78
|
+
if (this.fix && isPublished) {
|
|
79
|
+
field.fixStatus = fixStatus;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
if (this.fix && isPublished) {
|
|
83
|
+
this.log((0, messages_1.$t)(messages_1.auditFixMsg.ENTRY_MANDATORY_FIELD_FIX, { uid, locale: code }), 'error');
|
|
84
|
+
entry.publish_details = [];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
delete this.missingMandatoryFields[uid];
|
|
89
|
+
}
|
|
64
90
|
const message = (0, messages_1.$t)(messages_1.auditMsg.SCAN_ENTRY_SUCCESS_MSG, {
|
|
65
91
|
title,
|
|
66
92
|
local: code,
|
|
@@ -77,7 +103,11 @@ class Entries {
|
|
|
77
103
|
}
|
|
78
104
|
// this.log('', 'info'); // Adding empty line
|
|
79
105
|
this.removeEmptyVal();
|
|
80
|
-
return
|
|
106
|
+
return {
|
|
107
|
+
missingEntryRefs: this.missingRefs,
|
|
108
|
+
missingSelectFeild: this.missingSelectFeild,
|
|
109
|
+
missingMandatoryFields: this.missingMandatoryFields,
|
|
110
|
+
};
|
|
81
111
|
}
|
|
82
112
|
/**
|
|
83
113
|
* The function removes any properties from the `missingRefs` object that have an empty array value.
|
|
@@ -88,6 +118,16 @@ class Entries {
|
|
|
88
118
|
delete this.missingRefs[propName];
|
|
89
119
|
}
|
|
90
120
|
}
|
|
121
|
+
for (let propName in this.missingSelectFeild) {
|
|
122
|
+
if (!this.missingSelectFeild[propName].length) {
|
|
123
|
+
delete this.missingSelectFeild[propName];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
for (let propName in this.missingMandatoryFields) {
|
|
127
|
+
if (!this.missingMandatoryFields[propName].length) {
|
|
128
|
+
delete this.missingMandatoryFields[propName];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
91
131
|
}
|
|
92
132
|
/**
|
|
93
133
|
* The function `fixPrerequisiteData` fixes the prerequisite data by updating the `ctSchema` and
|
|
@@ -163,10 +203,12 @@ class Entries {
|
|
|
163
203
|
if (this.fix) {
|
|
164
204
|
entry = this.runFixOnSchema(tree, field.schema, entry);
|
|
165
205
|
}
|
|
166
|
-
for (const child of (_a = field.schema) !== null && _a !== void 0 ? _a : []) {
|
|
206
|
+
for (const child of (_a = field === null || field === void 0 ? void 0 : field.schema) !== null && _a !== void 0 ? _a : []) {
|
|
167
207
|
const { uid } = child;
|
|
168
|
-
|
|
208
|
+
this.missingMandatoryFields[this.currentUid].push(...this.validateMandatoryFields([...tree, { uid: field.uid, name: child.display_name, field: uid }], child, entry));
|
|
209
|
+
if (!(entry === null || entry === void 0 ? void 0 : entry[uid]) && !child.hasOwnProperty('display_type')) {
|
|
169
210
|
continue;
|
|
211
|
+
}
|
|
170
212
|
switch (child.data_type) {
|
|
171
213
|
case 'reference':
|
|
172
214
|
this.missingRefs[this.currentUid].push(...this.validateReferenceField([...tree, { uid: child.uid, name: child.display_name, field: uid }], child, entry[uid]));
|
|
@@ -190,6 +232,12 @@ class Entries {
|
|
|
190
232
|
case 'group':
|
|
191
233
|
this.validateGroupField([...tree, { uid: field.uid, name: child.display_name, field: uid }], child, entry[uid]);
|
|
192
234
|
break;
|
|
235
|
+
case 'text':
|
|
236
|
+
case 'number':
|
|
237
|
+
if (child.hasOwnProperty('display_type')) {
|
|
238
|
+
this.missingSelectFeild[this.currentUid].push(...this.validateSelectField([...tree, { uid: field.uid, name: child.display_name, field: uid }], child, entry[uid]));
|
|
239
|
+
}
|
|
240
|
+
break;
|
|
193
241
|
}
|
|
194
242
|
}
|
|
195
243
|
}
|
|
@@ -453,10 +501,205 @@ class Entries {
|
|
|
453
501
|
case 'group':
|
|
454
502
|
entry[uid] = this.fixGroupField([...tree, { uid: field.uid, name: field.display_name, data_type: field.data_type }], field, entry[uid]);
|
|
455
503
|
break;
|
|
504
|
+
case 'text':
|
|
505
|
+
case 'number':
|
|
506
|
+
if (field.hasOwnProperty('display_type')) {
|
|
507
|
+
entry[uid] = this.fixSelectField([...tree, { uid: field.uid, name: field.display_name, data_type: field.data_type }], field, entry[uid]);
|
|
508
|
+
}
|
|
509
|
+
break;
|
|
456
510
|
}
|
|
457
511
|
});
|
|
458
512
|
return entry;
|
|
459
513
|
}
|
|
514
|
+
/**
|
|
515
|
+
* We check for the select field with condition in order of multiple -> Array
|
|
516
|
+
* We find the missing values i.e. the values present in entry but not in the options of the content-type
|
|
517
|
+
* @param tree : Contains all the tree where the select field is located used for getting the path to it
|
|
518
|
+
* @param fieldStructure it contains the Content-type structure of the field
|
|
519
|
+
* @param field It contains the value that is present in the entry it can be array or value of number | string
|
|
520
|
+
* @returns if there is missing field returns field and path
|
|
521
|
+
* Else empty array
|
|
522
|
+
*/
|
|
523
|
+
validateSelectField(tree, fieldStructure, field) {
|
|
524
|
+
const { display_name, enum: selectOptions, multiple, min_instance, display_type } = fieldStructure;
|
|
525
|
+
if (field === null || field === '' || (field === null || field === void 0 ? void 0 : field.length) === 0 || !field) {
|
|
526
|
+
let missingCTSelectFieldValues = 'Not Selected';
|
|
527
|
+
return [
|
|
528
|
+
{
|
|
529
|
+
uid: this.currentUid,
|
|
530
|
+
name: this.currentTitle,
|
|
531
|
+
display_name,
|
|
532
|
+
display_type,
|
|
533
|
+
missingCTSelectFieldValues,
|
|
534
|
+
min_instance: min_instance !== null && min_instance !== void 0 ? min_instance : 'NA',
|
|
535
|
+
tree,
|
|
536
|
+
treeStr: tree
|
|
537
|
+
.map(({ name }) => name)
|
|
538
|
+
.filter((val) => val)
|
|
539
|
+
.join(' ➜ '),
|
|
540
|
+
},
|
|
541
|
+
];
|
|
542
|
+
}
|
|
543
|
+
let missingCTSelectFieldValues;
|
|
544
|
+
if (multiple) {
|
|
545
|
+
if (Array.isArray(field)) {
|
|
546
|
+
let obj = this.findNotPresentSelectField(field, selectOptions);
|
|
547
|
+
let { notPresent } = obj;
|
|
548
|
+
if (notPresent.length) {
|
|
549
|
+
missingCTSelectFieldValues = notPresent;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
else if (!selectOptions.choices.some((choice) => choice.value === field)) {
|
|
554
|
+
missingCTSelectFieldValues = field;
|
|
555
|
+
}
|
|
556
|
+
if (display_type && missingCTSelectFieldValues) {
|
|
557
|
+
return [
|
|
558
|
+
{
|
|
559
|
+
uid: this.currentUid,
|
|
560
|
+
name: this.currentTitle,
|
|
561
|
+
display_name,
|
|
562
|
+
display_type,
|
|
563
|
+
missingCTSelectFieldValues,
|
|
564
|
+
min_instance: min_instance !== null && min_instance !== void 0 ? min_instance : 'NA',
|
|
565
|
+
tree,
|
|
566
|
+
treeStr: tree
|
|
567
|
+
.map(({ name }) => name)
|
|
568
|
+
.filter((val) => val)
|
|
569
|
+
.join(' ➜ '),
|
|
570
|
+
},
|
|
571
|
+
];
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
return [];
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* This functions check which of the select values used in entry is/are not present in the Content-type
|
|
579
|
+
* Then removes those values from entry
|
|
580
|
+
* If the entry is empty then adds the first value of the options
|
|
581
|
+
* If the entry has multiple choices and min_instances then adds that number of instances
|
|
582
|
+
* @param {Record<string, unknown>}tree Contains the path where the select field can be found
|
|
583
|
+
* @param field : It contains the content-type structure of the select field
|
|
584
|
+
* @param entry : it contains the value in the entry of select field one of the options of the CT.
|
|
585
|
+
* @returns
|
|
586
|
+
*/
|
|
587
|
+
fixSelectField(tree, field, entry) {
|
|
588
|
+
const { enum: selectOptions, multiple, min_instance, display_type, display_name, uid } = field;
|
|
589
|
+
let missingCTSelectFieldValues;
|
|
590
|
+
let isMissingValuePresent = false;
|
|
591
|
+
if (multiple) {
|
|
592
|
+
let obj = this.findNotPresentSelectField(entry, selectOptions);
|
|
593
|
+
let { notPresent, filteredFeild } = obj;
|
|
594
|
+
entry = filteredFeild;
|
|
595
|
+
missingCTSelectFieldValues = notPresent;
|
|
596
|
+
if (missingCTSelectFieldValues.length) {
|
|
597
|
+
isMissingValuePresent = true;
|
|
598
|
+
}
|
|
599
|
+
if (min_instance && Array.isArray(entry)) {
|
|
600
|
+
const missingInstances = min_instance - entry.length;
|
|
601
|
+
if (missingInstances > 0) {
|
|
602
|
+
isMissingValuePresent = true;
|
|
603
|
+
const newValues = selectOptions.choices
|
|
604
|
+
.filter((choice) => !entry.includes(choice.value))
|
|
605
|
+
.slice(0, missingInstances)
|
|
606
|
+
.map((choice) => choice.value);
|
|
607
|
+
entry.push(...newValues);
|
|
608
|
+
this.log((0, messages_1.$t)(messages_1.auditFixMsg.ENTRY_SELECT_FIELD_FIX, { value: newValues.join(' '), uid }), 'error');
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
if (entry.length === 0) {
|
|
613
|
+
isMissingValuePresent = true;
|
|
614
|
+
const defaultValue = selectOptions.choices.length > 0 ? selectOptions.choices[0].value : null;
|
|
615
|
+
entry.push(defaultValue);
|
|
616
|
+
this.log((0, messages_1.$t)(messages_1.auditFixMsg.ENTRY_SELECT_FIELD_FIX, { value: defaultValue, uid }), 'error');
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
const isPresent = selectOptions.choices.some((choice) => choice.value === entry);
|
|
622
|
+
if (!isPresent) {
|
|
623
|
+
missingCTSelectFieldValues = entry;
|
|
624
|
+
isMissingValuePresent = true;
|
|
625
|
+
let defaultValue = selectOptions.choices.length > 0 ? selectOptions.choices[0].value : null;
|
|
626
|
+
entry = defaultValue;
|
|
627
|
+
this.log((0, messages_1.$t)(messages_1.auditFixMsg.ENTRY_SELECT_FIELD_FIX, { value: defaultValue, uid }), 'error');
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
if (display_type && isMissingValuePresent) {
|
|
631
|
+
this.missingSelectFeild[this.currentUid].push({
|
|
632
|
+
uid: this.currentUid,
|
|
633
|
+
name: this.currentTitle,
|
|
634
|
+
display_name,
|
|
635
|
+
display_type,
|
|
636
|
+
missingCTSelectFieldValues,
|
|
637
|
+
min_instance: min_instance !== null && min_instance !== void 0 ? min_instance : 'NA',
|
|
638
|
+
tree,
|
|
639
|
+
treeStr: tree
|
|
640
|
+
.map(({ name }) => name)
|
|
641
|
+
.filter((val) => val)
|
|
642
|
+
.join(' ➜ '),
|
|
643
|
+
fixStatus: 'Fixed',
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
return entry;
|
|
647
|
+
}
|
|
648
|
+
validateMandatoryFields(tree, fieldStructure, entry) {
|
|
649
|
+
const { display_name, multiple, data_type, mandatory, field_metadata, uid } = fieldStructure;
|
|
650
|
+
const isJsonRteEmpty = () => {
|
|
651
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
652
|
+
const jsonNode = multiple
|
|
653
|
+
? (_f = (_e = (_d = (_c = (_b = (_a = entry[uid]) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.children) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.children) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.text
|
|
654
|
+
: (_l = (_k = (_j = (_h = (_g = entry[uid]) === null || _g === void 0 ? void 0 : _g.children) === null || _h === void 0 ? void 0 : _h[0]) === null || _j === void 0 ? void 0 : _j.children) === null || _k === void 0 ? void 0 : _k[0]) === null || _l === void 0 ? void 0 : _l.text;
|
|
655
|
+
return jsonNode === '';
|
|
656
|
+
};
|
|
657
|
+
const isEntryEmpty = () => {
|
|
658
|
+
var _a;
|
|
659
|
+
const fieldValue = multiple ? (_a = entry[uid]) === null || _a === void 0 ? void 0 : _a.length : entry[uid];
|
|
660
|
+
return fieldValue === '' || !fieldValue;
|
|
661
|
+
};
|
|
662
|
+
if (mandatory) {
|
|
663
|
+
if ((data_type === 'json' && field_metadata.allow_json_rte && isJsonRteEmpty()) ||
|
|
664
|
+
(!(data_type === 'json') && isEntryEmpty())) {
|
|
665
|
+
return [
|
|
666
|
+
{
|
|
667
|
+
uid: this.currentUid,
|
|
668
|
+
name: this.currentTitle,
|
|
669
|
+
display_name,
|
|
670
|
+
missingFieldUid: uid,
|
|
671
|
+
tree,
|
|
672
|
+
treeStr: tree
|
|
673
|
+
.filter(({ name }) => name)
|
|
674
|
+
.map(({ name }) => name)
|
|
675
|
+
.join(' ➜ '),
|
|
676
|
+
},
|
|
677
|
+
];
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
return [];
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
*
|
|
684
|
+
* @param field It contains the value to be searched
|
|
685
|
+
* @param selectOptions It contains the options that were added in CT
|
|
686
|
+
* @returns An Array of entry containing only the values that were present in CT, An array of not present entries
|
|
687
|
+
*/
|
|
688
|
+
findNotPresentSelectField(field, selectOptions) {
|
|
689
|
+
let present = [];
|
|
690
|
+
let notPresent = [];
|
|
691
|
+
const choicesMap = new Map(selectOptions.choices.map((choice) => [choice.value, choice]));
|
|
692
|
+
for (const value of field) {
|
|
693
|
+
const choice = choicesMap.get(value);
|
|
694
|
+
if (choice) {
|
|
695
|
+
present.push(choice.value);
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
notPresent.push(value);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
return { filteredFeild: present, notPresent };
|
|
702
|
+
}
|
|
460
703
|
/**
|
|
461
704
|
* The function `fixGlobalFieldReferences` adds a new entry to a tree data structure and runs a fix
|
|
462
705
|
* on the schema.
|
|
@@ -733,7 +976,11 @@ class Entries {
|
|
|
733
976
|
const entries = (await fsUtility.readChunkFiles.next());
|
|
734
977
|
for (const entryUid in entries) {
|
|
735
978
|
let { title } = entries[entryUid];
|
|
736
|
-
if (!title) {
|
|
979
|
+
if (entries[entryUid].hasOwnProperty('title') && !title) {
|
|
980
|
+
this.isEntryWithoutTitleField = true;
|
|
981
|
+
this.log(`The 'title' field in Entry with UID '${entryUid}' of Content Type '${uid}' in Locale '${code}' is empty.`, `error`);
|
|
982
|
+
}
|
|
983
|
+
else if (!title) {
|
|
737
984
|
this.isEntryWithoutTitleField = true;
|
|
738
985
|
this.log(`Entry with UID '${entryUid}' of Content Type '${uid}' in Locale '${code}' does not have a 'title' field.`, `error`);
|
|
739
986
|
}
|
|
@@ -743,7 +990,7 @@ class Entries {
|
|
|
743
990
|
}
|
|
744
991
|
}
|
|
745
992
|
if (this.isEntryWithoutTitleField) {
|
|
746
|
-
throw Error(`Entries found with missing 'title' field! Please make the data corrections and re-run the audit.`);
|
|
993
|
+
// throw Error(`Entries found with missing 'title' field! Please make the data corrections and re-run the audit.`);
|
|
747
994
|
}
|
|
748
995
|
}
|
|
749
996
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import config from '../config';
|
|
2
2
|
import { AnyProperty } from './common';
|
|
3
3
|
import { ConfigType, LogFn } from './utils';
|
|
4
|
-
type ContentTypeSchemaType = ReferenceFieldDataType | GlobalFieldDataType | ExtensionOrAppFieldDataType | JsonRTEFieldDataType | GroupFieldDataType | ModularBlocksDataType;
|
|
4
|
+
type ContentTypeSchemaType = ReferenceFieldDataType | GlobalFieldDataType | ExtensionOrAppFieldDataType | JsonRTEFieldDataType | GroupFieldDataType | ModularBlocksDataType | SelectFeildStruct;
|
|
5
5
|
type ContentTypeStruct = {
|
|
6
6
|
uid: string;
|
|
7
7
|
title: string;
|
|
8
8
|
description: string;
|
|
9
9
|
schema?: ContentTypeSchemaType[];
|
|
10
|
+
mandatory: boolean;
|
|
10
11
|
};
|
|
11
12
|
type ModuleConstructorParam = {
|
|
12
13
|
log: LogFn;
|
|
@@ -26,6 +27,7 @@ type CommonDataTypeStruct = {
|
|
|
26
27
|
ref_multiple: boolean;
|
|
27
28
|
allow_json_rte: boolean;
|
|
28
29
|
} & AnyProperty;
|
|
30
|
+
mandatory: boolean;
|
|
29
31
|
};
|
|
30
32
|
type RefErrorReturnType = {
|
|
31
33
|
name: string;
|
|
@@ -66,23 +68,38 @@ type ModularBlockType = {
|
|
|
66
68
|
uid: string;
|
|
67
69
|
title: string;
|
|
68
70
|
reference_to?: string;
|
|
69
|
-
schema: (JsonRTEFieldDataType | ModularBlocksDataType | ReferenceFieldDataType | ExtensionOrAppFieldDataType | GroupFieldDataType)[];
|
|
71
|
+
schema: (JsonRTEFieldDataType | ModularBlocksDataType | ReferenceFieldDataType | ExtensionOrAppFieldDataType | GroupFieldDataType | SelectFeildStruct)[];
|
|
70
72
|
};
|
|
71
73
|
type ModularBlocksDataType = CommonDataTypeStruct & {
|
|
72
74
|
blocks: ModularBlockType[];
|
|
73
75
|
};
|
|
74
|
-
type GroupFieldSchemaTypes = GroupFieldDataType | CommonDataTypeStruct | GlobalFieldDataType | ReferenceFieldDataType | ExtensionOrAppFieldDataType;
|
|
75
|
-
type GlobalFieldSchemaTypes = ReferenceFieldDataType | GroupFieldDataType | ExtensionOrAppFieldDataType;
|
|
76
|
-
type ModularBlocksSchemaTypes = ReferenceFieldDataType | JsonRTEFieldDataType;
|
|
76
|
+
type GroupFieldSchemaTypes = GroupFieldDataType | CommonDataTypeStruct | GlobalFieldDataType | ReferenceFieldDataType | ExtensionOrAppFieldDataType | SelectFeildStruct;
|
|
77
|
+
type GlobalFieldSchemaTypes = ReferenceFieldDataType | GroupFieldDataType | ExtensionOrAppFieldDataType | SelectFeildStruct;
|
|
78
|
+
type ModularBlocksSchemaTypes = ReferenceFieldDataType | JsonRTEFieldDataType | SelectFeildStruct;
|
|
79
|
+
type SelectFeildStruct = CommonDataTypeStruct & {
|
|
80
|
+
display_type: string;
|
|
81
|
+
enum: {
|
|
82
|
+
advanced: string;
|
|
83
|
+
choices: Record<string, unknown>[];
|
|
84
|
+
};
|
|
85
|
+
min_instance?: number;
|
|
86
|
+
max_instance?: number;
|
|
87
|
+
multiple: boolean;
|
|
88
|
+
};
|
|
77
89
|
declare enum OutputColumn {
|
|
78
90
|
Title = "name",
|
|
79
91
|
'Field name' = "display_name",
|
|
80
92
|
'Field type' = "data_type",
|
|
93
|
+
'Display type' = "display_type",
|
|
81
94
|
'Missing references' = "missingRefs",
|
|
82
95
|
Path = "treeStr",
|
|
83
96
|
title = "title",
|
|
84
97
|
'uid' = "uid",
|
|
85
98
|
'missingCts' = "content_types",
|
|
86
|
-
'Missing Branches' = "branches"
|
|
99
|
+
'Missing Branches' = "branches",
|
|
100
|
+
'MissingValues' = "missingCTSelectFieldValues",
|
|
101
|
+
'Minimum Required Instaces' = "min_instance",
|
|
102
|
+
'missingFieldUid' = "missingFieldUid",
|
|
103
|
+
'isPublished' = "isPublished"
|
|
87
104
|
}
|
|
88
|
-
export { CtConstructorParam, ContentTypeStruct, ModuleConstructorParam, ReferenceFieldDataType, GlobalFieldDataType, ExtensionOrAppFieldDataType, JsonRTEFieldDataType, GroupFieldDataType, ModularBlocksDataType, RefErrorReturnType, ModularBlocksSchemaTypes, ModularBlockType, OutputColumn, ContentTypeSchemaType, GlobalFieldSchemaTypes, WorkflowExtensionsRefErrorReturnType, };
|
|
105
|
+
export { CtConstructorParam, ContentTypeStruct, ModuleConstructorParam, ReferenceFieldDataType, GlobalFieldDataType, ExtensionOrAppFieldDataType, JsonRTEFieldDataType, GroupFieldDataType, ModularBlocksDataType, RefErrorReturnType, ModularBlocksSchemaTypes, ModularBlockType, OutputColumn, ContentTypeSchemaType, GlobalFieldSchemaTypes, WorkflowExtensionsRefErrorReturnType, SelectFeildStruct, };
|
|
@@ -6,11 +6,16 @@ var OutputColumn;
|
|
|
6
6
|
OutputColumn["Title"] = "name";
|
|
7
7
|
OutputColumn["Field name"] = "display_name";
|
|
8
8
|
OutputColumn["Field type"] = "data_type";
|
|
9
|
+
OutputColumn["Display type"] = "display_type";
|
|
9
10
|
OutputColumn["Missing references"] = "missingRefs";
|
|
10
11
|
OutputColumn["Path"] = "treeStr";
|
|
11
12
|
OutputColumn["title"] = "title";
|
|
12
13
|
OutputColumn["uid"] = "uid";
|
|
13
14
|
OutputColumn["missingCts"] = "content_types";
|
|
14
15
|
OutputColumn["Missing Branches"] = "branches";
|
|
16
|
+
OutputColumn["MissingValues"] = "missingCTSelectFieldValues";
|
|
17
|
+
OutputColumn["Minimum Required Instaces"] = "min_instance";
|
|
18
|
+
OutputColumn["missingFieldUid"] = "missingFieldUid";
|
|
19
|
+
OutputColumn["isPublished"] = "isPublished";
|
|
15
20
|
})(OutputColumn || (OutputColumn = {}));
|
|
16
21
|
exports.OutputColumn = OutputColumn;
|
package/lib/types/entries.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ type Locale = {
|
|
|
8
8
|
type EntryStruct = {
|
|
9
9
|
uid: string;
|
|
10
10
|
title: string;
|
|
11
|
+
publish_details: [];
|
|
11
12
|
} & {
|
|
12
13
|
[key: string]: EntryReferenceFieldDataType[] | EntryGlobalFieldDataType | EntryJsonRTEFieldDataType | EntryGroupFieldDataType | EntryModularBlocksDataType[];
|
|
13
14
|
};
|
|
@@ -35,6 +36,10 @@ type GroupFieldType = EntryReferenceFieldDataType[] | EntryGlobalFieldDataType |
|
|
|
35
36
|
type EntryGroupFieldDataType = {
|
|
36
37
|
[key: string]: GroupFieldType;
|
|
37
38
|
};
|
|
39
|
+
type SelectValue = string | string[] | number | number;
|
|
40
|
+
type EntrySelectFeildDataType = {
|
|
41
|
+
[key: string]: SelectValue;
|
|
42
|
+
};
|
|
38
43
|
type EntryModularBlockType = {
|
|
39
44
|
[key: string]: EntryJsonRTEFieldDataType | EntryModularBlocksDataType | EntryReferenceFieldDataType[] | EntryGroupFieldDataType;
|
|
40
45
|
};
|
|
@@ -51,5 +56,7 @@ type EntryRefErrorReturnType = {
|
|
|
51
56
|
tree: Record<string, unknown>[];
|
|
52
57
|
missingRefs: string[] | Record<string, unknown>[];
|
|
53
58
|
};
|
|
54
|
-
type EntryFieldType = EntryStruct | EntryGlobalFieldDataType | EntryModularBlocksDataType | EntryGroupFieldDataType | EntryExtensionOrAppFieldDataType
|
|
55
|
-
|
|
59
|
+
type EntryFieldType = EntryStruct | EntryGlobalFieldDataType | EntryModularBlocksDataType | EntryGroupFieldDataType | EntryExtensionOrAppFieldDataType | EntrySelectFeildDataType | {
|
|
60
|
+
[key: string]: any;
|
|
61
|
+
};
|
|
62
|
+
export { Locale, EntryStruct, EntryFieldType, EntryGlobalFieldDataType, EntryExtensionOrAppFieldDataType, EntryJsonRTEFieldDataType, EntryGroupFieldDataType, EntryModularBlocksDataType, EntryReferenceFieldDataType, EntryRefErrorReturnType, GroupFieldType, EntryModularBlockType, EntrySelectFeildDataType, SelectValue };
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.6.1",
|
|
3
3
|
"commands": {
|
|
4
4
|
"cm:stacks:audit:fix": {
|
|
5
5
|
"id": "cm:stacks:audit:fix",
|
|
@@ -22,22 +22,6 @@
|
|
|
22
22
|
"$ <%= config.bin %> <%= command.id %> --report-path=<path> --modules=content-types --filter=\"name=\"<filter-value>\" --copy-dir --copy-path=<path>"
|
|
23
23
|
],
|
|
24
24
|
"flags": {
|
|
25
|
-
"config": {
|
|
26
|
-
"name": "config",
|
|
27
|
-
"type": "option",
|
|
28
|
-
"char": "c",
|
|
29
|
-
"description": "Path of the external config",
|
|
30
|
-
"helpGroup": "COMMON",
|
|
31
|
-
"multiple": false
|
|
32
|
-
},
|
|
33
|
-
"data-dir": {
|
|
34
|
-
"name": "data-dir",
|
|
35
|
-
"type": "option",
|
|
36
|
-
"char": "d",
|
|
37
|
-
"description": "Path where the data is stored",
|
|
38
|
-
"helpGroup": "COMMON",
|
|
39
|
-
"multiple": false
|
|
40
|
-
},
|
|
41
25
|
"report-path": {
|
|
42
26
|
"name": "report-path",
|
|
43
27
|
"type": "option",
|
|
@@ -176,22 +160,6 @@
|
|
|
176
160
|
"$ <%= config.bin %> <%= command.id %> --report-path=<path> --modules=content-types --filter=\"name=\"<filter-value>\""
|
|
177
161
|
],
|
|
178
162
|
"flags": {
|
|
179
|
-
"config": {
|
|
180
|
-
"name": "config",
|
|
181
|
-
"type": "option",
|
|
182
|
-
"char": "c",
|
|
183
|
-
"description": "Path of the external config",
|
|
184
|
-
"helpGroup": "COMMON",
|
|
185
|
-
"multiple": false
|
|
186
|
-
},
|
|
187
|
-
"data-dir": {
|
|
188
|
-
"name": "data-dir",
|
|
189
|
-
"type": "option",
|
|
190
|
-
"char": "d",
|
|
191
|
-
"description": "Path where the data is stored",
|
|
192
|
-
"helpGroup": "COMMON",
|
|
193
|
-
"multiple": false
|
|
194
|
-
},
|
|
195
163
|
"report-path": {
|
|
196
164
|
"name": "report-path",
|
|
197
165
|
"type": "option",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-audit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Contentstack audit plugin",
|
|
5
5
|
"author": "Contentstack CLI",
|
|
6
6
|
"homepage": "https://github.com/contentstack/cli",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"main": "./lib/index.js",
|
|
9
9
|
"types": "./lib/index.d.ts",
|
|
10
10
|
"bin": {
|
|
11
|
-
"audit": "./bin/run"
|
|
11
|
+
"audit": "./bin/run.js"
|
|
12
12
|
},
|
|
13
13
|
"repository": "contentstack/audit",
|
|
14
14
|
"files": [
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"/oclif.manifest.json"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@contentstack/cli-command": "~1.2.
|
|
22
|
-
"@contentstack/cli-utilities": "~1.6.
|
|
21
|
+
"@contentstack/cli-command": "~1.2.18",
|
|
22
|
+
"@contentstack/cli-utilities": "~1.6.1",
|
|
23
23
|
"@oclif/plugin-help": "^5",
|
|
24
24
|
"@oclif/plugin-plugins": "^5.0.0",
|
|
25
25
|
"chalk": "^4.1.2",
|
package/bin/dev
DELETED