@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 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.2.1 linux-x64 node-v18.18.2
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
- --columns=<value> only show provided columns (comma-separated)
62
- --csv output is csv format [alias: --output=csv]
63
- --filter=<value> filter property by partial string matching, ex: name=foo
64
- --modules=<option>... Provide the list of modules to be audited
65
- <options: content-types|global-fields|entries>
66
- --no-truncate do not truncate output to fit screen
67
- --report-path=<value> Path to store the audit reports
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] [--columns <value> | ] [--sort <value>]
97
- [--filter <value>] [--csv | --no-truncate]
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
- --csv output is csv format [alias: --output=csv]
106
- --filter=<value> filter property by partial string matching, ex: name=foo
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
- --sort=<value> property to sort by (prepend '-' for descending)
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
- --columns=<value> only show provided columns (comma-separated)
146
- --csv output is csv format [alias: --output=csv]
147
- --filter=<value> filter property by partial string matching, ex: name=foo
148
- --modules=<option>... Provide the list of modules to be audited
149
- <options: content-types|global-fields|entries>
150
- --no-truncate do not truncate output to fit screen
151
- --report-path=<value> Path to store the audit reports
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] [--columns <value> | ] [--sort <value>]
183
- [--filter <value>] [--csv | --no-truncate]
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
- --csv output is csv format [alias: --output=csv]
192
- --filter=<value> filter property by partial string matching, ex: name=foo
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
- --sort=<value> property to sort by (prepend '-' for descending)
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/v3.8.4/src/commands/plugins/index.ts)_
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
- -v, --verbose
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:install myplugin
325
+ $ csdx plugins:add myplugin
295
326
 
296
- $ csdx plugins:install https://github.com/someuser/someplugin
327
+ $ csdx plugins:add https://github.com/someuser/someplugin
297
328
 
298
- $ csdx plugins:install someuser/someplugin
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/v3.8.4/src/commands/plugins/inspect.ts)_
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
- -v, --verbose
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/v3.8.4/src/commands/plugins/install.ts)_
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 Show CLI 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/v3.8.4/src/commands/plugins/link.ts)_
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/v3.8.4/src/commands/plugins/uninstall.ts)_
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/v3.8.4/src/commands/plugins/update.ts)_
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: string): Promise<void>;
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
- csvStream.pipe(assetFileStream).on('close', resolve).on('error', reject);
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
- csvStream.write(row);
258
+ rowData.push(row);
258
259
  }
259
- csvStream.end();
260
+ csv.write(rowData, { headers: true }).pipe(ws).on('error', reject).on('finish', resolve);
260
261
  });
261
262
  }
262
263
  }
@@ -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
- }) }, cli_utilities_1.ux.table.flags({
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
- }) }, cli_utilities_1.ux.table.flags({
45
- only: ['columns', 'sort', 'filter', 'csv', 'no-truncate'],
46
- }));
44
+ }) }, (0, util_1.getTableFlags)());
@@ -2,6 +2,7 @@ declare const config: {
2
2
  showTerminalOutput: boolean;
3
3
  skipRefs: string[];
4
4
  modules: string[];
5
+ 'fix-fields': string[];
5
6
  moduleConfig: {
6
7
  'content-types': {
7
8
  name: string;
@@ -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',
@@ -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 };
@@ -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
- msg = msg.replace(new RegExp(`{${key}}`, 'g'), args[key]);
57
+ const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
58
+ msg = msg.replace(new RegExp(`{${escapedKey}}`, 'g'), args[key]);
49
59
  }
50
60
  return msg;
51
61
  }
@@ -8,6 +8,7 @@ export default class ContentType {
8
8
  folderPath: string;
9
9
  currentUid: string;
10
10
  currentTitle: string;
11
+ inMemoryFix: boolean;
11
12
  gfSchema: ContentTypeStruct[];
12
13
  ctSchema: ContentTypeStruct[];
13
14
  protected schema: ContentTypeStruct[];
@@ -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.fix && !this.config.flags['copy-dir']) {
64
- canWrite = this.config.flags.yes || (await core_1.ux.confirm(messages_1.commonMsg.FIX_CONFIRMATION));
65
- }
66
- if (canWrite) {
67
- (0, fs_1.writeFileSync)((0, path_1.join)(this.folderPath, this.config.moduleConfig[this.moduleName].fileName), JSON.stringify(this.schema));
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 (_a = field.schema) !== null && _a !== void 0 ? _a : []) {
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;
@@ -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
- private fix;
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
- private entries;
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;
@@ -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 content_types_1.default({
92
+ this.gfSchema = (await new global_fields_1.default({
93
93
  fix: true,
94
94
  log: () => { },
95
95
  config: this.config,
96
- moduleName: 'entries',
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 && !this.config.flags['copy-dir']) {
108
- canWrite = this.config.flags.yes || (await core_1.ux.confirm(messages_1.commonMsg.FIX_CONFIRMATION));
109
- }
110
- if (canWrite) {
111
- (0, fs_1.writeFileSync)(filePath, JSON.stringify(schema));
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
- return;
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
  /**
@@ -0,0 +1,5 @@
1
+ import { ux } from "@contentstack/cli-utilities";
2
+ type IFlags = typeof ux.table.Flags;
3
+ type IncludeFlags<T, K extends keyof T> = Pick<T, K>;
4
+ type CommandNames = 'cm:stacks:audit' | 'cm:stacks:audit:fix';
5
+ export { IFlags, IncludeFlags, CommandNames };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -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, };
@@ -1,3 +1,4 @@
1
- export * from "./utils";
1
+ export * from './utils';
2
+ export * from './common';
2
3
  export * from './entries';
3
4
  export * from './content-types';
@@ -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;
@@ -1 +1,2 @@
1
- export { default as Logger } from "./log";
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
- if ((0, fs_1.existsSync)(this.config.basePath)) {
56
- const filename = (0, path_1.normalize)((0, path_1.resolve)(this.config.basePath, 'logs', `${logType}.log`)).replace(/^(\.\.(\/|\\|$))+/, '');
57
- const loggerOptions = {
58
- transports: [
59
- new winston_1.default.transports.File(Object.assign(Object.assign({}, this.loggerOptions), { level: logType, filename })),
60
- new winston_1.default.transports.Console(consoleOptions),
61
- ],
62
- levels: customLevels.levels,
63
- };
64
- if (logType === 'error') {
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":"abc................/g, 'authtoken":"abc....');
102
+ return JSON.stringify(item).replace(/"authtoken":\s*".*?"/, '"authtoken": "..."');
112
103
  }
113
104
  catch (error) { }
114
105
  return item;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.2.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 show provided columns (comma-separated)",
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": "property to sort by (prepend '-' for descending)",
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": "filter property by partial string matching, ex: name=foo",
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 csv format [alias: --output=csv]",
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": "do not truncate output to fit screen",
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 show provided columns (comma-separated)",
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": "property to sort by (prepend '-' for descending)",
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": "filter property by partial string matching, ex: name=foo",
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 csv format [alias: --output=csv]",
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": "do not truncate output to fit screen",
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.2.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.15",
22
- "@contentstack/cli-utilities": "~1.5.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": "^3.8.4",
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": "^1.0.3",
42
+ "eslint-config-oclif-typescript": "^3.0.8",
42
43
  "mocha": "^10.2.0",
43
44
  "nyc": "^15.1.0",
44
- "oclif": "^3.10.0",
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
+ }