@contentstack/cli-audit 1.2.1 → 1.3.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 +103 -47
- package/lib/audit-base-command.d.ts +2 -2
- package/lib/audit-base-command.js +9 -8
- package/lib/base-command.js +4 -1
- package/lib/commands/cm/stacks/audit/fix.js +7 -3
- package/lib/commands/cm/stacks/audit/index.js +2 -4
- package/lib/config/index.d.ts +1 -0
- package/lib/config/index.js +1 -0
- package/lib/messages/index.d.ts +10 -2
- package/lib/messages/index.js +13 -3
- package/lib/modules/content-types.d.ts +1 -0
- package/lib/modules/content-types.js +59 -9
- package/lib/modules/entries.d.ts +2 -2
- package/lib/modules/entries.js +12 -11
- package/lib/modules/global-fields.d.ts +1 -1
- package/lib/modules/global-fields.js +2 -2
- package/lib/types/common.d.ts +5 -0
- package/lib/types/common.js +2 -0
- package/lib/types/content-types.d.ts +1 -1
- package/lib/types/index.d.ts +2 -1
- package/lib/types/index.js +1 -0
- package/lib/util/flags.d.ts +10 -0
- package/lib/util/flags.js +26 -0
- package/lib/util/index.d.ts +2 -1
- package/lib/util/index.js +5 -5
- package/lib/util/log.js +12 -21
- package/oclif.manifest.json +40 -11
- package/package.json +10 -7
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.3.1 linux-x64 node-v18.19.0
|
|
23
23
|
$ csdx --help [COMMAND]
|
|
24
24
|
USAGE
|
|
25
25
|
$ csdx COMMAND
|
|
@@ -41,6 +41,7 @@ USAGE
|
|
|
41
41
|
* [`csdx plugins:install PLUGIN...`](#csdx-pluginsinstall-plugin-1)
|
|
42
42
|
* [`csdx plugins:link PLUGIN`](#csdx-pluginslink-plugin)
|
|
43
43
|
* [`csdx plugins:uninstall PLUGIN...`](#csdx-pluginsuninstall-plugin)
|
|
44
|
+
* [`csdx plugins:reset`](#csdx-pluginsreset)
|
|
44
45
|
* [`csdx plugins:uninstall PLUGIN...`](#csdx-pluginsuninstall-plugin-1)
|
|
45
46
|
* [`csdx plugins:uninstall PLUGIN...`](#csdx-pluginsuninstall-plugin-2)
|
|
46
47
|
* [`csdx plugins:update`](#csdx-pluginsupdate)
|
|
@@ -56,16 +57,20 @@ USAGE
|
|
|
56
57
|
--no-truncate]
|
|
57
58
|
|
|
58
59
|
FLAGS
|
|
60
|
+
--modules=<option>... Provide the list of modules to be audited
|
|
61
|
+
<options: content-types|global-fields|entries>
|
|
62
|
+
--report-path=<value> Path to store the audit reports
|
|
63
|
+
|
|
64
|
+
COMMON FLAGS
|
|
59
65
|
-c, --config=<value> Path of the external config
|
|
60
66
|
-d, --data-dir=<value> Path where the data is stored
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
--
|
|
64
|
-
--
|
|
65
|
-
|
|
66
|
-
--no-truncate
|
|
67
|
-
--
|
|
68
|
-
--sort=<value> property to sort by (prepend '-' for descending)
|
|
67
|
+
|
|
68
|
+
TABLE FLAGS
|
|
69
|
+
--columns=<value> Show only the specified columns (comma-separated)
|
|
70
|
+
--csv The output is in the CSV format [alias: --output=csv]
|
|
71
|
+
--filter=<value> Filter property by partial string matching. For example: name=foo
|
|
72
|
+
--no-truncate The output is not truncated to fit the screen
|
|
73
|
+
--sort=<value> Property to sort by (prepend '-' for descending)
|
|
69
74
|
|
|
70
75
|
DESCRIPTION
|
|
71
76
|
Perform audits and find possible errors in the exported Contentstack data
|
|
@@ -93,22 +98,29 @@ Perform audits and fix possible errors in the exported Contentstack data.
|
|
|
93
98
|
```
|
|
94
99
|
USAGE
|
|
95
100
|
$ csdx audit:fix [-c <value>] [-d <value>] [--report-path <value>] [--modules
|
|
96
|
-
content-types|global-fields|entries] [--copy-path <value> --copy-dir] [--
|
|
97
|
-
[--
|
|
101
|
+
content-types|global-fields|entries] [--copy-path <value> --copy-dir] [--fix-only
|
|
102
|
+
reference|global_field|json:rte|json:custom-field|blocks|group] [--columns <value> | ] [--sort <value>] [--filter
|
|
103
|
+
<value>] [--csv | --no-truncate]
|
|
98
104
|
|
|
99
105
|
FLAGS
|
|
100
|
-
-c, --config=<value> Path of the external config
|
|
101
|
-
-d, --data-dir=<value> Path where the data is stored
|
|
102
|
-
--columns=<value> only show provided columns (comma-separated)
|
|
103
106
|
--copy-dir Create backup from the original data.
|
|
104
107
|
--copy-path=<value> Provide the path to backup the copied data
|
|
105
|
-
--
|
|
106
|
-
|
|
108
|
+
--fix-only=<option>... Provide the list of fix options
|
|
109
|
+
<options: reference|global_field|json:rte|json:custom-field|blocks|group>
|
|
107
110
|
--modules=<option>... Provide the list of modules to be audited
|
|
108
111
|
<options: content-types|global-fields|entries>
|
|
109
|
-
--no-truncate do not truncate output to fit screen
|
|
110
112
|
--report-path=<value> Path to store the audit reports
|
|
111
|
-
|
|
113
|
+
|
|
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
|
+
TABLE FLAGS
|
|
119
|
+
--columns=<value> Show only the specified columns (comma-separated)
|
|
120
|
+
--csv The output is in the CSV format [alias: --output=csv]
|
|
121
|
+
--filter=<value> Filter property by partial string matching. For example: name=foo
|
|
122
|
+
--no-truncate The output is not truncated to fit the screen
|
|
123
|
+
--sort=<value> Property to sort by (prepend '-' for descending)
|
|
112
124
|
|
|
113
125
|
DESCRIPTION
|
|
114
126
|
Perform audits and fix possible errors in the exported Contentstack data.
|
|
@@ -124,6 +136,8 @@ EXAMPLES
|
|
|
124
136
|
|
|
125
137
|
$ csdx audit:fix --report-path=<path> --copy-dir --csv
|
|
126
138
|
|
|
139
|
+
$ csdx audit:fix --fix-only=reference,global_field --copy-dir
|
|
140
|
+
|
|
127
141
|
$ csdx audit:fix --report-path=<path> --filter="name=<filter-value>"
|
|
128
142
|
|
|
129
143
|
$ csdx audit:fix --report-path=<path> --modules=content-types --filter="name="<filter-value>" --copy-dir --copy-path=<path>
|
|
@@ -140,16 +154,20 @@ USAGE
|
|
|
140
154
|
--no-truncate]
|
|
141
155
|
|
|
142
156
|
FLAGS
|
|
157
|
+
--modules=<option>... Provide the list of modules to be audited
|
|
158
|
+
<options: content-types|global-fields|entries>
|
|
159
|
+
--report-path=<value> Path to store the audit reports
|
|
160
|
+
|
|
161
|
+
COMMON FLAGS
|
|
143
162
|
-c, --config=<value> Path of the external config
|
|
144
163
|
-d, --data-dir=<value> Path where the data is stored
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
--
|
|
148
|
-
--
|
|
149
|
-
|
|
150
|
-
--no-truncate
|
|
151
|
-
--
|
|
152
|
-
--sort=<value> property to sort by (prepend '-' for descending)
|
|
164
|
+
|
|
165
|
+
TABLE FLAGS
|
|
166
|
+
--columns=<value> Show only the specified columns (comma-separated)
|
|
167
|
+
--csv The output is in the CSV format [alias: --output=csv]
|
|
168
|
+
--filter=<value> Filter property by partial string matching. For example: name=foo
|
|
169
|
+
--no-truncate The output is not truncated to fit the screen
|
|
170
|
+
--sort=<value> Property to sort by (prepend '-' for descending)
|
|
153
171
|
|
|
154
172
|
DESCRIPTION
|
|
155
173
|
Perform audits and find possible errors in the exported Contentstack data
|
|
@@ -179,22 +197,29 @@ Perform audits and fix possible errors in the exported Contentstack data.
|
|
|
179
197
|
```
|
|
180
198
|
USAGE
|
|
181
199
|
$ csdx cm:stacks:audit:fix [-c <value>] [-d <value>] [--report-path <value>] [--modules
|
|
182
|
-
content-types|global-fields|entries] [--copy-path <value> --copy-dir] [--
|
|
183
|
-
[--
|
|
200
|
+
content-types|global-fields|entries] [--copy-path <value> --copy-dir] [--fix-only
|
|
201
|
+
reference|global_field|json:rte|json:custom-field|blocks|group] [--columns <value> | ] [--sort <value>] [--filter
|
|
202
|
+
<value>] [--csv | --no-truncate]
|
|
184
203
|
|
|
185
204
|
FLAGS
|
|
186
|
-
-c, --config=<value> Path of the external config
|
|
187
|
-
-d, --data-dir=<value> Path where the data is stored
|
|
188
|
-
--columns=<value> only show provided columns (comma-separated)
|
|
189
205
|
--copy-dir Create backup from the original data.
|
|
190
206
|
--copy-path=<value> Provide the path to backup the copied data
|
|
191
|
-
--
|
|
192
|
-
|
|
207
|
+
--fix-only=<option>... Provide the list of fix options
|
|
208
|
+
<options: reference|global_field|json:rte|json:custom-field|blocks|group>
|
|
193
209
|
--modules=<option>... Provide the list of modules to be audited
|
|
194
210
|
<options: content-types|global-fields|entries>
|
|
195
|
-
--no-truncate do not truncate output to fit screen
|
|
196
211
|
--report-path=<value> Path to store the audit reports
|
|
197
|
-
|
|
212
|
+
|
|
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
|
+
TABLE FLAGS
|
|
218
|
+
--columns=<value> Show only the specified columns (comma-separated)
|
|
219
|
+
--csv The output is in the CSV format [alias: --output=csv]
|
|
220
|
+
--filter=<value> Filter property by partial string matching. For example: name=foo
|
|
221
|
+
--no-truncate The output is not truncated to fit the screen
|
|
222
|
+
--sort=<value> Property to sort by (prepend '-' for descending)
|
|
198
223
|
|
|
199
224
|
DESCRIPTION
|
|
200
225
|
Perform audits and fix possible errors in the exported Contentstack data.
|
|
@@ -210,6 +235,8 @@ EXAMPLES
|
|
|
210
235
|
|
|
211
236
|
$ csdx cm:stacks:audit:fix --report-path=<path> --copy-dir --csv
|
|
212
237
|
|
|
238
|
+
$ csdx cm:stacks:audit:fix --fix-only=reference,global_field --copy-dir
|
|
239
|
+
|
|
213
240
|
$ csdx cm:stacks:audit:fix --report-path=<path> --filter="name=<filter-value>"
|
|
214
241
|
|
|
215
242
|
$ csdx cm:stacks:audit:fix --report-path=<path> --modules=content-types --filter="name="<filter-value>" --copy-dir --copy-path=<path>
|
|
@@ -258,7 +285,7 @@ EXAMPLES
|
|
|
258
285
|
$ csdx plugins
|
|
259
286
|
```
|
|
260
287
|
|
|
261
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
288
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v4.1.10/src/commands/plugins/index.ts)_
|
|
262
289
|
|
|
263
290
|
## `csdx plugins:install PLUGIN...`
|
|
264
291
|
|
|
@@ -274,7 +301,11 @@ ARGUMENTS
|
|
|
274
301
|
FLAGS
|
|
275
302
|
-f, --force Run yarn install with force flag.
|
|
276
303
|
-h, --help Show CLI help.
|
|
277
|
-
-
|
|
304
|
+
-s, --silent Silences yarn output.
|
|
305
|
+
-v, --verbose Show verbose yarn output.
|
|
306
|
+
|
|
307
|
+
GLOBAL FLAGS
|
|
308
|
+
--json Format output as json.
|
|
278
309
|
|
|
279
310
|
DESCRIPTION
|
|
280
311
|
Installs a plugin into the CLI.
|
|
@@ -291,11 +322,11 @@ ALIASES
|
|
|
291
322
|
$ csdx plugins:add
|
|
292
323
|
|
|
293
324
|
EXAMPLES
|
|
294
|
-
$ csdx plugins:
|
|
325
|
+
$ csdx plugins:add myplugin
|
|
295
326
|
|
|
296
|
-
$ csdx plugins:
|
|
327
|
+
$ csdx plugins:add https://github.com/someuser/someplugin
|
|
297
328
|
|
|
298
|
-
$ csdx plugins:
|
|
329
|
+
$ csdx plugins:add someuser/someplugin
|
|
299
330
|
```
|
|
300
331
|
|
|
301
332
|
## `csdx plugins:inspect PLUGIN...`
|
|
@@ -323,7 +354,7 @@ EXAMPLES
|
|
|
323
354
|
$ csdx plugins:inspect myplugin
|
|
324
355
|
```
|
|
325
356
|
|
|
326
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
357
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v4.1.10/src/commands/plugins/inspect.ts)_
|
|
327
358
|
|
|
328
359
|
## `csdx plugins:install PLUGIN...`
|
|
329
360
|
|
|
@@ -339,7 +370,11 @@ ARGUMENTS
|
|
|
339
370
|
FLAGS
|
|
340
371
|
-f, --force Run yarn install with force flag.
|
|
341
372
|
-h, --help Show CLI help.
|
|
342
|
-
-
|
|
373
|
+
-s, --silent Silences yarn output.
|
|
374
|
+
-v, --verbose Show verbose yarn output.
|
|
375
|
+
|
|
376
|
+
GLOBAL FLAGS
|
|
377
|
+
--json Format output as json.
|
|
343
378
|
|
|
344
379
|
DESCRIPTION
|
|
345
380
|
Installs a plugin into the CLI.
|
|
@@ -363,7 +398,7 @@ EXAMPLES
|
|
|
363
398
|
$ csdx plugins:install someuser/someplugin
|
|
364
399
|
```
|
|
365
400
|
|
|
366
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
401
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v4.1.10/src/commands/plugins/install.ts)_
|
|
367
402
|
|
|
368
403
|
## `csdx plugins:link PLUGIN`
|
|
369
404
|
|
|
@@ -377,8 +412,9 @@ ARGUMENTS
|
|
|
377
412
|
PATH [default: .] path to plugin
|
|
378
413
|
|
|
379
414
|
FLAGS
|
|
380
|
-
-h, --help
|
|
415
|
+
-h, --help Show CLI help.
|
|
381
416
|
-v, --verbose
|
|
417
|
+
--[no-]install Install dependencies after linking the plugin.
|
|
382
418
|
|
|
383
419
|
DESCRIPTION
|
|
384
420
|
Links a plugin into the CLI for development.
|
|
@@ -392,7 +428,7 @@ EXAMPLES
|
|
|
392
428
|
$ csdx plugins:link myplugin
|
|
393
429
|
```
|
|
394
430
|
|
|
395
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
431
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v4.1.10/src/commands/plugins/link.ts)_
|
|
396
432
|
|
|
397
433
|
## `csdx plugins:uninstall PLUGIN...`
|
|
398
434
|
|
|
@@ -415,8 +451,22 @@ DESCRIPTION
|
|
|
415
451
|
ALIASES
|
|
416
452
|
$ csdx plugins:unlink
|
|
417
453
|
$ csdx plugins:remove
|
|
454
|
+
|
|
455
|
+
EXAMPLES
|
|
456
|
+
$ csdx plugins:remove myplugin
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
## `csdx plugins:reset`
|
|
460
|
+
|
|
461
|
+
Remove all user-installed and linked plugins.
|
|
462
|
+
|
|
463
|
+
```
|
|
464
|
+
USAGE
|
|
465
|
+
$ csdx plugins:reset
|
|
418
466
|
```
|
|
419
467
|
|
|
468
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v4.1.10/src/commands/plugins/reset.ts)_
|
|
469
|
+
|
|
420
470
|
## `csdx plugins:uninstall PLUGIN...`
|
|
421
471
|
|
|
422
472
|
Removes a plugin from the CLI.
|
|
@@ -438,9 +488,12 @@ DESCRIPTION
|
|
|
438
488
|
ALIASES
|
|
439
489
|
$ csdx plugins:unlink
|
|
440
490
|
$ csdx plugins:remove
|
|
491
|
+
|
|
492
|
+
EXAMPLES
|
|
493
|
+
$ csdx plugins:uninstall myplugin
|
|
441
494
|
```
|
|
442
495
|
|
|
443
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
496
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v4.1.10/src/commands/plugins/uninstall.ts)_
|
|
444
497
|
|
|
445
498
|
## `csdx plugins:uninstall PLUGIN...`
|
|
446
499
|
|
|
@@ -463,6 +516,9 @@ DESCRIPTION
|
|
|
463
516
|
ALIASES
|
|
464
517
|
$ csdx plugins:unlink
|
|
465
518
|
$ csdx plugins:remove
|
|
519
|
+
|
|
520
|
+
EXAMPLES
|
|
521
|
+
$ csdx plugins:unlink myplugin
|
|
466
522
|
```
|
|
467
523
|
|
|
468
524
|
## `csdx plugins:update`
|
|
@@ -481,5 +537,5 @@ DESCRIPTION
|
|
|
481
537
|
Update installed plugins.
|
|
482
538
|
```
|
|
483
539
|
|
|
484
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
540
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v4.1.10/src/commands/plugins/update.ts)_
|
|
485
541
|
<!-- commandsstop -->
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import config from './config';
|
|
2
2
|
import { BaseCommand } from './base-command';
|
|
3
|
-
import { ContentTypeStruct } from './types';
|
|
3
|
+
import { CommandNames, ContentTypeStruct } from './types';
|
|
4
4
|
export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseCommand> {
|
|
5
5
|
private currentCommand;
|
|
6
6
|
get fixStatus(): {
|
|
@@ -16,7 +16,7 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
|
|
|
16
16
|
* @param {string} command - The `command` parameter is a string that represents the current command
|
|
17
17
|
* being executed.
|
|
18
18
|
*/
|
|
19
|
-
start(command:
|
|
19
|
+
start(command: CommandNames): Promise<void>;
|
|
20
20
|
/**
|
|
21
21
|
* The `scan` function performs an audit on different modules (content-types, global-fields, and
|
|
22
22
|
* entries) and returns the missing references for each module.
|
|
@@ -56,6 +56,10 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
56
56
|
else {
|
|
57
57
|
this.log(this.messages.NO_MISSING_REF_FOUND, 'info');
|
|
58
58
|
this.log('');
|
|
59
|
+
if (this.currentCommand === 'cm:stacks:audit:fix' && (0, fs_1.existsSync)(this.sharedConfig.basePath)) {
|
|
60
|
+
// NOTE Clean up the backup dir if no issue found while audit the content
|
|
61
|
+
(0, fs_1.rmSync)(this.sharedConfig.basePath, { recursive: true });
|
|
62
|
+
}
|
|
59
63
|
}
|
|
60
64
|
}
|
|
61
65
|
/**
|
|
@@ -227,14 +231,10 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
227
231
|
* @returns The function `prepareCSV` returns a Promise that resolves to `void`.
|
|
228
232
|
*/
|
|
229
233
|
prepareCSV(moduleName, listOfMissingRefs) {
|
|
230
|
-
const csvStream = csv.format({ headers: true });
|
|
231
234
|
const csvPath = (0, path_1.join)(this.sharedConfig.reportPath, `${moduleName}.csv`);
|
|
232
|
-
const assetFileStream = (0, fs_1.createWriteStream)(csvPath);
|
|
233
|
-
assetFileStream.on('error', (error) => {
|
|
234
|
-
throw error;
|
|
235
|
-
});
|
|
236
235
|
return new Promise((resolve, reject) => {
|
|
237
|
-
|
|
236
|
+
// file deepcode ignore MissingClose: Will auto close once csv stream end
|
|
237
|
+
const ws = (0, fs_1.createWriteStream)(csvPath).on('error', reject);
|
|
238
238
|
const defaultColumns = Object.keys(types_1.OutputColumn);
|
|
239
239
|
const userDefinedColumns = this.sharedConfig.flags.columns ? this.sharedConfig.flags.columns.split(',') : null;
|
|
240
240
|
let missingRefs = Object.values(listOfMissingRefs).flat();
|
|
@@ -245,6 +245,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
245
245
|
const [column, value] = this.sharedConfig.flags.filter.split('=');
|
|
246
246
|
missingRefs = missingRefs.filter((row) => row[types_1.OutputColumn[column]] === value);
|
|
247
247
|
}
|
|
248
|
+
const rowData = [];
|
|
248
249
|
for (const issue of missingRefs) {
|
|
249
250
|
let row = {};
|
|
250
251
|
for (const column of columns) {
|
|
@@ -254,9 +255,9 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
254
255
|
if (this.currentCommand === 'cm:stacks:audit:fix') {
|
|
255
256
|
row['Fix status'] = row.fixStatus;
|
|
256
257
|
}
|
|
257
|
-
|
|
258
|
+
rowData.push(row);
|
|
258
259
|
}
|
|
259
|
-
|
|
260
|
+
csv.write(rowData, { headers: true }).pipe(ws).on('error', reject).on('finish', resolve);
|
|
260
261
|
});
|
|
261
262
|
}
|
|
262
263
|
}
|
package/lib/base-command.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BaseCommand = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const merge_1 = tslib_1.__importDefault(require("lodash/merge"));
|
|
5
6
|
const fs_1 = require("fs");
|
|
6
7
|
const cli_command_1 = require("@contentstack/cli-command");
|
|
7
8
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
@@ -66,7 +67,7 @@ class BaseCommand extends cli_command_1.Command {
|
|
|
66
67
|
registerConfig() {
|
|
67
68
|
if (this.flags.config && (0, fs_1.existsSync)(this.flags.config)) {
|
|
68
69
|
try {
|
|
69
|
-
this.sharedConfig = JSON.parse((0, fs_1.readFileSync)(this.flags.config, { encoding: 'utf-8' }));
|
|
70
|
+
this.sharedConfig = (0, merge_1.default)(this.sharedConfig, JSON.parse((0, fs_1.readFileSync)(this.flags.config, { encoding: 'utf-8' })));
|
|
70
71
|
}
|
|
71
72
|
catch (error) {
|
|
72
73
|
this.log(error, 'error');
|
|
@@ -79,10 +80,12 @@ exports.BaseCommand = BaseCommand;
|
|
|
79
80
|
BaseCommand.baseFlags = {
|
|
80
81
|
config: cli_utilities_1.Flags.string({
|
|
81
82
|
char: 'c',
|
|
83
|
+
helpGroup: 'COMMON',
|
|
82
84
|
description: messages_1.commonMsg.CONFIG,
|
|
83
85
|
}),
|
|
84
86
|
'data-dir': cli_utilities_1.Flags.string({
|
|
85
87
|
char: 'd',
|
|
88
|
+
helpGroup: 'COMMON',
|
|
86
89
|
description: messages_1.commonMsg.DATA_DIR,
|
|
87
90
|
}),
|
|
88
91
|
};
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
5
5
|
const config_1 = tslib_1.__importDefault(require("../../../../config"));
|
|
6
|
+
const util_1 = require("../../../../util");
|
|
6
7
|
const messages_1 = require("../../../../messages");
|
|
7
8
|
const audit_base_command_1 = require("../../../../audit-base-command");
|
|
8
9
|
class AuditFix extends audit_base_command_1.AuditBaseCommand {
|
|
@@ -29,6 +30,7 @@ AuditFix.examples = [
|
|
|
29
30
|
'$ <%= config.bin %> <%= command.id %> --copy-dir',
|
|
30
31
|
'$ <%= config.bin %> <%= command.id %> --report-path=<path> --copy-dir',
|
|
31
32
|
'$ <%= config.bin %> <%= command.id %> --report-path=<path> --copy-dir --csv',
|
|
33
|
+
'$ <%= config.bin %> <%= command.id %> --fix-only=reference,global_field --copy-dir',
|
|
32
34
|
'$ <%= config.bin %> <%= command.id %> --report-path=<path> --filter="name=<filter-value>"',
|
|
33
35
|
'$ <%= config.bin %> <%= command.id %> --report-path=<path> --modules=content-types --filter="name="<filter-value>" --copy-dir --copy-path=<path>',
|
|
34
36
|
];
|
|
@@ -46,10 +48,12 @@ AuditFix.flags = Object.assign({ 'report-path': cli_utilities_1.Flags.string({
|
|
|
46
48
|
}), 'copy-path': cli_utilities_1.Flags.string({
|
|
47
49
|
dependsOn: ['copy-dir'],
|
|
48
50
|
description: messages_1.auditFixMsg.BKP_PATH,
|
|
51
|
+
}), 'fix-only': cli_utilities_1.Flags.string({
|
|
52
|
+
multiple: true,
|
|
53
|
+
options: config_1.default['fix-fields'],
|
|
54
|
+
description: messages_1.auditFixMsg.FIX_OPTIONS,
|
|
49
55
|
}), yes: cli_utilities_1.Flags.boolean({
|
|
50
56
|
char: 'y',
|
|
51
57
|
hidden: true,
|
|
52
58
|
description: 'Use this flag to skip confirmation',
|
|
53
|
-
}) },
|
|
54
|
-
only: ['columns', 'sort', 'filter', 'csv', 'no-truncate'],
|
|
55
|
-
}));
|
|
59
|
+
}) }, (0, util_1.getTableFlags)());
|
|
@@ -5,6 +5,7 @@ const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
|
5
5
|
const config_1 = tslib_1.__importDefault(require("../../../../config"));
|
|
6
6
|
const messages_1 = require("../../../../messages");
|
|
7
7
|
const audit_base_command_1 = require("../../../../audit-base-command");
|
|
8
|
+
const util_1 = require("../../../../util");
|
|
8
9
|
class Audit extends audit_base_command_1.AuditBaseCommand {
|
|
9
10
|
/**
|
|
10
11
|
* The `run` function is an asynchronous function that performs an audit on different modules
|
|
@@ -16,7 +17,6 @@ class Audit extends audit_base_command_1.AuditBaseCommand {
|
|
|
16
17
|
}
|
|
17
18
|
catch (error) {
|
|
18
19
|
this.log(error instanceof Error ? error.message : error, 'error');
|
|
19
|
-
console.trace(error);
|
|
20
20
|
cli_utilities_1.ux.action.stop('Process failed.!');
|
|
21
21
|
this.exit(1);
|
|
22
22
|
}
|
|
@@ -41,6 +41,4 @@ Audit.flags = Object.assign({ 'report-path': cli_utilities_1.Flags.string({
|
|
|
41
41
|
multiple: true,
|
|
42
42
|
options: config_1.default.modules,
|
|
43
43
|
description: messages_1.auditMsg.MODULES,
|
|
44
|
-
}) },
|
|
45
|
-
only: ['columns', 'sort', 'filter', 'csv', 'no-truncate'],
|
|
46
|
-
}));
|
|
44
|
+
}) }, (0, util_1.getTableFlags)());
|
package/lib/config/index.d.ts
CHANGED
package/lib/config/index.js
CHANGED
|
@@ -4,6 +4,7 @@ const config = {
|
|
|
4
4
|
showTerminalOutput: true,
|
|
5
5
|
skipRefs: ['sys_assets'],
|
|
6
6
|
modules: ['content-types', 'global-fields', 'entries'],
|
|
7
|
+
'fix-fields': ['reference', 'global_field', 'json:rte', 'json:custom-field', 'blocks', 'group'],
|
|
7
8
|
moduleConfig: {
|
|
8
9
|
'content-types': {
|
|
9
10
|
name: 'content type',
|
package/lib/messages/index.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
declare const errors: {};
|
|
2
|
+
declare const tableColumnDescriptions: {
|
|
3
|
+
TABLE_COLUMNS: string;
|
|
4
|
+
TABLE_SORT: string;
|
|
5
|
+
TABLE_CSV: string;
|
|
6
|
+
TABLE_FILTER: string;
|
|
7
|
+
'TABLE_NO-TRUNCATE': string;
|
|
8
|
+
};
|
|
2
9
|
declare const commonMsg: {
|
|
3
10
|
CONFIG: string;
|
|
4
11
|
DATA_DIR: string;
|
|
@@ -20,11 +27,12 @@ declare const auditMsg: {
|
|
|
20
27
|
declare const auditFixMsg: {
|
|
21
28
|
COPY_DATA: string;
|
|
22
29
|
BKP_PATH: string;
|
|
30
|
+
FIX_OPTIONS: string;
|
|
23
31
|
FIXED_CONTENT_PATH_MAG: string;
|
|
24
32
|
EMPTY_FIX_MSG: string;
|
|
25
33
|
AUDIT_FIX_CMD_DESCRIPTION: string;
|
|
26
34
|
};
|
|
27
|
-
declare const messages: typeof errors & typeof commonMsg & typeof auditMsg & typeof auditFixMsg;
|
|
35
|
+
declare const messages: typeof errors & typeof commonMsg & typeof auditMsg & typeof auditFixMsg & typeof tableColumnDescriptions;
|
|
28
36
|
/**
|
|
29
37
|
* The function `$t` is a TypeScript function that replaces placeholders in a string with corresponding
|
|
30
38
|
* values from an object.
|
|
@@ -36,4 +44,4 @@ declare const messages: typeof errors & typeof commonMsg & typeof auditMsg & typ
|
|
|
36
44
|
*/
|
|
37
45
|
declare function $t(msg: string, args: Record<string, string>): string;
|
|
38
46
|
export default messages;
|
|
39
|
-
export { $t, errors, commonMsg, auditMsg, auditFixMsg };
|
|
47
|
+
export { $t, errors, commonMsg, auditMsg, auditFixMsg, tableColumnDescriptions };
|
package/lib/messages/index.js
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.auditFixMsg = exports.auditMsg = exports.commonMsg = exports.errors = exports.$t = void 0;
|
|
3
|
+
exports.tableColumnDescriptions = exports.auditFixMsg = exports.auditMsg = exports.commonMsg = exports.errors = exports.$t = void 0;
|
|
4
4
|
const errors = {};
|
|
5
5
|
exports.errors = errors;
|
|
6
|
+
const tableColumnDescriptions = {
|
|
7
|
+
TABLE_COLUMNS: 'Show only the specified columns (comma-separated)',
|
|
8
|
+
TABLE_SORT: "Property to sort by (prepend '-' for descending)",
|
|
9
|
+
TABLE_CSV: 'The output is in the CSV format [alias: --output=csv]',
|
|
10
|
+
TABLE_FILTER: 'Filter property by partial string matching. For example: name=foo',
|
|
11
|
+
'TABLE_NO-TRUNCATE': 'The output is not truncated to fit the screen',
|
|
12
|
+
};
|
|
13
|
+
exports.tableColumnDescriptions = tableColumnDescriptions;
|
|
6
14
|
const commonMsg = {
|
|
7
15
|
CONFIG: 'Path of the external config',
|
|
8
16
|
DATA_DIR: 'Path where the data is stored',
|
|
@@ -26,12 +34,13 @@ exports.auditMsg = auditMsg;
|
|
|
26
34
|
const auditFixMsg = {
|
|
27
35
|
COPY_DATA: 'Create backup from the original data.',
|
|
28
36
|
BKP_PATH: 'Provide the path to backup the copied data',
|
|
37
|
+
FIX_OPTIONS: 'Provide the list of fix options',
|
|
29
38
|
FIXED_CONTENT_PATH_MAG: 'You can locate the fixed content at {path}.',
|
|
30
39
|
EMPTY_FIX_MSG: 'Successfully removed the empty field/block found at {path} from the schema.',
|
|
31
40
|
AUDIT_FIX_CMD_DESCRIPTION: 'Perform audits and fix possible errors in the exported Contentstack data.',
|
|
32
41
|
};
|
|
33
42
|
exports.auditFixMsg = auditFixMsg;
|
|
34
|
-
const messages = Object.assign(Object.assign(Object.assign(Object.assign({}, errors), commonMsg), auditMsg), auditFixMsg);
|
|
43
|
+
const messages = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, errors), commonMsg), auditMsg), auditFixMsg), tableColumnDescriptions);
|
|
35
44
|
/**
|
|
36
45
|
* The function `$t` is a TypeScript function that replaces placeholders in a string with corresponding
|
|
37
46
|
* values from an object.
|
|
@@ -45,7 +54,8 @@ function $t(msg, args) {
|
|
|
45
54
|
if (!msg)
|
|
46
55
|
return '';
|
|
47
56
|
for (const key of Object.keys(args)) {
|
|
48
|
-
|
|
57
|
+
const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
58
|
+
msg = msg.replace(new RegExp(`{${escapedKey}}`, 'g'), args[key]);
|
|
49
59
|
}
|
|
50
60
|
return msg;
|
|
51
61
|
}
|
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const find_1 = tslib_1.__importDefault(require("lodash/find"));
|
|
5
|
-
const core_1 = require("@oclif/core");
|
|
6
5
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
7
6
|
const path_1 = require("path");
|
|
8
7
|
const fs_1 = require("fs");
|
|
8
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
9
9
|
const messages_1 = require("../messages");
|
|
10
10
|
/* The `ContentType` class is responsible for scanning content types, looking for references, and
|
|
11
11
|
generating a report in JSON and CSV formats. */
|
|
12
12
|
class ContentType {
|
|
13
13
|
constructor({ log, fix, config, moduleName, ctSchema, gfSchema }) {
|
|
14
|
+
this.inMemoryFix = false;
|
|
14
15
|
this.schema = [];
|
|
15
16
|
this.missingRefs = {};
|
|
16
17
|
this.log = log;
|
|
@@ -29,6 +30,7 @@ class ContentType {
|
|
|
29
30
|
*/
|
|
30
31
|
async run(returnFixSchema = false) {
|
|
31
32
|
var _a;
|
|
33
|
+
this.inMemoryFix = returnFixSchema;
|
|
32
34
|
if (!(0, fs_1.existsSync)(this.folderPath)) {
|
|
33
35
|
throw new Error((0, messages_1.$t)(messages_1.auditMsg.NOT_VALID_PATH, { path: this.folderPath }));
|
|
34
36
|
}
|
|
@@ -59,12 +61,15 @@ class ContentType {
|
|
|
59
61
|
* JSON to the specified file path.
|
|
60
62
|
*/
|
|
61
63
|
async writeFixContent() {
|
|
64
|
+
var _a;
|
|
62
65
|
let canWrite = true;
|
|
63
|
-
if (this.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
if (!this.inMemoryFix && this.fix) {
|
|
67
|
+
if (!this.config.flags['copy-dir']) {
|
|
68
|
+
canWrite = (_a = this.config.flags.yes) !== null && _a !== void 0 ? _a : (await cli_utilities_1.ux.confirm(messages_1.commonMsg.FIX_CONFIRMATION));
|
|
69
|
+
}
|
|
70
|
+
if (canWrite) {
|
|
71
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(this.folderPath, this.config.moduleConfig[this.moduleName].fileName), JSON.stringify(this.schema));
|
|
72
|
+
}
|
|
68
73
|
}
|
|
69
74
|
}
|
|
70
75
|
/**
|
|
@@ -79,11 +84,14 @@ class ContentType {
|
|
|
79
84
|
* object in the array should have a `uid` and `name` property.
|
|
80
85
|
*/
|
|
81
86
|
async lookForReference(tree, field) {
|
|
82
|
-
var _a;
|
|
87
|
+
var _a, _b;
|
|
88
|
+
const fixTypes = (_a = this.config.flags['fix-only']) !== null && _a !== void 0 ? _a : this.config['fix-fields'];
|
|
83
89
|
if (this.fix) {
|
|
84
90
|
field.schema = this.runFixOnSchema(tree, field.schema);
|
|
85
91
|
}
|
|
86
|
-
for (let child of (
|
|
92
|
+
for (let child of (_b = field.schema) !== null && _b !== void 0 ? _b : []) {
|
|
93
|
+
if (!fixTypes.includes(child.data_type) && child.data_type !== 'json')
|
|
94
|
+
continue;
|
|
87
95
|
switch (child.data_type) {
|
|
88
96
|
case 'reference':
|
|
89
97
|
this.missingRefs[this.currentUid].push(...this.validateReferenceField([...tree, { uid: field.uid, name: child.display_name }], child));
|
|
@@ -93,9 +101,13 @@ class ContentType {
|
|
|
93
101
|
break;
|
|
94
102
|
case 'json':
|
|
95
103
|
if (child.field_metadata.extension) {
|
|
104
|
+
if (!fixTypes.includes('json:custom-field'))
|
|
105
|
+
continue;
|
|
96
106
|
// NOTE Custom field type
|
|
97
107
|
}
|
|
98
108
|
else if (child.field_metadata.allow_json_rte) {
|
|
109
|
+
if (!fixTypes.includes('json:rte'))
|
|
110
|
+
continue;
|
|
99
111
|
// NOTE JSON RTE field type
|
|
100
112
|
this.missingRefs[this.currentUid].push(...this.validateJsonRTEFields([...tree, { uid: child.uid, name: child.display_name }], child));
|
|
101
113
|
}
|
|
@@ -131,6 +143,18 @@ class ContentType {
|
|
|
131
143
|
*/
|
|
132
144
|
async validateGlobalField(tree, field) {
|
|
133
145
|
// NOTE Any GlobalField related logic can be added here
|
|
146
|
+
if (!field.schema && !this.fix) {
|
|
147
|
+
this.missingRefs[this.currentUid].push({
|
|
148
|
+
tree,
|
|
149
|
+
ct_uid: this.currentUid,
|
|
150
|
+
name: this.currentTitle,
|
|
151
|
+
data_type: field.data_type,
|
|
152
|
+
display_name: field.display_name,
|
|
153
|
+
missingRefs: 'Empty schema found',
|
|
154
|
+
treeStr: tree.map(({ name }) => name).join(' ➜ '),
|
|
155
|
+
});
|
|
156
|
+
return void 0;
|
|
157
|
+
}
|
|
134
158
|
await this.lookForReference(tree, field);
|
|
135
159
|
}
|
|
136
160
|
/**
|
|
@@ -233,7 +257,11 @@ class ContentType {
|
|
|
233
257
|
// NOTE Global field Fix
|
|
234
258
|
return schema
|
|
235
259
|
.map((field) => {
|
|
260
|
+
var _a;
|
|
236
261
|
const { data_type } = field;
|
|
262
|
+
const fixTypes = (_a = this.config.flags['fix-only']) !== null && _a !== void 0 ? _a : this.config['fix-fields'];
|
|
263
|
+
if (!fixTypes.includes(data_type) && data_type !== 'json')
|
|
264
|
+
return field;
|
|
237
265
|
switch (data_type) {
|
|
238
266
|
case 'global_field':
|
|
239
267
|
return this.fixGlobalFieldReferences(tree, field);
|
|
@@ -242,9 +270,14 @@ class ContentType {
|
|
|
242
270
|
if (data_type === 'json') {
|
|
243
271
|
if (field.field_metadata.extension) {
|
|
244
272
|
// NOTE Custom field type
|
|
273
|
+
if (!fixTypes.includes('json:custom-field'))
|
|
274
|
+
return field;
|
|
275
|
+
// NOTE Fix logic
|
|
245
276
|
return field;
|
|
246
277
|
}
|
|
247
278
|
else if (field.field_metadata.allow_json_rte) {
|
|
279
|
+
if (!fixTypes.includes('json:rte'))
|
|
280
|
+
return field;
|
|
248
281
|
return this.fixMissingReferences(tree, field);
|
|
249
282
|
}
|
|
250
283
|
}
|
|
@@ -279,6 +312,7 @@ class ContentType {
|
|
|
279
312
|
* doesn't.
|
|
280
313
|
*/
|
|
281
314
|
fixGlobalFieldReferences(tree, field) {
|
|
315
|
+
var _a;
|
|
282
316
|
const { reference_to, display_name, data_type } = field;
|
|
283
317
|
if (reference_to && data_type === 'global_field') {
|
|
284
318
|
tree = [...tree, { uid: field.uid, name: field.display_name, data_type: field.data_type }];
|
|
@@ -289,12 +323,28 @@ class ContentType {
|
|
|
289
323
|
data_type,
|
|
290
324
|
display_name,
|
|
291
325
|
fixStatus: 'Fixed',
|
|
292
|
-
missingRefs: [reference_to],
|
|
293
326
|
ct_uid: this.currentUid,
|
|
294
327
|
name: this.currentTitle,
|
|
328
|
+
missingRefs: [reference_to],
|
|
295
329
|
treeStr: tree.map(({ name }) => name).join(' ➜ '),
|
|
296
330
|
});
|
|
297
331
|
}
|
|
332
|
+
else if (!field.schema) {
|
|
333
|
+
const gfSchema = (_a = (0, find_1.default)(this.gfSchema, { uid: field.reference_to })) === null || _a === void 0 ? void 0 : _a.schema;
|
|
334
|
+
if (gfSchema) {
|
|
335
|
+
field.schema = gfSchema;
|
|
336
|
+
this.missingRefs[this.currentUid].push({
|
|
337
|
+
tree,
|
|
338
|
+
data_type,
|
|
339
|
+
display_name,
|
|
340
|
+
fixStatus: 'Fixed',
|
|
341
|
+
ct_uid: this.currentUid,
|
|
342
|
+
name: this.currentTitle,
|
|
343
|
+
missingRefs: 'Empty schema found',
|
|
344
|
+
treeStr: tree.map(({ name }) => name).join(' ➜ '),
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
298
348
|
return refExist ? field : null;
|
|
299
349
|
}
|
|
300
350
|
return field;
|
package/lib/modules/entries.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import auditConfig from '../config';
|
|
|
2
2
|
import { LogFn, Locale, ConfigType, EntryStruct, EntryFieldType, ModularBlockType, ContentTypeStruct, CtConstructorParam, GroupFieldDataType, GlobalFieldDataType, JsonRTEFieldDataType, ContentTypeSchemaType, ModularBlocksDataType, ModuleConstructorParam, ReferenceFieldDataType, EntryRefErrorReturnType, EntryGroupFieldDataType, EntryGlobalFieldDataType, EntryJsonRTEFieldDataType, EntryModularBlocksDataType, EntryReferenceFieldDataType } from '../types';
|
|
3
3
|
export default class Entries {
|
|
4
4
|
log: LogFn;
|
|
5
|
-
|
|
5
|
+
protected fix: boolean;
|
|
6
6
|
fileName: string;
|
|
7
7
|
locales: Locale[];
|
|
8
8
|
config: ConfigType;
|
|
@@ -11,7 +11,7 @@ export default class Entries {
|
|
|
11
11
|
currentTitle: string;
|
|
12
12
|
gfSchema: ContentTypeStruct[];
|
|
13
13
|
ctSchema: ContentTypeStruct[];
|
|
14
|
-
|
|
14
|
+
protected entries: Record<string, EntryStruct>;
|
|
15
15
|
protected missingRefs: Record<string, any>;
|
|
16
16
|
entryMetaData: Record<string, any>[];
|
|
17
17
|
moduleName: keyof typeof auditConfig.moduleConfig;
|
package/lib/modules/entries.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
const find_1 = tslib_1.__importDefault(require("lodash/find"));
|
|
5
|
-
const core_1 = require("@oclif/core");
|
|
6
5
|
const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
7
6
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
8
7
|
const path_1 = require("path");
|
|
@@ -10,6 +9,7 @@ const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
|
10
9
|
const fs_1 = require("fs");
|
|
11
10
|
const content_types_1 = tslib_1.__importDefault(require("./content-types"));
|
|
12
11
|
const messages_1 = require("../messages");
|
|
12
|
+
const global_fields_1 = tslib_1.__importDefault(require("./global-fields"));
|
|
13
13
|
class Entries {
|
|
14
14
|
constructor({ log, fix, config, moduleName, ctSchema, gfSchema }) {
|
|
15
15
|
this.missingRefs = {};
|
|
@@ -38,7 +38,7 @@ class Entries {
|
|
|
38
38
|
for (const { code } of this.locales) {
|
|
39
39
|
for (const ctSchema of this.ctSchema) {
|
|
40
40
|
const basePath = (0, path_1.join)(this.folderPath, ctSchema.uid, code);
|
|
41
|
-
const fsUtility = new cli_utilities_1.FsUtility({ basePath, indexFileName: 'index.json' });
|
|
41
|
+
const fsUtility = new cli_utilities_1.FsUtility({ basePath, indexFileName: 'index.json', createDirIfNotExist: false });
|
|
42
42
|
const indexer = fsUtility.indexFileContent;
|
|
43
43
|
for (const fileIndex in indexer) {
|
|
44
44
|
const entries = (await fsUtility.readChunkFiles.next());
|
|
@@ -89,11 +89,11 @@ class Entries {
|
|
|
89
89
|
ctSchema: this.ctSchema,
|
|
90
90
|
gfSchema: this.gfSchema,
|
|
91
91
|
}).run(true));
|
|
92
|
-
this.gfSchema = (await new
|
|
92
|
+
this.gfSchema = (await new global_fields_1.default({
|
|
93
93
|
fix: true,
|
|
94
94
|
log: () => { },
|
|
95
95
|
config: this.config,
|
|
96
|
-
moduleName: '
|
|
96
|
+
moduleName: 'global-fields',
|
|
97
97
|
ctSchema: this.ctSchema,
|
|
98
98
|
gfSchema: this.gfSchema,
|
|
99
99
|
}).run(true));
|
|
@@ -104,11 +104,13 @@ class Entries {
|
|
|
104
104
|
*/
|
|
105
105
|
async writeFixContent(filePath, schema) {
|
|
106
106
|
let canWrite = true;
|
|
107
|
-
if (this.fix
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
(
|
|
107
|
+
if (this.fix) {
|
|
108
|
+
if (!this.config.flags['copy-dir']) {
|
|
109
|
+
canWrite = this.config.flags.yes || (await cli_utilities_1.ux.confirm(messages_1.commonMsg.FIX_CONFIRMATION));
|
|
110
|
+
}
|
|
111
|
+
if (canWrite) {
|
|
112
|
+
(0, fs_1.writeFileSync)(filePath, JSON.stringify(schema));
|
|
113
|
+
}
|
|
112
114
|
}
|
|
113
115
|
}
|
|
114
116
|
/**
|
|
@@ -131,7 +133,7 @@ class Entries {
|
|
|
131
133
|
for (const child of (_a = field.schema) !== null && _a !== void 0 ? _a : []) {
|
|
132
134
|
const { uid } = child;
|
|
133
135
|
if (!(entry === null || entry === void 0 ? void 0 : entry[uid]))
|
|
134
|
-
|
|
136
|
+
continue;
|
|
135
137
|
switch (child.data_type) {
|
|
136
138
|
case 'reference':
|
|
137
139
|
this.missingRefs[this.currentUid].push(...this.validateReferenceField([...tree, { uid: child.uid, name: child.display_name, field: uid }], child, entry[uid]));
|
|
@@ -203,7 +205,6 @@ class Entries {
|
|
|
203
205
|
*/
|
|
204
206
|
validateJsonRTEFields(tree, fieldStructure, field) {
|
|
205
207
|
var _a;
|
|
206
|
-
// const missingRefIndex = []
|
|
207
208
|
// NOTE Other possible reference logic will be added related to JSON RTE (Ex missing assets, extensions etc.,)
|
|
208
209
|
for (const index in (_a = field === null || field === void 0 ? void 0 : field.children) !== null && _a !== void 0 ? _a : []) {
|
|
209
210
|
const child = field.children[index];
|
|
@@ -6,7 +6,7 @@ export default class GlobalField extends ContentType {
|
|
|
6
6
|
* references.
|
|
7
7
|
* @returns the value of the variable `missingRefs`.
|
|
8
8
|
*/
|
|
9
|
-
run(): Promise<Record<string, any>>;
|
|
9
|
+
run(returnFixSchema?: boolean): Promise<Record<string, any>>;
|
|
10
10
|
/**
|
|
11
11
|
* The function validates a field containing modular blocks by traversing each block and checking for
|
|
12
12
|
* references in a given tree.
|
|
@@ -8,9 +8,9 @@ class GlobalField extends content_types_1.default {
|
|
|
8
8
|
* references.
|
|
9
9
|
* @returns the value of the variable `missingRefs`.
|
|
10
10
|
*/
|
|
11
|
-
async run() {
|
|
11
|
+
async run(returnFixSchema = false) {
|
|
12
12
|
// NOTE add any validation if required
|
|
13
|
-
const missingRefs = await super.run();
|
|
13
|
+
const missingRefs = await super.run(returnFixSchema);
|
|
14
14
|
return missingRefs;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
@@ -73,4 +73,4 @@ declare enum OutputColumn {
|
|
|
73
73
|
'Missing references' = "missingRefs",
|
|
74
74
|
Path = "treeStr"
|
|
75
75
|
}
|
|
76
|
-
export { CtConstructorParam, ContentTypeStruct, ModuleConstructorParam, ReferenceFieldDataType, GlobalFieldDataType, CustomFieldDataType, JsonRTEFieldDataType, GroupFieldDataType, ModularBlocksDataType, RefErrorReturnType, ModularBlocksSchemaTypes, ModularBlockType, OutputColumn, ContentTypeSchemaType, };
|
|
76
|
+
export { CtConstructorParam, ContentTypeStruct, ModuleConstructorParam, ReferenceFieldDataType, GlobalFieldDataType, CustomFieldDataType, JsonRTEFieldDataType, GroupFieldDataType, ModularBlocksDataType, RefErrorReturnType, ModularBlocksSchemaTypes, ModularBlockType, OutputColumn, ContentTypeSchemaType, GlobalFieldSchemaTypes, };
|
package/lib/types/index.d.ts
CHANGED
package/lib/types/index.js
CHANGED
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
tslib_1.__exportStar(require("./utils"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./common"), exports);
|
|
5
6
|
tslib_1.__exportStar(require("./entries"), exports);
|
|
6
7
|
tslib_1.__exportStar(require("./content-types"), exports);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IFlags, IncludeFlags } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* The function `getTableFlags` returns a set of table flags based on the specified columns, with
|
|
4
|
+
* updated descriptions and help groups.
|
|
5
|
+
* @param {(keyof IFlags)[]} columns - An optional array of column keys from the IFlags interface. The
|
|
6
|
+
* default value is ['columns', 'sort', 'filter', 'csv', 'no-truncate'].
|
|
7
|
+
* @returns an object of type `IncludeFlags<IFlags, keyof IFlags>`.
|
|
8
|
+
*/
|
|
9
|
+
declare function getTableFlags(columns?: (keyof IFlags)[]): IncludeFlags<IFlags, keyof IFlags>;
|
|
10
|
+
export { getTableFlags };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTableFlags = void 0;
|
|
4
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
5
|
+
const messages_1 = require("../messages");
|
|
6
|
+
/**
|
|
7
|
+
* The function `getTableFlags` returns a set of table flags based on the specified columns, with
|
|
8
|
+
* updated descriptions and help groups.
|
|
9
|
+
* @param {(keyof IFlags)[]} columns - An optional array of column keys from the IFlags interface. The
|
|
10
|
+
* default value is ['columns', 'sort', 'filter', 'csv', 'no-truncate'].
|
|
11
|
+
* @returns an object of type `IncludeFlags<IFlags, keyof IFlags>`.
|
|
12
|
+
*/
|
|
13
|
+
function getTableFlags(columns = ['columns', 'sort', 'filter', 'csv', 'no-truncate']) {
|
|
14
|
+
const flags = cli_utilities_1.ux.table.flags({
|
|
15
|
+
only: columns,
|
|
16
|
+
});
|
|
17
|
+
// NOTE Assign group and update Descriptions
|
|
18
|
+
columns.forEach((element) => {
|
|
19
|
+
var _a;
|
|
20
|
+
flags[element].helpGroup = 'TABLE';
|
|
21
|
+
const descriptionKey = `TABLE_${element.toUpperCase()}`;
|
|
22
|
+
flags[element].description = (_a = messages_1.tableColumnDescriptions[descriptionKey]) !== null && _a !== void 0 ? _a : flags[element].description;
|
|
23
|
+
});
|
|
24
|
+
return flags;
|
|
25
|
+
}
|
|
26
|
+
exports.getTableFlags = getTableFlags;
|
package/lib/util/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './flags';
|
|
2
|
+
export { default as Logger, print } from './log';
|
package/lib/util/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.Logger = void 0;
|
|
3
|
+
exports.print = exports.Logger = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
tslib_1.__exportStar(require("./flags"), exports);
|
|
7
6
|
var log_1 = require("./log");
|
|
8
|
-
Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return __importDefault(log_1).default; } });
|
|
7
|
+
Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return tslib_1.__importDefault(log_1).default; } });
|
|
8
|
+
Object.defineProperty(exports, "print", { enumerable: true, get: function () { return log_1.print; } });
|
package/lib/util/log.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.print = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const map_1 = tslib_1.__importDefault(require("lodash/map"));
|
|
6
6
|
const winston_1 = tslib_1.__importDefault(require("winston"));
|
|
7
|
-
const fs_1 = require("fs");
|
|
8
7
|
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
9
8
|
const replace_1 = tslib_1.__importDefault(require("lodash/replace"));
|
|
10
9
|
const isObject_1 = tslib_1.__importDefault(require("lodash/isObject"));
|
|
@@ -52,26 +51,18 @@ class Logger {
|
|
|
52
51
|
if (logType === 'error') {
|
|
53
52
|
consoleOptions.level = logType;
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
transports:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
loggerOptions.levels = { error: 0 };
|
|
66
|
-
}
|
|
67
|
-
return winston_1.default.createLogger(loggerOptions);
|
|
54
|
+
const filename = (0, path_1.normalize)((0, path_1.resolve)(this.config.basePath, 'logs', `${logType}.log`)).replace(/^(\.\.(\/|\\|$))+/, '');
|
|
55
|
+
const loggerOptions = {
|
|
56
|
+
transports: [
|
|
57
|
+
new winston_1.default.transports.File(Object.assign(Object.assign({}, this.loggerOptions), { level: logType, filename })),
|
|
58
|
+
new winston_1.default.transports.Console(consoleOptions),
|
|
59
|
+
],
|
|
60
|
+
levels: customLevels.levels,
|
|
61
|
+
};
|
|
62
|
+
if (logType === 'error') {
|
|
63
|
+
loggerOptions.levels = { error: 0 };
|
|
68
64
|
}
|
|
69
|
-
winston_1.default
|
|
70
|
-
.createLogger({
|
|
71
|
-
transports: [new winston_1.default.transports.Console(consoleOptions)],
|
|
72
|
-
})
|
|
73
|
-
.error('Provided base path is not valid');
|
|
74
|
-
throw new Error('Provided base path is not valid');
|
|
65
|
+
return winston_1.default.createLogger(loggerOptions);
|
|
75
66
|
}
|
|
76
67
|
/**
|
|
77
68
|
* The function `log` takes a message and an optional log type, and logs the message using different
|
|
@@ -108,7 +99,7 @@ class Logger {
|
|
|
108
99
|
let returnStr = '';
|
|
109
100
|
const replaceCredentials = (item) => {
|
|
110
101
|
try {
|
|
111
|
-
return JSON.stringify(item).replace(/authtoken"
|
|
102
|
+
return JSON.stringify(item).replace(/"authtoken":\s*".*?"/, '"authtoken": "..."');
|
|
112
103
|
}
|
|
113
104
|
catch (error) { }
|
|
114
105
|
return item;
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.3.1",
|
|
3
3
|
"commands": {
|
|
4
4
|
"cm:stacks:audit:fix": {
|
|
5
5
|
"id": "cm:stacks:audit:fix",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"$ <%= config.bin %> <%= command.id %> --copy-dir",
|
|
17
17
|
"$ <%= config.bin %> <%= command.id %> --report-path=<path> --copy-dir",
|
|
18
18
|
"$ <%= config.bin %> <%= command.id %> --report-path=<path> --copy-dir --csv",
|
|
19
|
+
"$ <%= config.bin %> <%= command.id %> --fix-only=reference,global_field --copy-dir",
|
|
19
20
|
"$ <%= config.bin %> <%= command.id %> --report-path=<path> --filter=\"name=<filter-value>\"",
|
|
20
21
|
"$ <%= config.bin %> <%= command.id %> --report-path=<path> --modules=content-types --filter=\"name=\"<filter-value>\" --copy-dir --copy-path=<path>"
|
|
21
22
|
],
|
|
@@ -25,6 +26,7 @@
|
|
|
25
26
|
"type": "option",
|
|
26
27
|
"char": "c",
|
|
27
28
|
"description": "Path of the external config",
|
|
29
|
+
"helpGroup": "COMMON",
|
|
28
30
|
"multiple": false
|
|
29
31
|
},
|
|
30
32
|
"data-dir": {
|
|
@@ -32,6 +34,7 @@
|
|
|
32
34
|
"type": "option",
|
|
33
35
|
"char": "d",
|
|
34
36
|
"description": "Path where the data is stored",
|
|
37
|
+
"helpGroup": "COMMON",
|
|
35
38
|
"multiple": false
|
|
36
39
|
},
|
|
37
40
|
"report-path": {
|
|
@@ -73,6 +76,20 @@
|
|
|
73
76
|
"copy-dir"
|
|
74
77
|
]
|
|
75
78
|
},
|
|
79
|
+
"fix-only": {
|
|
80
|
+
"name": "fix-only",
|
|
81
|
+
"type": "option",
|
|
82
|
+
"description": "Provide the list of fix options",
|
|
83
|
+
"multiple": true,
|
|
84
|
+
"options": [
|
|
85
|
+
"reference",
|
|
86
|
+
"global_field",
|
|
87
|
+
"json:rte",
|
|
88
|
+
"json:custom-field",
|
|
89
|
+
"blocks",
|
|
90
|
+
"group"
|
|
91
|
+
]
|
|
92
|
+
},
|
|
76
93
|
"yes": {
|
|
77
94
|
"name": "yes",
|
|
78
95
|
"type": "boolean",
|
|
@@ -84,7 +101,8 @@
|
|
|
84
101
|
"columns": {
|
|
85
102
|
"name": "columns",
|
|
86
103
|
"type": "option",
|
|
87
|
-
"description": "only
|
|
104
|
+
"description": "Show only the specified columns (comma-separated)",
|
|
105
|
+
"helpGroup": "TABLE",
|
|
88
106
|
"multiple": false,
|
|
89
107
|
"exclusive": [
|
|
90
108
|
"extended"
|
|
@@ -93,19 +111,22 @@
|
|
|
93
111
|
"sort": {
|
|
94
112
|
"name": "sort",
|
|
95
113
|
"type": "option",
|
|
96
|
-
"description": "
|
|
114
|
+
"description": "Property to sort by (prepend '-' for descending)",
|
|
115
|
+
"helpGroup": "TABLE",
|
|
97
116
|
"multiple": false
|
|
98
117
|
},
|
|
99
118
|
"filter": {
|
|
100
119
|
"name": "filter",
|
|
101
120
|
"type": "option",
|
|
102
|
-
"description": "
|
|
121
|
+
"description": "Filter property by partial string matching. For example: name=foo",
|
|
122
|
+
"helpGroup": "TABLE",
|
|
103
123
|
"multiple": false
|
|
104
124
|
},
|
|
105
125
|
"csv": {
|
|
106
126
|
"name": "csv",
|
|
107
127
|
"type": "boolean",
|
|
108
|
-
"description": "output is
|
|
128
|
+
"description": "The output is in the CSV format [alias: --output=csv]",
|
|
129
|
+
"helpGroup": "TABLE",
|
|
109
130
|
"allowNo": false,
|
|
110
131
|
"exclusive": [
|
|
111
132
|
"no-truncate"
|
|
@@ -114,7 +135,8 @@
|
|
|
114
135
|
"no-truncate": {
|
|
115
136
|
"name": "no-truncate",
|
|
116
137
|
"type": "boolean",
|
|
117
|
-
"description": "
|
|
138
|
+
"description": "The output is not truncated to fit the screen",
|
|
139
|
+
"helpGroup": "TABLE",
|
|
118
140
|
"allowNo": false,
|
|
119
141
|
"exclusive": [
|
|
120
142
|
"csv"
|
|
@@ -147,6 +169,7 @@
|
|
|
147
169
|
"type": "option",
|
|
148
170
|
"char": "c",
|
|
149
171
|
"description": "Path of the external config",
|
|
172
|
+
"helpGroup": "COMMON",
|
|
150
173
|
"multiple": false
|
|
151
174
|
},
|
|
152
175
|
"data-dir": {
|
|
@@ -154,6 +177,7 @@
|
|
|
154
177
|
"type": "option",
|
|
155
178
|
"char": "d",
|
|
156
179
|
"description": "Path where the data is stored",
|
|
180
|
+
"helpGroup": "COMMON",
|
|
157
181
|
"multiple": false
|
|
158
182
|
},
|
|
159
183
|
"report-path": {
|
|
@@ -183,7 +207,8 @@
|
|
|
183
207
|
"columns": {
|
|
184
208
|
"name": "columns",
|
|
185
209
|
"type": "option",
|
|
186
|
-
"description": "only
|
|
210
|
+
"description": "Show only the specified columns (comma-separated)",
|
|
211
|
+
"helpGroup": "TABLE",
|
|
187
212
|
"multiple": false,
|
|
188
213
|
"exclusive": [
|
|
189
214
|
"extended"
|
|
@@ -192,19 +217,22 @@
|
|
|
192
217
|
"sort": {
|
|
193
218
|
"name": "sort",
|
|
194
219
|
"type": "option",
|
|
195
|
-
"description": "
|
|
220
|
+
"description": "Property to sort by (prepend '-' for descending)",
|
|
221
|
+
"helpGroup": "TABLE",
|
|
196
222
|
"multiple": false
|
|
197
223
|
},
|
|
198
224
|
"filter": {
|
|
199
225
|
"name": "filter",
|
|
200
226
|
"type": "option",
|
|
201
|
-
"description": "
|
|
227
|
+
"description": "Filter property by partial string matching. For example: name=foo",
|
|
228
|
+
"helpGroup": "TABLE",
|
|
202
229
|
"multiple": false
|
|
203
230
|
},
|
|
204
231
|
"csv": {
|
|
205
232
|
"name": "csv",
|
|
206
233
|
"type": "boolean",
|
|
207
|
-
"description": "output is
|
|
234
|
+
"description": "The output is in the CSV format [alias: --output=csv]",
|
|
235
|
+
"helpGroup": "TABLE",
|
|
208
236
|
"allowNo": false,
|
|
209
237
|
"exclusive": [
|
|
210
238
|
"no-truncate"
|
|
@@ -213,7 +241,8 @@
|
|
|
213
241
|
"no-truncate": {
|
|
214
242
|
"name": "no-truncate",
|
|
215
243
|
"type": "boolean",
|
|
216
|
-
"description": "
|
|
244
|
+
"description": "The output is not truncated to fit the screen",
|
|
245
|
+
"helpGroup": "TABLE",
|
|
217
246
|
"allowNo": false,
|
|
218
247
|
"exclusive": [
|
|
219
248
|
"csv"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-audit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Contentstack audit plugin",
|
|
5
5
|
"author": "Contentstack CLI",
|
|
6
6
|
"homepage": "https://github.com/contentstack/cli",
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
"/oclif.manifest.json"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@contentstack/cli-command": "~1.2.
|
|
22
|
-
"@contentstack/cli-utilities": "~1.5.
|
|
21
|
+
"@contentstack/cli-command": "~1.2.16",
|
|
22
|
+
"@contentstack/cli-utilities": "~1.5.9",
|
|
23
23
|
"@oclif/plugin-help": "^5",
|
|
24
|
-
"@oclif/plugin-plugins": "^
|
|
24
|
+
"@oclif/plugin-plugins": "^4.1.9",
|
|
25
25
|
"chalk": "^4.1.2",
|
|
26
26
|
"fast-csv": "^4.3.6",
|
|
27
27
|
"fs-extra": "^11.1.1",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"winston": "^3.10.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
+
"@contentstack/cli-dev-dependencies": "^1.2.4",
|
|
33
34
|
"@oclif/test": "^2.0.3",
|
|
34
35
|
"@types/chai": "^4.3.5",
|
|
35
36
|
"@types/fs-extra": "^11.0.2",
|
|
@@ -38,11 +39,13 @@
|
|
|
38
39
|
"chai": "^4.3.7",
|
|
39
40
|
"eslint": "^8.43.0",
|
|
40
41
|
"eslint-config-oclif": "^4.0.0",
|
|
41
|
-
"eslint-config-oclif-typescript": "^
|
|
42
|
+
"eslint-config-oclif-typescript": "^3.0.8",
|
|
42
43
|
"mocha": "^10.2.0",
|
|
43
44
|
"nyc": "^15.1.0",
|
|
44
|
-
"oclif": "^3
|
|
45
|
+
"oclif": "^3",
|
|
45
46
|
"shx": "^0.3.4",
|
|
47
|
+
"sinon": "^17.0.0",
|
|
48
|
+
"ts-jest": "^29.1.1",
|
|
46
49
|
"ts-node": "^10.9.1",
|
|
47
50
|
"tslib": "^2.5.3",
|
|
48
51
|
"typescript": "^5.1.3"
|
|
@@ -81,4 +84,4 @@
|
|
|
81
84
|
"keywords": [
|
|
82
85
|
"oclif"
|
|
83
86
|
]
|
|
84
|
-
}
|
|
87
|
+
}
|