@contentstack/cli-audit 1.4.1 → 1.5.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 +78 -68
- package/lib/audit-base-command.d.ts +7 -1
- package/lib/audit-base-command.js +84 -9
- package/lib/commands/cm/stacks/audit/index.d.ts +1 -1
- package/lib/commands/cm/stacks/audit/index.js +1 -1
- package/lib/config/index.d.ts +10 -0
- package/lib/config/index.js +12 -2
- package/lib/messages/index.d.ts +8 -0
- package/lib/messages/index.js +11 -2
- package/lib/modules/extensions.d.ts +20 -0
- package/lib/modules/extensions.js +89 -0
- package/lib/modules/index.d.ts +6 -4
- package/lib/modules/index.js +5 -1
- package/lib/modules/workflows.d.ts +27 -0
- package/lib/modules/workflows.js +117 -0
- package/lib/types/content-types.d.ts +12 -2
- package/lib/types/content-types.js +4 -0
- package/lib/types/extensions.d.ts +24 -0
- package/lib/types/extensions.js +2 -0
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.js +2 -0
- package/lib/types/workflow.d.ts +14 -0
- package/lib/types/workflow.js +2 -0
- package/oclif.manifest.json +9 -4
- package/package.json +4 -4
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.5.1 linux-x64 node-v18.19.1
|
|
23
23
|
$ csdx --help [COMMAND]
|
|
24
24
|
USAGE
|
|
25
25
|
$ csdx COMMAND
|
|
@@ -36,14 +36,14 @@ USAGE
|
|
|
36
36
|
* [`csdx cm:stacks:audit:fix`](#csdx-cmstacksauditfix)
|
|
37
37
|
* [`csdx help [COMMANDS]`](#csdx-help-commands)
|
|
38
38
|
* [`csdx plugins`](#csdx-plugins)
|
|
39
|
-
* [`csdx plugins:
|
|
39
|
+
* [`csdx plugins:add PLUGIN`](#csdx-pluginsadd-plugin)
|
|
40
40
|
* [`csdx plugins:inspect PLUGIN...`](#csdx-pluginsinspect-plugin)
|
|
41
|
-
* [`csdx plugins:install PLUGIN
|
|
42
|
-
* [`csdx plugins:link
|
|
43
|
-
* [`csdx plugins:
|
|
41
|
+
* [`csdx plugins:install PLUGIN`](#csdx-pluginsinstall-plugin)
|
|
42
|
+
* [`csdx plugins:link PATH`](#csdx-pluginslink-path)
|
|
43
|
+
* [`csdx plugins:remove [PLUGIN]`](#csdx-pluginsremove-plugin)
|
|
44
44
|
* [`csdx plugins:reset`](#csdx-pluginsreset)
|
|
45
|
-
* [`csdx plugins:uninstall PLUGIN
|
|
46
|
-
* [`csdx plugins:
|
|
45
|
+
* [`csdx plugins:uninstall [PLUGIN]`](#csdx-pluginsuninstall-plugin)
|
|
46
|
+
* [`csdx plugins:unlink [PLUGIN]`](#csdx-pluginsunlink-plugin)
|
|
47
47
|
* [`csdx plugins:update`](#csdx-pluginsupdate)
|
|
48
48
|
|
|
49
49
|
## `csdx audit`
|
|
@@ -53,12 +53,12 @@ Perform audits and find possible errors in the exported Contentstack data
|
|
|
53
53
|
```
|
|
54
54
|
USAGE
|
|
55
55
|
$ csdx audit [-c <value>] [-d <value>] [--report-path <value>] [--modules
|
|
56
|
-
content-types|global-fields|entries] [--columns <value> | ] [--sort <value>] [--filter <value>]
|
|
57
|
-
--no-truncate]
|
|
56
|
+
content-types|global-fields|entries|extensions|workflows] [--columns <value> | ] [--sort <value>] [--filter <value>]
|
|
57
|
+
[--csv | --no-truncate]
|
|
58
58
|
|
|
59
59
|
FLAGS
|
|
60
60
|
--modules=<option>... Provide the list of modules to be audited
|
|
61
|
-
<options: content-types|global-fields|entries>
|
|
61
|
+
<options: content-types|global-fields|entries|extensions|workflows>
|
|
62
62
|
--report-path=<value> Path to store the audit reports
|
|
63
63
|
|
|
64
64
|
COMMON FLAGS
|
|
@@ -98,17 +98,17 @@ Perform audits and fix possible errors in the exported Contentstack data.
|
|
|
98
98
|
```
|
|
99
99
|
USAGE
|
|
100
100
|
$ csdx audit:fix [-c <value>] [-d <value>] [--report-path <value>] [--modules
|
|
101
|
-
content-types|global-fields|entries] [--copy-path <value> --copy-dir] [--fix-only
|
|
102
|
-
reference|global_field|json:rte|json:extension|blocks|group] [--columns <value> | ] [--sort <value>]
|
|
103
|
-
<value>] [--csv | --no-truncate]
|
|
101
|
+
content-types|global-fields|entries|extensions|workflows] [--copy-path <value> --copy-dir] [--fix-only
|
|
102
|
+
reference|global_field|json:rte|json:extension|blocks|group|content_types] [--columns <value> | ] [--sort <value>]
|
|
103
|
+
[--filter <value>] [--csv | --no-truncate]
|
|
104
104
|
|
|
105
105
|
FLAGS
|
|
106
106
|
--copy-dir Create backup from the original data.
|
|
107
107
|
--copy-path=<value> Provide the path to backup the copied data
|
|
108
108
|
--fix-only=<option>... Provide the list of fix options
|
|
109
|
-
<options: reference|global_field|json:rte|json:extension|blocks|group>
|
|
109
|
+
<options: reference|global_field|json:rte|json:extension|blocks|group|content_types>
|
|
110
110
|
--modules=<option>... Provide the list of modules to be audited
|
|
111
|
-
<options: content-types|global-fields|entries>
|
|
111
|
+
<options: content-types|global-fields|entries|extensions|workflows>
|
|
112
112
|
--report-path=<value> Path to store the audit reports
|
|
113
113
|
|
|
114
114
|
COMMON FLAGS
|
|
@@ -150,12 +150,12 @@ Perform audits and find possible errors in the exported Contentstack data
|
|
|
150
150
|
```
|
|
151
151
|
USAGE
|
|
152
152
|
$ csdx cm:stacks:audit [-c <value>] [-d <value>] [--report-path <value>] [--modules
|
|
153
|
-
content-types|global-fields|entries] [--columns <value> | ] [--sort <value>] [--filter <value>]
|
|
154
|
-
--no-truncate]
|
|
153
|
+
content-types|global-fields|entries|extensions|workflows] [--columns <value> | ] [--sort <value>] [--filter <value>]
|
|
154
|
+
[--csv | --no-truncate]
|
|
155
155
|
|
|
156
156
|
FLAGS
|
|
157
157
|
--modules=<option>... Provide the list of modules to be audited
|
|
158
|
-
<options: content-types|global-fields|entries>
|
|
158
|
+
<options: content-types|global-fields|entries|extensions|workflows>
|
|
159
159
|
--report-path=<value> Path to store the audit reports
|
|
160
160
|
|
|
161
161
|
COMMON FLAGS
|
|
@@ -197,17 +197,17 @@ Perform audits and fix possible errors in the exported Contentstack data.
|
|
|
197
197
|
```
|
|
198
198
|
USAGE
|
|
199
199
|
$ csdx cm:stacks:audit:fix [-c <value>] [-d <value>] [--report-path <value>] [--modules
|
|
200
|
-
content-types|global-fields|entries] [--copy-path <value> --copy-dir] [--fix-only
|
|
201
|
-
reference|global_field|json:rte|json:extension|blocks|group] [--columns <value> | ] [--sort <value>]
|
|
202
|
-
<value>] [--csv | --no-truncate]
|
|
200
|
+
content-types|global-fields|entries|extensions|workflows] [--copy-path <value> --copy-dir] [--fix-only
|
|
201
|
+
reference|global_field|json:rte|json:extension|blocks|group|content_types] [--columns <value> | ] [--sort <value>]
|
|
202
|
+
[--filter <value>] [--csv | --no-truncate]
|
|
203
203
|
|
|
204
204
|
FLAGS
|
|
205
205
|
--copy-dir Create backup from the original data.
|
|
206
206
|
--copy-path=<value> Provide the path to backup the copied data
|
|
207
207
|
--fix-only=<option>... Provide the list of fix options
|
|
208
|
-
<options: reference|global_field|json:rte|json:extension|blocks|group>
|
|
208
|
+
<options: reference|global_field|json:rte|json:extension|blocks|group|content_types>
|
|
209
209
|
--modules=<option>... Provide the list of modules to be audited
|
|
210
|
-
<options: content-types|global-fields|entries>
|
|
210
|
+
<options: content-types|global-fields|entries|extensions|workflows>
|
|
211
211
|
--report-path=<value> Path to store the audit reports
|
|
212
212
|
|
|
213
213
|
COMMON FLAGS
|
|
@@ -285,48 +285,53 @@ EXAMPLES
|
|
|
285
285
|
$ csdx plugins
|
|
286
286
|
```
|
|
287
287
|
|
|
288
|
-
_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/v5.0.0/src/commands/plugins/index.ts)_
|
|
289
289
|
|
|
290
|
-
## `csdx plugins:
|
|
290
|
+
## `csdx plugins:add PLUGIN`
|
|
291
291
|
|
|
292
|
-
Installs a plugin into
|
|
292
|
+
Installs a plugin into csdx.
|
|
293
293
|
|
|
294
294
|
```
|
|
295
295
|
USAGE
|
|
296
|
-
$ csdx plugins:
|
|
296
|
+
$ csdx plugins:add PLUGIN [--json] [-f] [-h] [-s | -v]
|
|
297
297
|
|
|
298
298
|
ARGUMENTS
|
|
299
299
|
PLUGIN Plugin to install.
|
|
300
300
|
|
|
301
301
|
FLAGS
|
|
302
|
-
-f, --force
|
|
302
|
+
-f, --force Force npm to fetch remote resources even if a local copy exists on disk.
|
|
303
303
|
-h, --help Show CLI help.
|
|
304
|
-
-s, --silent Silences
|
|
305
|
-
-v, --verbose Show verbose
|
|
304
|
+
-s, --silent Silences npm output.
|
|
305
|
+
-v, --verbose Show verbose npm output.
|
|
306
306
|
|
|
307
307
|
GLOBAL FLAGS
|
|
308
308
|
--json Format output as json.
|
|
309
309
|
|
|
310
310
|
DESCRIPTION
|
|
311
|
-
Installs a plugin into
|
|
312
|
-
Can be installed from npm or a git url.
|
|
311
|
+
Installs a plugin into csdx.
|
|
313
312
|
|
|
314
|
-
|
|
313
|
+
Uses bundled npm executable to install plugins into /home/runner/.local/share/@contentstack/cli-audit
|
|
315
314
|
|
|
316
|
-
|
|
317
|
-
will override the core plugin implementation. This is useful if a user needs to update core plugin functionality in
|
|
318
|
-
the CLI without the need to patch and update the whole CLI.
|
|
315
|
+
Installation of a user-installed plugin will override a core plugin.
|
|
319
316
|
|
|
317
|
+
Use the CSDX_NPM_LOG_LEVEL environment variable to set the npm loglevel.
|
|
318
|
+
Use the CSDX_NPM_REGISTRY environment variable to set the npm registry.
|
|
320
319
|
|
|
321
320
|
ALIASES
|
|
322
321
|
$ csdx plugins:add
|
|
323
322
|
|
|
324
323
|
EXAMPLES
|
|
325
|
-
|
|
324
|
+
Install a plugin from npm registry.
|
|
325
|
+
|
|
326
|
+
$ csdx plugins:add myplugin
|
|
327
|
+
|
|
328
|
+
Install a plugin from a github url.
|
|
329
|
+
|
|
330
|
+
$ csdx plugins:add https://github.com/someuser/someplugin
|
|
326
331
|
|
|
327
|
-
|
|
332
|
+
Install a plugin from a github slug.
|
|
328
333
|
|
|
329
|
-
|
|
334
|
+
$ csdx plugins:add someuser/someplugin
|
|
330
335
|
```
|
|
331
336
|
|
|
332
337
|
## `csdx plugins:inspect PLUGIN...`
|
|
@@ -354,59 +359,64 @@ EXAMPLES
|
|
|
354
359
|
$ csdx plugins:inspect myplugin
|
|
355
360
|
```
|
|
356
361
|
|
|
357
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
362
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.0/src/commands/plugins/inspect.ts)_
|
|
358
363
|
|
|
359
|
-
## `csdx plugins:install PLUGIN
|
|
364
|
+
## `csdx plugins:install PLUGIN`
|
|
360
365
|
|
|
361
|
-
Installs a plugin into
|
|
366
|
+
Installs a plugin into csdx.
|
|
362
367
|
|
|
363
368
|
```
|
|
364
369
|
USAGE
|
|
365
|
-
$ csdx plugins:install PLUGIN
|
|
370
|
+
$ csdx plugins:install PLUGIN [--json] [-f] [-h] [-s | -v]
|
|
366
371
|
|
|
367
372
|
ARGUMENTS
|
|
368
373
|
PLUGIN Plugin to install.
|
|
369
374
|
|
|
370
375
|
FLAGS
|
|
371
|
-
-f, --force
|
|
376
|
+
-f, --force Force npm to fetch remote resources even if a local copy exists on disk.
|
|
372
377
|
-h, --help Show CLI help.
|
|
373
|
-
-s, --silent Silences
|
|
374
|
-
-v, --verbose Show verbose
|
|
378
|
+
-s, --silent Silences npm output.
|
|
379
|
+
-v, --verbose Show verbose npm output.
|
|
375
380
|
|
|
376
381
|
GLOBAL FLAGS
|
|
377
382
|
--json Format output as json.
|
|
378
383
|
|
|
379
384
|
DESCRIPTION
|
|
380
|
-
Installs a plugin into
|
|
381
|
-
Can be installed from npm or a git url.
|
|
385
|
+
Installs a plugin into csdx.
|
|
382
386
|
|
|
383
|
-
|
|
387
|
+
Uses bundled npm executable to install plugins into /home/runner/.local/share/@contentstack/cli-audit
|
|
384
388
|
|
|
385
|
-
|
|
386
|
-
will override the core plugin implementation. This is useful if a user needs to update core plugin functionality in
|
|
387
|
-
the CLI without the need to patch and update the whole CLI.
|
|
389
|
+
Installation of a user-installed plugin will override a core plugin.
|
|
388
390
|
|
|
391
|
+
Use the CSDX_NPM_LOG_LEVEL environment variable to set the npm loglevel.
|
|
392
|
+
Use the CSDX_NPM_REGISTRY environment variable to set the npm registry.
|
|
389
393
|
|
|
390
394
|
ALIASES
|
|
391
395
|
$ csdx plugins:add
|
|
392
396
|
|
|
393
397
|
EXAMPLES
|
|
394
|
-
|
|
398
|
+
Install a plugin from npm registry.
|
|
399
|
+
|
|
400
|
+
$ csdx plugins:install myplugin
|
|
401
|
+
|
|
402
|
+
Install a plugin from a github url.
|
|
403
|
+
|
|
404
|
+
$ csdx plugins:install https://github.com/someuser/someplugin
|
|
395
405
|
|
|
396
|
-
|
|
406
|
+
Install a plugin from a github slug.
|
|
397
407
|
|
|
398
|
-
|
|
408
|
+
$ csdx plugins:install someuser/someplugin
|
|
399
409
|
```
|
|
400
410
|
|
|
401
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
411
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.0/src/commands/plugins/install.ts)_
|
|
402
412
|
|
|
403
|
-
## `csdx plugins:link
|
|
413
|
+
## `csdx plugins:link PATH`
|
|
404
414
|
|
|
405
415
|
Links a plugin into the CLI for development.
|
|
406
416
|
|
|
407
417
|
```
|
|
408
418
|
USAGE
|
|
409
|
-
$ csdx plugins:link
|
|
419
|
+
$ csdx plugins:link PATH [-h] [--install] [-v]
|
|
410
420
|
|
|
411
421
|
ARGUMENTS
|
|
412
422
|
PATH [default: .] path to plugin
|
|
@@ -428,15 +438,15 @@ EXAMPLES
|
|
|
428
438
|
$ csdx plugins:link myplugin
|
|
429
439
|
```
|
|
430
440
|
|
|
431
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
441
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.0/src/commands/plugins/link.ts)_
|
|
432
442
|
|
|
433
|
-
## `csdx plugins:
|
|
443
|
+
## `csdx plugins:remove [PLUGIN]`
|
|
434
444
|
|
|
435
445
|
Removes a plugin from the CLI.
|
|
436
446
|
|
|
437
447
|
```
|
|
438
448
|
USAGE
|
|
439
|
-
$ csdx plugins:
|
|
449
|
+
$ csdx plugins:remove [PLUGIN] [-h] [-v]
|
|
440
450
|
|
|
441
451
|
ARGUMENTS
|
|
442
452
|
PLUGIN plugin to uninstall
|
|
@@ -469,15 +479,15 @@ FLAGS
|
|
|
469
479
|
--reinstall Reinstall all plugins after uninstalling.
|
|
470
480
|
```
|
|
471
481
|
|
|
472
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
482
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.0/src/commands/plugins/reset.ts)_
|
|
473
483
|
|
|
474
|
-
## `csdx plugins:uninstall PLUGIN
|
|
484
|
+
## `csdx plugins:uninstall [PLUGIN]`
|
|
475
485
|
|
|
476
486
|
Removes a plugin from the CLI.
|
|
477
487
|
|
|
478
488
|
```
|
|
479
489
|
USAGE
|
|
480
|
-
$ csdx plugins:uninstall PLUGIN
|
|
490
|
+
$ csdx plugins:uninstall [PLUGIN] [-h] [-v]
|
|
481
491
|
|
|
482
492
|
ARGUMENTS
|
|
483
493
|
PLUGIN plugin to uninstall
|
|
@@ -497,15 +507,15 @@ EXAMPLES
|
|
|
497
507
|
$ csdx plugins:uninstall myplugin
|
|
498
508
|
```
|
|
499
509
|
|
|
500
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
510
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.0/src/commands/plugins/uninstall.ts)_
|
|
501
511
|
|
|
502
|
-
## `csdx plugins:
|
|
512
|
+
## `csdx plugins:unlink [PLUGIN]`
|
|
503
513
|
|
|
504
514
|
Removes a plugin from the CLI.
|
|
505
515
|
|
|
506
516
|
```
|
|
507
517
|
USAGE
|
|
508
|
-
$ csdx plugins:
|
|
518
|
+
$ csdx plugins:unlink [PLUGIN] [-h] [-v]
|
|
509
519
|
|
|
510
520
|
ARGUMENTS
|
|
511
521
|
PLUGIN plugin to uninstall
|
|
@@ -541,5 +551,5 @@ DESCRIPTION
|
|
|
541
551
|
Update installed plugins.
|
|
542
552
|
```
|
|
543
553
|
|
|
544
|
-
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/
|
|
554
|
+
_See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v5.0.0/src/commands/plugins/update.ts)_
|
|
545
555
|
<!-- commandsstop -->
|
|
@@ -11,7 +11,7 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
|
|
|
11
11
|
};
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
|
-
* The `start` function performs an audit on content types, global fields,
|
|
14
|
+
* The `start` function performs an audit on content types, global fields, entries, and workflows and displays
|
|
15
15
|
* any missing references.
|
|
16
16
|
* @param {string} command - The `command` parameter is a string that represents the current command
|
|
17
17
|
* being executed.
|
|
@@ -27,6 +27,8 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
|
|
|
27
27
|
missingCtRefs: Record<string, any> | undefined;
|
|
28
28
|
missingGfRefs: Record<string, any> | undefined;
|
|
29
29
|
missingEntryRefs: Record<string, any> | undefined;
|
|
30
|
+
missingCtRefsInExtensions: {} | undefined;
|
|
31
|
+
missingCtRefsInWorkflow: {} | undefined;
|
|
30
32
|
}>;
|
|
31
33
|
/**
|
|
32
34
|
* The `promptQueue` function prompts the user to enter a data directory path if the `data-dir` flag
|
|
@@ -58,6 +60,10 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
|
|
|
58
60
|
module: string;
|
|
59
61
|
missingRefs?: Record<string, any>;
|
|
60
62
|
}[]): void;
|
|
63
|
+
showOutputOnScreenWorkflowsAndExtension(allMissingRefs: {
|
|
64
|
+
module: string;
|
|
65
|
+
missingRefs?: Record<string, any>;
|
|
66
|
+
}[]): void;
|
|
61
67
|
/**
|
|
62
68
|
* The function prepares a report by writing a JSON file and a CSV file with a list of missing
|
|
63
69
|
* references for a given module.
|
|
@@ -29,7 +29,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
|
-
* The `start` function performs an audit on content types, global fields,
|
|
32
|
+
* The `start` function performs an audit on content types, global fields, entries, and workflows and displays
|
|
33
33
|
* any missing references.
|
|
34
34
|
* @param {string} command - The `command` parameter is a string that represents the current command
|
|
35
35
|
* being executed.
|
|
@@ -39,13 +39,19 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
39
39
|
await this.promptQueue();
|
|
40
40
|
await this.createBackUp();
|
|
41
41
|
this.sharedConfig.reportPath = (0, path_1.resolve)(this.flags['report-path'] || process.cwd(), 'audit-report');
|
|
42
|
-
const { missingCtRefs, missingGfRefs, missingEntryRefs } = await this.scanAndFix();
|
|
42
|
+
const { missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow } = await this.scanAndFix();
|
|
43
43
|
this.showOutputOnScreen([
|
|
44
44
|
{ module: 'Content types', missingRefs: missingCtRefs },
|
|
45
45
|
{ module: 'Global Fields', missingRefs: missingGfRefs },
|
|
46
46
|
{ module: 'Entries', missingRefs: missingEntryRefs },
|
|
47
47
|
]);
|
|
48
|
-
|
|
48
|
+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Extensions', missingRefs: missingCtRefsInExtensions }]);
|
|
49
|
+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Workflows', missingRefs: missingCtRefsInWorkflow }]);
|
|
50
|
+
if (!(0, isEmpty_1.default)(missingCtRefs) ||
|
|
51
|
+
!(0, isEmpty_1.default)(missingGfRefs) ||
|
|
52
|
+
!(0, isEmpty_1.default)(missingEntryRefs) ||
|
|
53
|
+
!(0, isEmpty_1.default)(missingCtRefsInWorkflow) ||
|
|
54
|
+
!(0, isEmpty_1.default)(missingCtRefsInExtensions)) {
|
|
49
55
|
if (this.currentCommand === 'cm:stacks:audit') {
|
|
50
56
|
this.log(this.$t(messages_1.auditMsg.FINAL_REPORT_PATH, { path: this.sharedConfig.reportPath }), 'warn');
|
|
51
57
|
}
|
|
@@ -63,7 +69,11 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
63
69
|
(0, fs_1.rmSync)(this.sharedConfig.basePath, { recursive: true });
|
|
64
70
|
}
|
|
65
71
|
}
|
|
66
|
-
return !(0, isEmpty_1.default)(missingCtRefs) ||
|
|
72
|
+
return (!(0, isEmpty_1.default)(missingCtRefs) ||
|
|
73
|
+
!(0, isEmpty_1.default)(missingGfRefs) ||
|
|
74
|
+
!(0, isEmpty_1.default)(missingEntryRefs) ||
|
|
75
|
+
!(0, isEmpty_1.default)(missingCtRefsInWorkflow) ||
|
|
76
|
+
!(0, isEmpty_1.default)(missingCtRefsInExtensions));
|
|
67
77
|
}
|
|
68
78
|
/**
|
|
69
79
|
* The `scan` function performs an audit on different modules (content-types, global-fields, and
|
|
@@ -73,7 +83,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
73
83
|
*/
|
|
74
84
|
async scanAndFix() {
|
|
75
85
|
let { ctSchema, gfSchema } = this.getCtAndGfSchema();
|
|
76
|
-
let missingCtRefs, missingGfRefs, missingEntryRefs;
|
|
86
|
+
let missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow;
|
|
77
87
|
for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) {
|
|
78
88
|
(0, log_1.print)([
|
|
79
89
|
{
|
|
@@ -103,6 +113,20 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
103
113
|
missingEntryRefs = await new modules_1.Entries((0, cloneDeep_1.default)(constructorParam)).run();
|
|
104
114
|
await this.prepareReport(module, missingEntryRefs);
|
|
105
115
|
break;
|
|
116
|
+
case 'workflows':
|
|
117
|
+
missingCtRefsInWorkflow = await new modules_1.Workflows({
|
|
118
|
+
ctSchema,
|
|
119
|
+
log: this.log,
|
|
120
|
+
moduleName: module,
|
|
121
|
+
config: this.sharedConfig,
|
|
122
|
+
fix: this.currentCommand === 'cm:stacks:audit:fix',
|
|
123
|
+
}).run();
|
|
124
|
+
await this.prepareReport(module, missingCtRefsInWorkflow);
|
|
125
|
+
break;
|
|
126
|
+
case 'extensions':
|
|
127
|
+
missingCtRefsInExtensions = await new modules_1.Extensions((0, cloneDeep_1.default)(constructorParam)).run();
|
|
128
|
+
await this.prepareReport(module, missingCtRefsInExtensions);
|
|
129
|
+
break;
|
|
106
130
|
}
|
|
107
131
|
(0, log_1.print)([
|
|
108
132
|
{
|
|
@@ -117,7 +141,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
117
141
|
},
|
|
118
142
|
]);
|
|
119
143
|
}
|
|
120
|
-
return { missingCtRefs, missingGfRefs, missingEntryRefs };
|
|
144
|
+
return { missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow };
|
|
121
145
|
}
|
|
122
146
|
/**
|
|
123
147
|
* The `promptQueue` function prompts the user to enter a data directory path if the `data-dir` flag
|
|
@@ -210,6 +234,47 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
210
234
|
}
|
|
211
235
|
}
|
|
212
236
|
}
|
|
237
|
+
// Make it generic it takes the column header as param
|
|
238
|
+
showOutputOnScreenWorkflowsAndExtension(allMissingRefs) {
|
|
239
|
+
var _a;
|
|
240
|
+
if (!this.sharedConfig.showTerminalOutput || ((_a = this.flags['external-config']) === null || _a === void 0 ? void 0 : _a.noTerminalOutput)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
this.log(''); // Adding a new line
|
|
244
|
+
for (const { module, missingRefs } of allMissingRefs) {
|
|
245
|
+
if ((0, isEmpty_1.default)(missingRefs)) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
(0, log_1.print)([{ bold: true, color: 'cyan', message: ` ${module}` }]);
|
|
249
|
+
const tableValues = Object.values(missingRefs).flat();
|
|
250
|
+
const tableKeys = Object.keys(missingRefs[0]);
|
|
251
|
+
const arrayOfObjects = tableKeys.map((key) => {
|
|
252
|
+
if (['title', 'name', 'uid', 'content_types', 'branches', 'fixStatus'].includes(key)) {
|
|
253
|
+
return {
|
|
254
|
+
[key]: {
|
|
255
|
+
minWidth: 7,
|
|
256
|
+
header: key,
|
|
257
|
+
get: (row) => {
|
|
258
|
+
if (key === 'fixStatus') {
|
|
259
|
+
return chalk_1.default.green(typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]);
|
|
260
|
+
}
|
|
261
|
+
else if (key === 'content_types' || key === 'branches') {
|
|
262
|
+
return chalk_1.default.red(typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
return chalk_1.default.white(typeof row[key] === 'object' ? JSON.stringify(row[key]) : row[key]);
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
return {};
|
|
272
|
+
});
|
|
273
|
+
const mergedObject = Object.assign({}, ...arrayOfObjects);
|
|
274
|
+
cli_utilities_1.ux.table(tableValues, mergedObject, Object.assign({}, this.flags));
|
|
275
|
+
this.log(''); // Adding a new line
|
|
276
|
+
}
|
|
277
|
+
}
|
|
213
278
|
/**
|
|
214
279
|
* The function prepares a report by writing a JSON file and a CSV file with a list of missing
|
|
215
280
|
* references for a given module.
|
|
@@ -254,14 +319,24 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
254
319
|
: defaultColumns;
|
|
255
320
|
if (this.sharedConfig.flags.filter) {
|
|
256
321
|
const [column, value] = this.sharedConfig.flags.filter.split('=');
|
|
257
|
-
|
|
322
|
+
// Filter the missingRefs array
|
|
323
|
+
missingRefs = missingRefs.filter((row) => {
|
|
324
|
+
if (types_1.OutputColumn[column] in row) {
|
|
325
|
+
const rowKey = types_1.OutputColumn[column];
|
|
326
|
+
return row[rowKey] === value;
|
|
327
|
+
}
|
|
328
|
+
return false;
|
|
329
|
+
});
|
|
258
330
|
}
|
|
259
331
|
const rowData = [];
|
|
260
332
|
for (const issue of missingRefs) {
|
|
261
333
|
let row = {};
|
|
262
334
|
for (const column of columns) {
|
|
263
|
-
|
|
264
|
-
|
|
335
|
+
if (Object.keys(issue).includes(types_1.OutputColumn[column])) {
|
|
336
|
+
const issueKey = types_1.OutputColumn[column];
|
|
337
|
+
row[column] = issue[issueKey];
|
|
338
|
+
row[column] = typeof row[column] === 'object' ? JSON.stringify(row[column]) : row[column];
|
|
339
|
+
}
|
|
265
340
|
}
|
|
266
341
|
if (this.currentCommand === 'cm:stacks:audit:fix') {
|
|
267
342
|
row['Fix status'] = row.fixStatus;
|
|
@@ -7,7 +7,7 @@ export default class Audit extends AuditBaseCommand {
|
|
|
7
7
|
static flags: FlagInput;
|
|
8
8
|
/**
|
|
9
9
|
* The `run` function is an asynchronous function that performs an audit on different modules
|
|
10
|
-
* (content-types, global-fields, entries) and generates a report.
|
|
10
|
+
* (content-types, global-fields, entries, workflows) and generates a report.
|
|
11
11
|
*/
|
|
12
12
|
run(): Promise<void>;
|
|
13
13
|
}
|
|
@@ -9,7 +9,7 @@ const util_1 = require("../../../../util");
|
|
|
9
9
|
class Audit extends audit_base_command_1.AuditBaseCommand {
|
|
10
10
|
/**
|
|
11
11
|
* The `run` function is an asynchronous function that performs an audit on different modules
|
|
12
|
-
* (content-types, global-fields, entries) and generates a report.
|
|
12
|
+
* (content-types, global-fields, entries, workflows) and generates a report.
|
|
13
13
|
*/
|
|
14
14
|
async run() {
|
|
15
15
|
try {
|
package/lib/config/index.d.ts
CHANGED
|
@@ -25,6 +25,16 @@ declare const config: {
|
|
|
25
25
|
dirName: string;
|
|
26
26
|
fileName: string;
|
|
27
27
|
};
|
|
28
|
+
workflows: {
|
|
29
|
+
name: string;
|
|
30
|
+
dirName: string;
|
|
31
|
+
fileName: string;
|
|
32
|
+
};
|
|
33
|
+
extensions: {
|
|
34
|
+
name: string;
|
|
35
|
+
dirName: string;
|
|
36
|
+
fileName: string;
|
|
37
|
+
};
|
|
28
38
|
};
|
|
29
39
|
entries: {
|
|
30
40
|
systemKeys: string[];
|
package/lib/config/index.js
CHANGED
|
@@ -4,8 +4,8 @@ const config = {
|
|
|
4
4
|
showTerminalOutput: true,
|
|
5
5
|
skipRefs: ['sys_assets'],
|
|
6
6
|
skipFieldTypes: ['taxonomy', 'group'],
|
|
7
|
-
modules: ['content-types', 'global-fields', 'entries'],
|
|
8
|
-
'fix-fields': ['reference', 'global_field', 'json:rte', 'json:extension', 'blocks', 'group'],
|
|
7
|
+
modules: ['content-types', 'global-fields', 'entries', 'extensions', 'workflows'],
|
|
8
|
+
'fix-fields': ['reference', 'global_field', 'json:rte', 'json:extension', 'blocks', 'group', 'content_types'],
|
|
9
9
|
moduleConfig: {
|
|
10
10
|
'content-types': {
|
|
11
11
|
name: 'content type',
|
|
@@ -27,6 +27,16 @@ const config = {
|
|
|
27
27
|
dirName: 'locales',
|
|
28
28
|
fileName: 'locales.json',
|
|
29
29
|
},
|
|
30
|
+
workflows: {
|
|
31
|
+
name: 'workflows',
|
|
32
|
+
dirName: 'workflows',
|
|
33
|
+
fileName: 'workflows.json',
|
|
34
|
+
},
|
|
35
|
+
extensions: {
|
|
36
|
+
name: 'extensions',
|
|
37
|
+
dirName: 'extensions',
|
|
38
|
+
fileName: 'extensions.json',
|
|
39
|
+
},
|
|
30
40
|
},
|
|
31
41
|
entries: {
|
|
32
42
|
systemKeys: [
|
package/lib/messages/index.d.ts
CHANGED
|
@@ -10,6 +10,11 @@ declare const commonMsg: {
|
|
|
10
10
|
CONFIG: string;
|
|
11
11
|
DATA_DIR: string;
|
|
12
12
|
FIX_CONFIRMATION: string;
|
|
13
|
+
WORKFLOW_FIX_WARN: string;
|
|
14
|
+
WORKFLOW_FIX_CONFIRMATION: string;
|
|
15
|
+
EXTENSION_FIX_WARN: string;
|
|
16
|
+
EXTENSION_FIX_CONFIRMATION: string;
|
|
17
|
+
WF_BRANCH_REMOVAL: string;
|
|
13
18
|
};
|
|
14
19
|
declare const auditMsg: {
|
|
15
20
|
REPORT_PATH: string;
|
|
@@ -22,7 +27,9 @@ declare const auditMsg: {
|
|
|
22
27
|
FINAL_REPORT_PATH: string;
|
|
23
28
|
SCAN_CT_SUCCESS_MSG: string;
|
|
24
29
|
SCAN_ENTRY_SUCCESS_MSG: string;
|
|
30
|
+
SCAN_EXT_SUCCESS_MSG: string;
|
|
25
31
|
AUDIT_CMD_DESCRIPTION: string;
|
|
32
|
+
SCAN_WF_SUCCESS_MSG: string;
|
|
26
33
|
};
|
|
27
34
|
declare const auditFixMsg: {
|
|
28
35
|
COPY_DATA: string;
|
|
@@ -31,6 +38,7 @@ declare const auditFixMsg: {
|
|
|
31
38
|
FIXED_CONTENT_PATH_MAG: string;
|
|
32
39
|
EMPTY_FIX_MSG: string;
|
|
33
40
|
AUDIT_FIX_CMD_DESCRIPTION: string;
|
|
41
|
+
WF_FIX_MSG: string;
|
|
34
42
|
};
|
|
35
43
|
declare const messages: typeof errors & typeof commonMsg & typeof auditMsg & typeof auditFixMsg & typeof tableColumnDescriptions;
|
|
36
44
|
/**
|
package/lib/messages/index.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.tableColumnDescriptions = exports.auditFixMsg = exports.auditMsg = exports.commonMsg = exports.errors = exports.$t = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const memoize_1 = tslib_1.__importDefault(require("lodash/memoize"));
|
|
6
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
6
7
|
const errors = {};
|
|
7
8
|
exports.errors = errors;
|
|
8
9
|
const tableColumnDescriptions = {
|
|
@@ -17,6 +18,11 @@ const commonMsg = {
|
|
|
17
18
|
CONFIG: 'Path of the external config',
|
|
18
19
|
DATA_DIR: 'Path where the data is stored',
|
|
19
20
|
FIX_CONFIRMATION: 'Would you like to overwrite existing file.?',
|
|
21
|
+
WORKFLOW_FIX_WARN: `The workflow associated with UID {uid} and name {name} will be removed.`,
|
|
22
|
+
WORKFLOW_FIX_CONFIRMATION: 'Would you like to overwrite existing file?',
|
|
23
|
+
EXTENSION_FIX_WARN: `The extension associated with UID {uid} and title '{title}' will be removed.`,
|
|
24
|
+
EXTENSION_FIX_CONFIRMATION: `Would you like to overwrite existing file?`,
|
|
25
|
+
WF_BRANCH_REMOVAL: `Removing the branch '{branch} from workflow with UID {uid} and name {name} will be removed.'`,
|
|
20
26
|
};
|
|
21
27
|
exports.commonMsg = commonMsg;
|
|
22
28
|
const auditMsg = {
|
|
@@ -30,7 +36,9 @@ const auditMsg = {
|
|
|
30
36
|
FINAL_REPORT_PATH: "Reports ready. Please find the reports at '{path}'.",
|
|
31
37
|
SCAN_CT_SUCCESS_MSG: "Successfully completed the scanning of {module} '{title}'.",
|
|
32
38
|
SCAN_ENTRY_SUCCESS_MSG: "Successfully completed the scanning of {module} ({local}) '{title}'.",
|
|
39
|
+
SCAN_EXT_SUCCESS_MSG: "Successfully completed scanning the {module} titled '{title}' with UID '{uid}'",
|
|
33
40
|
AUDIT_CMD_DESCRIPTION: 'Perform audits and find possible errors in the exported Contentstack data',
|
|
41
|
+
SCAN_WF_SUCCESS_MSG: 'Successfully completed the scanning of workflow with UID {uid} and name {name}.',
|
|
34
42
|
};
|
|
35
43
|
exports.auditMsg = auditMsg;
|
|
36
44
|
const auditFixMsg = {
|
|
@@ -40,6 +48,7 @@ const auditFixMsg = {
|
|
|
40
48
|
FIXED_CONTENT_PATH_MAG: 'You can locate the fixed content at {path}.',
|
|
41
49
|
EMPTY_FIX_MSG: 'Successfully removed the empty field/block found at {path} from the schema.',
|
|
42
50
|
AUDIT_FIX_CMD_DESCRIPTION: 'Perform audits and fix possible errors in the exported Contentstack data.',
|
|
51
|
+
WF_FIX_MSG: 'Successfully removed the workflow {uid} named {name}.',
|
|
43
52
|
};
|
|
44
53
|
exports.auditFixMsg = auditFixMsg;
|
|
45
54
|
const messages = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, errors), commonMsg), auditMsg), auditFixMsg), tableColumnDescriptions);
|
|
@@ -57,8 +66,8 @@ function $t(msg, args) {
|
|
|
57
66
|
if (!msg)
|
|
58
67
|
return '';
|
|
59
68
|
for (const key of Object.keys(args)) {
|
|
60
|
-
const escapedKey =
|
|
61
|
-
msg = msg.replace(new RegExp(`{${escapedKey}}`, 'g'), args[key] || escapedKey);
|
|
69
|
+
const escapedKey = (0, cli_utilities_1.escapeRegExp)(key);
|
|
70
|
+
msg = msg.replace(new RegExp(`{${escapedKey}}`, 'g'), (0, cli_utilities_1.escapeRegExp)(args[key]) || escapedKey);
|
|
62
71
|
}
|
|
63
72
|
return msg;
|
|
64
73
|
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { LogFn, ConfigType, ContentTypeStruct, CtConstructorParam, ModuleConstructorParam, Extension } from '../types';
|
|
2
|
+
import auditConfig from '../config';
|
|
3
|
+
export default class Extensions {
|
|
4
|
+
log: LogFn;
|
|
5
|
+
protected fix: boolean;
|
|
6
|
+
fileName: any;
|
|
7
|
+
config: ConfigType;
|
|
8
|
+
folderPath: string;
|
|
9
|
+
extensionsSchema: Extension[];
|
|
10
|
+
ctSchema: ContentTypeStruct[];
|
|
11
|
+
moduleName: keyof typeof auditConfig.moduleConfig;
|
|
12
|
+
ctUidSet: Set<string>;
|
|
13
|
+
missingCtInExtensions: Extension[];
|
|
14
|
+
missingCts: Set<string>;
|
|
15
|
+
extensionsPath: string;
|
|
16
|
+
constructor({ log, fix, config, moduleName, ctSchema, }: ModuleConstructorParam & Pick<CtConstructorParam, 'ctSchema'>);
|
|
17
|
+
run(): Promise<{}>;
|
|
18
|
+
fixExtensionsScope(missingCtInExtensions: Extension[]): Promise<void>;
|
|
19
|
+
writeFixContent(fixedExtensions: Record<string, Extension>): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const path_1 = tslib_1.__importStar(require("path"));
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const lodash_1 = require("lodash");
|
|
7
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
8
|
+
const messages_1 = require("../messages");
|
|
9
|
+
const lodash_2 = require("lodash");
|
|
10
|
+
class Extensions {
|
|
11
|
+
constructor({ log, fix, config, moduleName, ctSchema, }) {
|
|
12
|
+
this.log = log;
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.fix = fix !== null && fix !== void 0 ? fix : false;
|
|
15
|
+
this.ctSchema = ctSchema;
|
|
16
|
+
this.extensionsSchema = [];
|
|
17
|
+
this.moduleName = moduleName !== null && moduleName !== void 0 ? moduleName : 'extensions';
|
|
18
|
+
this.fileName = config.moduleConfig[this.moduleName].fileName;
|
|
19
|
+
this.folderPath = (0, path_1.resolve)(config.basePath, config.moduleConfig[this.moduleName].dirName);
|
|
20
|
+
this.ctUidSet = new Set(['$all']);
|
|
21
|
+
this.missingCtInExtensions = [];
|
|
22
|
+
this.missingCts = new Set();
|
|
23
|
+
this.extensionsPath = '';
|
|
24
|
+
}
|
|
25
|
+
async run() {
|
|
26
|
+
if (!(0, fs_1.existsSync)(this.folderPath)) {
|
|
27
|
+
this.log(`Skipping ${this.moduleName} audit`, 'warn');
|
|
28
|
+
this.log((0, messages_1.$t)(messages_1.auditMsg.NOT_VALID_PATH, { path: this.folderPath }), { color: 'yellow' });
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
this.extensionsPath = path_1.default.join(this.folderPath, this.fileName);
|
|
32
|
+
this.extensionsSchema = (0, fs_1.existsSync)(this.extensionsPath)
|
|
33
|
+
? (0, lodash_2.values)(JSON.parse((0, fs_1.readFileSync)(this.extensionsPath, 'utf-8')))
|
|
34
|
+
: [];
|
|
35
|
+
this.ctSchema.map((ct) => this.ctUidSet.add(ct.uid));
|
|
36
|
+
for (const ext of this.extensionsSchema) {
|
|
37
|
+
const { title, uid, scope } = ext;
|
|
38
|
+
const ctNotPresent = scope === null || scope === void 0 ? void 0 : scope.content_types.filter((ct) => !this.ctUidSet.has(ct));
|
|
39
|
+
if ((ctNotPresent === null || ctNotPresent === void 0 ? void 0 : ctNotPresent.length) && ext.scope) {
|
|
40
|
+
ext.content_types = ctNotPresent;
|
|
41
|
+
ctNotPresent.forEach((ct) => this.missingCts.add(ct));
|
|
42
|
+
this.missingCtInExtensions.push((0, lodash_1.cloneDeep)(ext));
|
|
43
|
+
}
|
|
44
|
+
this.log((0, messages_1.$t)(messages_1.auditMsg.SCAN_EXT_SUCCESS_MSG, {
|
|
45
|
+
title,
|
|
46
|
+
module: this.config.moduleConfig[this.moduleName].name,
|
|
47
|
+
uid,
|
|
48
|
+
}), 'info');
|
|
49
|
+
}
|
|
50
|
+
if (this.fix && this.missingCtInExtensions.length) {
|
|
51
|
+
await this.fixExtensionsScope((0, lodash_1.cloneDeep)(this.missingCtInExtensions));
|
|
52
|
+
this.missingCtInExtensions.forEach((ext) => (ext.fixStatus = 'Fixed'));
|
|
53
|
+
return this.missingCtInExtensions;
|
|
54
|
+
}
|
|
55
|
+
return this.missingCtInExtensions;
|
|
56
|
+
}
|
|
57
|
+
async fixExtensionsScope(missingCtInExtensions) {
|
|
58
|
+
var _a, _b;
|
|
59
|
+
let newExtensionSchema = (0, fs_1.existsSync)(this.extensionsPath)
|
|
60
|
+
? JSON.parse((0, fs_1.readFileSync)(this.extensionsPath, 'utf8'))
|
|
61
|
+
: {};
|
|
62
|
+
for (const ext of missingCtInExtensions) {
|
|
63
|
+
const { uid, title } = ext;
|
|
64
|
+
const fixedCts = (_a = ext === null || ext === void 0 ? void 0 : ext.scope) === null || _a === void 0 ? void 0 : _a.content_types.filter((ct) => !this.missingCts.has(ct));
|
|
65
|
+
if ((fixedCts === null || fixedCts === void 0 ? void 0 : fixedCts.length) && ((_b = newExtensionSchema[uid]) === null || _b === void 0 ? void 0 : _b.scope)) {
|
|
66
|
+
newExtensionSchema[uid].scope.content_types = fixedCts;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
this.log((0, messages_1.$t)(messages_1.commonMsg.EXTENSION_FIX_WARN, { title: title, uid }), { color: 'yellow' });
|
|
70
|
+
const shouldDelete = this.config.flags.yes || (await cli_utilities_1.ux.confirm(messages_1.commonMsg.EXTENSION_FIX_CONFIRMATION));
|
|
71
|
+
if (shouldDelete) {
|
|
72
|
+
delete newExtensionSchema[uid];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
await this.writeFixContent(newExtensionSchema);
|
|
77
|
+
}
|
|
78
|
+
async writeFixContent(fixedExtensions) {
|
|
79
|
+
var _a;
|
|
80
|
+
if (this.fix &&
|
|
81
|
+
(this.config.flags['copy-dir'] ||
|
|
82
|
+
((_a = this.config.flags['external-config']) === null || _a === void 0 ? void 0 : _a.skipConfirm) ||
|
|
83
|
+
this.config.flags.yes ||
|
|
84
|
+
(await cli_utilities_1.ux.confirm(messages_1.commonMsg.FIX_CONFIRMATION)))) {
|
|
85
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(this.folderPath, this.config.moduleConfig[this.moduleName].fileName), JSON.stringify(fixedExtensions));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.default = Extensions;
|
package/lib/modules/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import Entries from
|
|
2
|
-
import GlobalField from
|
|
3
|
-
import ContentType from
|
|
4
|
-
|
|
1
|
+
import Entries from './entries';
|
|
2
|
+
import GlobalField from './global-fields';
|
|
3
|
+
import ContentType from './content-types';
|
|
4
|
+
import Workflows from './workflows';
|
|
5
|
+
import Extensions from './extensions';
|
|
6
|
+
export { Entries, GlobalField, ContentType, Workflows, Extensions };
|
package/lib/modules/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ContentType = exports.GlobalField = exports.Entries = void 0;
|
|
3
|
+
exports.Extensions = exports.Workflows = exports.ContentType = exports.GlobalField = exports.Entries = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const entries_1 = tslib_1.__importDefault(require("./entries"));
|
|
6
6
|
exports.Entries = entries_1.default;
|
|
@@ -8,3 +8,7 @@ const global_fields_1 = tslib_1.__importDefault(require("./global-fields"));
|
|
|
8
8
|
exports.GlobalField = global_fields_1.default;
|
|
9
9
|
const content_types_1 = tslib_1.__importDefault(require("./content-types"));
|
|
10
10
|
exports.ContentType = content_types_1.default;
|
|
11
|
+
const workflows_1 = tslib_1.__importDefault(require("./workflows"));
|
|
12
|
+
exports.Workflows = workflows_1.default;
|
|
13
|
+
const extensions_1 = tslib_1.__importDefault(require("./extensions"));
|
|
14
|
+
exports.Extensions = extensions_1.default;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { LogFn, ConfigType, ContentTypeStruct, CtConstructorParam, ModuleConstructorParam, Workflow } from '../types';
|
|
2
|
+
import auditConfig from '../config';
|
|
3
|
+
export default class Workflows {
|
|
4
|
+
log: LogFn;
|
|
5
|
+
protected fix: boolean;
|
|
6
|
+
fileName: any;
|
|
7
|
+
config: ConfigType;
|
|
8
|
+
folderPath: string;
|
|
9
|
+
workflowSchema: Workflow[];
|
|
10
|
+
ctSchema: ContentTypeStruct[];
|
|
11
|
+
moduleName: keyof typeof auditConfig.moduleConfig;
|
|
12
|
+
ctUidSet: Set<string>;
|
|
13
|
+
missingCtInWorkflows: Workflow[];
|
|
14
|
+
missingCts: Set<string>;
|
|
15
|
+
workflowPath: string;
|
|
16
|
+
isBranchFixDone: boolean;
|
|
17
|
+
constructor({ log, fix, config, moduleName, ctSchema, }: ModuleConstructorParam & Pick<CtConstructorParam, 'ctSchema'>);
|
|
18
|
+
/**
|
|
19
|
+
* Check whether the given path for the workflow exists or not
|
|
20
|
+
* If path exist read
|
|
21
|
+
* From the ctSchema add all the content type UID into ctUidSet to check whether the content-type is present or not
|
|
22
|
+
* @returns Array of object containing the workflow name, uid and content_types that are missing
|
|
23
|
+
*/
|
|
24
|
+
run(): Promise<{}>;
|
|
25
|
+
fixWorkflowSchema(): Promise<void>;
|
|
26
|
+
writeFixContent(newWorkflowSchema: Record<string, Workflow>): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path_1 = require("path");
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const lodash_1 = require("lodash");
|
|
6
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
7
|
+
const messages_1 = require("../messages");
|
|
8
|
+
const lodash_2 = require("lodash");
|
|
9
|
+
class Workflows {
|
|
10
|
+
constructor({ log, fix, config, moduleName, ctSchema, }) {
|
|
11
|
+
this.log = log;
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.fix = fix !== null && fix !== void 0 ? fix : false;
|
|
14
|
+
this.ctSchema = ctSchema;
|
|
15
|
+
this.workflowSchema = [];
|
|
16
|
+
this.moduleName = moduleName !== null && moduleName !== void 0 ? moduleName : 'workflows';
|
|
17
|
+
this.fileName = config.moduleConfig[this.moduleName].fileName;
|
|
18
|
+
this.folderPath = (0, path_1.resolve)(config.basePath, config.moduleConfig[this.moduleName].dirName);
|
|
19
|
+
this.ctUidSet = new Set(['$all']);
|
|
20
|
+
this.missingCtInWorkflows = [];
|
|
21
|
+
this.missingCts = new Set();
|
|
22
|
+
this.workflowPath = '';
|
|
23
|
+
this.isBranchFixDone = false;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check whether the given path for the workflow exists or not
|
|
27
|
+
* If path exist read
|
|
28
|
+
* From the ctSchema add all the content type UID into ctUidSet to check whether the content-type is present or not
|
|
29
|
+
* @returns Array of object containing the workflow name, uid and content_types that are missing
|
|
30
|
+
*/
|
|
31
|
+
async run() {
|
|
32
|
+
var _a;
|
|
33
|
+
if (!(0, fs_1.existsSync)(this.folderPath)) {
|
|
34
|
+
this.log(`Skipping ${this.moduleName} audit`, 'warn');
|
|
35
|
+
this.log((0, messages_1.$t)(messages_1.auditMsg.NOT_VALID_PATH, { path: this.folderPath }), { color: 'yellow' });
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
this.workflowPath = (0, path_1.join)(this.folderPath, this.fileName);
|
|
39
|
+
this.workflowSchema = (0, fs_1.existsSync)(this.workflowPath)
|
|
40
|
+
? (0, lodash_2.values)(JSON.parse((0, fs_1.readFileSync)(this.workflowPath, 'utf8')))
|
|
41
|
+
: [];
|
|
42
|
+
this.ctSchema.forEach((ct) => this.ctUidSet.add(ct.uid));
|
|
43
|
+
for (const workflow of this.workflowSchema) {
|
|
44
|
+
const ctNotPresent = workflow.content_types.filter((ct) => !this.ctUidSet.has(ct));
|
|
45
|
+
const branch = (_a = workflow === null || workflow === void 0 ? void 0 : workflow.branches) === null || _a === void 0 ? void 0 : _a.filter((branch) => { var _a; return branch !== ((_a = this.config) === null || _a === void 0 ? void 0 : _a.branch); });
|
|
46
|
+
if (ctNotPresent.length || (branch === null || branch === void 0 ? void 0 : branch.length)) {
|
|
47
|
+
const tempwf = (0, lodash_1.cloneDeep)(workflow);
|
|
48
|
+
tempwf.content_types = ctNotPresent || [];
|
|
49
|
+
if (workflow === null || workflow === void 0 ? void 0 : workflow.branches) {
|
|
50
|
+
tempwf.branches = branch;
|
|
51
|
+
}
|
|
52
|
+
if (branch === null || branch === void 0 ? void 0 : branch.length) {
|
|
53
|
+
this.isBranchFixDone = true;
|
|
54
|
+
}
|
|
55
|
+
ctNotPresent.forEach((ct) => this.missingCts.add(ct));
|
|
56
|
+
this.missingCtInWorkflows.push(tempwf);
|
|
57
|
+
}
|
|
58
|
+
this.log((0, messages_1.$t)(messages_1.auditMsg.SCAN_WF_SUCCESS_MSG, {
|
|
59
|
+
name: workflow.name,
|
|
60
|
+
uid: workflow.uid,
|
|
61
|
+
}), 'info');
|
|
62
|
+
}
|
|
63
|
+
if (this.fix && (this.missingCtInWorkflows.length || this.isBranchFixDone)) {
|
|
64
|
+
await this.fixWorkflowSchema();
|
|
65
|
+
this.missingCtInWorkflows.forEach((wf) => (wf.fixStatus = 'Fixed'));
|
|
66
|
+
}
|
|
67
|
+
return this.missingCtInWorkflows;
|
|
68
|
+
}
|
|
69
|
+
async fixWorkflowSchema() {
|
|
70
|
+
var _a;
|
|
71
|
+
const newWorkflowSchema = (0, fs_1.existsSync)(this.workflowPath)
|
|
72
|
+
? JSON.parse((0, fs_1.readFileSync)(this.workflowPath, 'utf8'))
|
|
73
|
+
: {};
|
|
74
|
+
if (Object.keys(newWorkflowSchema).length !== 0) {
|
|
75
|
+
for (const workflow of this.workflowSchema) {
|
|
76
|
+
const fixedCts = workflow.content_types.filter((ct) => !this.missingCts.has(ct));
|
|
77
|
+
const fixedBranches = [];
|
|
78
|
+
(_a = workflow === null || workflow === void 0 ? void 0 : workflow.branches) === null || _a === void 0 ? void 0 : _a.forEach((branch) => {
|
|
79
|
+
var _a;
|
|
80
|
+
if (branch !== ((_a = this.config) === null || _a === void 0 ? void 0 : _a.branch)) {
|
|
81
|
+
const { uid, name } = workflow;
|
|
82
|
+
this.log((0, messages_1.$t)(messages_1.commonMsg.WF_BRANCH_REMOVAL, { uid, name, branch }), { color: 'yellow' });
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
fixedBranches.push(branch);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
if (fixedBranches.length > 0) {
|
|
89
|
+
newWorkflowSchema[workflow.uid].branches = fixedBranches;
|
|
90
|
+
}
|
|
91
|
+
if (fixedCts.length) {
|
|
92
|
+
newWorkflowSchema[workflow.uid].content_types = fixedCts;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const { name, uid } = workflow;
|
|
96
|
+
const warningMessage = (0, messages_1.$t)(messages_1.commonMsg.WORKFLOW_FIX_WARN, { name, uid });
|
|
97
|
+
this.log(warningMessage, { color: 'yellow' });
|
|
98
|
+
if (this.config.flags.yes || (await cli_utilities_1.ux.confirm(messages_1.commonMsg.WORKFLOW_FIX_CONFIRMATION))) {
|
|
99
|
+
delete newWorkflowSchema[workflow.uid];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
await this.writeFixContent(newWorkflowSchema);
|
|
105
|
+
}
|
|
106
|
+
async writeFixContent(newWorkflowSchema) {
|
|
107
|
+
var _a;
|
|
108
|
+
if (this.fix &&
|
|
109
|
+
(this.config.flags['copy-dir'] ||
|
|
110
|
+
((_a = this.config.flags['external-config']) === null || _a === void 0 ? void 0 : _a.skipConfirm) ||
|
|
111
|
+
this.config.flags.yes ||
|
|
112
|
+
(await cli_utilities_1.ux.confirm(messages_1.commonMsg.FIX_CONFIRMATION)))) {
|
|
113
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(this.folderPath, this.config.moduleConfig[this.moduleName].fileName), JSON.stringify(newWorkflowSchema));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.default = Workflows;
|
|
@@ -36,6 +36,12 @@ type RefErrorReturnType = {
|
|
|
36
36
|
missingRefs: string[];
|
|
37
37
|
display_name: string;
|
|
38
38
|
tree: Record<string, unknown>[];
|
|
39
|
+
uid?: string;
|
|
40
|
+
content_types?: string[];
|
|
41
|
+
title?: string;
|
|
42
|
+
};
|
|
43
|
+
type WorkflowExtensionsRefErrorReturnType = RefErrorReturnType & {
|
|
44
|
+
branches?: string[];
|
|
39
45
|
};
|
|
40
46
|
type ReferenceFieldDataType = CommonDataTypeStruct & {
|
|
41
47
|
reference_to: string[];
|
|
@@ -73,6 +79,10 @@ declare enum OutputColumn {
|
|
|
73
79
|
'Field name' = "display_name",
|
|
74
80
|
'Field type' = "data_type",
|
|
75
81
|
'Missing references' = "missingRefs",
|
|
76
|
-
Path = "treeStr"
|
|
82
|
+
Path = "treeStr",
|
|
83
|
+
title = "title",
|
|
84
|
+
'uid' = "uid",
|
|
85
|
+
'missingCts' = "content_types",
|
|
86
|
+
'Missing Branches' = "branches"
|
|
77
87
|
}
|
|
78
|
-
export { CtConstructorParam, ContentTypeStruct, ModuleConstructorParam, ReferenceFieldDataType, GlobalFieldDataType, ExtensionOrAppFieldDataType, JsonRTEFieldDataType, GroupFieldDataType, ModularBlocksDataType, RefErrorReturnType, ModularBlocksSchemaTypes, ModularBlockType, OutputColumn, ContentTypeSchemaType, GlobalFieldSchemaTypes, };
|
|
88
|
+
export { CtConstructorParam, ContentTypeStruct, ModuleConstructorParam, ReferenceFieldDataType, GlobalFieldDataType, ExtensionOrAppFieldDataType, JsonRTEFieldDataType, GroupFieldDataType, ModularBlocksDataType, RefErrorReturnType, ModularBlocksSchemaTypes, ModularBlockType, OutputColumn, ContentTypeSchemaType, GlobalFieldSchemaTypes, WorkflowExtensionsRefErrorReturnType, };
|
|
@@ -8,5 +8,9 @@ var OutputColumn;
|
|
|
8
8
|
OutputColumn["Field type"] = "data_type";
|
|
9
9
|
OutputColumn["Missing references"] = "missingRefs";
|
|
10
10
|
OutputColumn["Path"] = "treeStr";
|
|
11
|
+
OutputColumn["title"] = "title";
|
|
12
|
+
OutputColumn["uid"] = "uid";
|
|
13
|
+
OutputColumn["missingCts"] = "content_types";
|
|
14
|
+
OutputColumn["Missing Branches"] = "branches";
|
|
11
15
|
})(OutputColumn || (OutputColumn = {}));
|
|
12
16
|
exports.OutputColumn = OutputColumn;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface Extension {
|
|
2
|
+
stackHeaders: {
|
|
3
|
+
api_key: string;
|
|
4
|
+
};
|
|
5
|
+
urlPath: string;
|
|
6
|
+
uid: string;
|
|
7
|
+
created_at: string;
|
|
8
|
+
updated_at: string;
|
|
9
|
+
created_by: string;
|
|
10
|
+
updated_by: string;
|
|
11
|
+
tags?: [];
|
|
12
|
+
_version: number;
|
|
13
|
+
title: string;
|
|
14
|
+
config: {};
|
|
15
|
+
type: 'field';
|
|
16
|
+
data_type: string;
|
|
17
|
+
multiple: boolean;
|
|
18
|
+
srcdoc?: string;
|
|
19
|
+
scope: {
|
|
20
|
+
content_types: string[];
|
|
21
|
+
};
|
|
22
|
+
content_types?: string[];
|
|
23
|
+
fixStatus?: string;
|
|
24
|
+
}
|
package/lib/types/index.d.ts
CHANGED
package/lib/types/index.js
CHANGED
|
@@ -5,3 +5,5 @@ tslib_1.__exportStar(require("./utils"), exports);
|
|
|
5
5
|
tslib_1.__exportStar(require("./common"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./entries"), exports);
|
|
7
7
|
tslib_1.__exportStar(require("./content-types"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./workflow"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./extensions"), exports);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface Workflow {
|
|
2
|
+
uid: string;
|
|
3
|
+
name: string;
|
|
4
|
+
content_types: string[];
|
|
5
|
+
org_uid?: string;
|
|
6
|
+
api_key?: string;
|
|
7
|
+
workflow_stages?: Record<string, unknown>;
|
|
8
|
+
admin_users?: any;
|
|
9
|
+
enabled?: boolean;
|
|
10
|
+
deleted_at?: any;
|
|
11
|
+
missingRefs?: any;
|
|
12
|
+
fixStatus?: string;
|
|
13
|
+
branches?: string[];
|
|
14
|
+
}
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.5.1",
|
|
3
3
|
"commands": {
|
|
4
4
|
"cm:stacks:audit:fix": {
|
|
5
5
|
"id": "cm:stacks:audit:fix",
|
|
@@ -58,7 +58,9 @@
|
|
|
58
58
|
"options": [
|
|
59
59
|
"content-types",
|
|
60
60
|
"global-fields",
|
|
61
|
-
"entries"
|
|
61
|
+
"entries",
|
|
62
|
+
"extensions",
|
|
63
|
+
"workflows"
|
|
62
64
|
]
|
|
63
65
|
},
|
|
64
66
|
"copy-dir": {
|
|
@@ -87,7 +89,8 @@
|
|
|
87
89
|
"json:rte",
|
|
88
90
|
"json:extension",
|
|
89
91
|
"blocks",
|
|
90
|
-
"group"
|
|
92
|
+
"group",
|
|
93
|
+
"content_types"
|
|
91
94
|
]
|
|
92
95
|
},
|
|
93
96
|
"yes": {
|
|
@@ -208,7 +211,9 @@
|
|
|
208
211
|
"options": [
|
|
209
212
|
"content-types",
|
|
210
213
|
"global-fields",
|
|
211
|
-
"entries"
|
|
214
|
+
"entries",
|
|
215
|
+
"extensions",
|
|
216
|
+
"workflows"
|
|
212
217
|
]
|
|
213
218
|
},
|
|
214
219
|
"columns": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-audit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Contentstack audit plugin",
|
|
5
5
|
"author": "Contentstack CLI",
|
|
6
6
|
"homepage": "https://github.com/contentstack/cli",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@contentstack/cli-command": "~1.2.16",
|
|
22
|
-
"@contentstack/cli-utilities": "~1.
|
|
22
|
+
"@contentstack/cli-utilities": "~1.6.0",
|
|
23
23
|
"@oclif/plugin-help": "^5",
|
|
24
|
-
"@oclif/plugin-plugins": "^
|
|
24
|
+
"@oclif/plugin-plugins": "^5.0.0",
|
|
25
25
|
"chalk": "^4.1.2",
|
|
26
26
|
"fast-csv": "^4.3.6",
|
|
27
27
|
"fs-extra": "^11.1.1",
|
|
@@ -86,4 +86,4 @@
|
|
|
86
86
|
"keywords": [
|
|
87
87
|
"oclif"
|
|
88
88
|
]
|
|
89
|
-
}
|
|
89
|
+
}
|