@contentstack/cli-audit 1.3.1 → 1.3.2

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 Contentstack
3
+ Copyright (c) 2024 Contentstack
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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.3.1 linux-x64 node-v18.19.0
22
+ @contentstack/cli-audit/1.3.2 linux-x64 node-v18.19.0
23
23
  $ csdx --help [COMMAND]
24
24
  USAGE
25
25
  $ csdx COMMAND
@@ -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: CommandNames): Promise<void>;
19
+ start(command: CommandNames): Promise<boolean>;
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,11 +56,14 @@ 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)) {
59
+ if (this.flags['copy-dir'] &&
60
+ this.currentCommand === 'cm:stacks:audit:fix' &&
61
+ (0, fs_1.existsSync)(this.sharedConfig.basePath)) {
60
62
  // NOTE Clean up the backup dir if no issue found while audit the content
61
63
  (0, fs_1.rmSync)(this.sharedConfig.basePath, { recursive: true });
62
64
  }
63
65
  }
66
+ return !(0, isEmpty_1.default)(missingCtRefs) || !(0, isEmpty_1.default)(missingGfRefs) || !(0, isEmpty_1.default)(missingEntryRefs);
64
67
  }
65
68
  /**
66
69
  * The `scan` function performs an audit on different modules (content-types, global-fields, and
@@ -123,7 +126,9 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
123
126
  throw Error(this.$t(this.messages.NOT_VALID_PATH, { path: this.sharedConfig.basePath }));
124
127
  }
125
128
  // NOTE create bkp directory
126
- const backupDirPath = `${(this.flags['copy-path'] || this.flags['data-dir']).replace(/\/+$/, '')}_backup_${(0, uuid_1.v4)()}`;
129
+ const backupDirPath = `${(this.flags['copy-path'] ||
130
+ this.flags['data-dir'] ||
131
+ this.sharedConfig.basePath).replace(/\/+$/, '')}_backup_${(0, uuid_1.v4)()}`;
127
132
  if (!(0, fs_1.existsSync)(backupDirPath)) {
128
133
  (0, fs_1.mkdirSync)(backupDirPath, { recursive: true });
129
134
  }
@@ -162,8 +167,8 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
162
167
  * objects, where each object has two properties:
163
168
  */
164
169
  showOutputOnScreen(allMissingRefs) {
165
- var _a;
166
- if (this.sharedConfig.showTerminalOutput) {
170
+ var _a, _b;
171
+ if (this.sharedConfig.showTerminalOutput && !((_a = this.flags['external-config']) === null || _a === void 0 ? void 0 : _a.noTerminalOutput)) {
167
172
  this.log(''); // NOTE adding new line
168
173
  for (const { module, missingRefs } of allMissingRefs) {
169
174
  if (!(0, isEmpty_1.default)(missingRefs)) {
@@ -190,7 +195,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
190
195
  get: (row) => {
191
196
  return chalk_1.default.red(typeof row.missingRefs === 'object' ? JSON.stringify(row.missingRefs) : row.missingRefs);
192
197
  },
193
- } }, (((_a = tableValues[0]) === null || _a === void 0 ? void 0 : _a.fixStatus) ? this.fixStatus : {})), { treeStr: {
198
+ } }, (((_b = tableValues[0]) === null || _b === void 0 ? void 0 : _b.fixStatus) ? this.fixStatus : {})), { treeStr: {
194
199
  minWidth: 7,
195
200
  header: 'Path',
196
201
  } }), Object.assign({}, this.flags));
@@ -3,12 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BaseCommand = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const merge_1 = tslib_1.__importDefault(require("lodash/merge"));
6
+ const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
6
7
  const fs_1 = require("fs");
7
8
  const cli_command_1 = require("@contentstack/cli-command");
8
9
  const cli_utilities_1 = require("@contentstack/cli-utilities");
9
10
  const config_1 = tslib_1.__importDefault(require("./config"));
10
11
  const util_1 = require("./util");
11
12
  const messages_1 = tslib_1.__importStar(require("./messages"));
13
+ const noLog = (_message, _logType) => { };
12
14
  class BaseCommand extends cli_command_1.Command {
13
15
  constructor() {
14
16
  super(...arguments);
@@ -21,6 +23,7 @@ class BaseCommand extends cli_command_1.Command {
21
23
  * plugins, registering the configuration, and initializing the logger.
22
24
  */
23
25
  async init() {
26
+ var _a, _b, _c;
24
27
  await super.init();
25
28
  const { args, flags } = await this.parse({
26
29
  flags: this.ctor.flags,
@@ -31,11 +34,21 @@ class BaseCommand extends cli_command_1.Command {
31
34
  this.flags = flags;
32
35
  this.args = args;
33
36
  this.sharedConfig = Object.assign(this.sharedConfig, { flags: this.flags });
37
+ if (!(0, isEmpty_1.default)((_a = this.flags['external-config']) === null || _a === void 0 ? void 0 : _a.config)) {
38
+ this.sharedConfig = Object.assign(this.sharedConfig, (_b = this.flags['external-config']) === null || _b === void 0 ? void 0 : _b.config);
39
+ }
34
40
  cli_utilities_1.cliux.registerSearchPlugin();
35
41
  this.registerConfig();
36
42
  // Init logger
37
- const logger = new util_1.Logger(this.sharedConfig);
38
- this.log = logger.log.bind(logger);
43
+ if ((_c = this.flags['external-config']) === null || _c === void 0 ? void 0 : _c.noLog) {
44
+ this.log = noLog;
45
+ cli_utilities_1.ux.action.start = () => { };
46
+ cli_utilities_1.ux.action.stop = () => { };
47
+ }
48
+ else {
49
+ const logger = new util_1.Logger(this.sharedConfig);
50
+ this.log = logger.log.bind(logger);
51
+ }
39
52
  }
40
53
  /**
41
54
  * The catch function is used to handle errors from a command, either by adding custom logic or
@@ -1,4 +1,5 @@
1
1
  import { FlagInput } from '@contentstack/cli-utilities';
2
+ import { ConfigType } from '../../../../types';
2
3
  import { AuditBaseCommand } from '../../../../audit-base-command';
3
4
  export default class AuditFix extends AuditBaseCommand {
4
5
  static aliases: string[];
@@ -9,5 +10,8 @@ export default class AuditFix extends AuditBaseCommand {
9
10
  * The `run` function is an asynchronous function that performs an audit on different modules
10
11
  * (content-types, global-fields, entries) and generates a report.
11
12
  */
12
- run(): Promise<void>;
13
+ run(): Promise<void | {
14
+ config: ConfigType;
15
+ hasFix: boolean;
16
+ }>;
13
17
  }
@@ -3,17 +3,22 @@ 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");
7
6
  const messages_1 = require("../../../../messages");
8
7
  const audit_base_command_1 = require("../../../../audit-base-command");
8
+ const util_1 = require("../../../../util");
9
+ const jsonFlag = (0, util_1.getJsonInputFlags)({ hidden: true });
9
10
  class AuditFix extends audit_base_command_1.AuditBaseCommand {
10
11
  /**
11
12
  * The `run` function is an asynchronous function that performs an audit on different modules
12
13
  * (content-types, global-fields, entries) and generates a report.
13
14
  */
14
15
  async run() {
16
+ var _a;
15
17
  try {
16
- await this.start('cm:stacks:audit:fix');
18
+ const hasFix = await this.start('cm:stacks:audit:fix');
19
+ if ((_a = this.flags['external-config']) === null || _a === void 0 ? void 0 : _a.returnResponse) {
20
+ return { config: this.sharedConfig, hasFix };
21
+ }
17
22
  }
18
23
  catch (error) {
19
24
  this.log(error instanceof Error ? error.message : error, 'error');
@@ -56,4 +61,4 @@ AuditFix.flags = Object.assign({ 'report-path': cli_utilities_1.Flags.string({
56
61
  char: 'y',
57
62
  hidden: true,
58
63
  description: 'Use this flag to skip confirmation',
59
- }) }, (0, util_1.getTableFlags)());
64
+ }), 'external-config': jsonFlag() }, (0, util_1.getTableFlags)());
package/lib/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- declare const _default: {};
2
- export default _default;
1
+ import Audit from "./commands/cm/stacks/audit";
2
+ import AuditFix from "./commands/cm/stacks/audit/fix";
3
+ export { Audit, AuditFix };
package/lib/index.js CHANGED
@@ -1,3 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = {};
3
+ exports.AuditFix = exports.Audit = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const audit_1 = tslib_1.__importDefault(require("./commands/cm/stacks/audit"));
6
+ exports.Audit = audit_1.default;
7
+ const fix_1 = tslib_1.__importDefault(require("./commands/cm/stacks/audit/fix"));
8
+ exports.AuditFix = fix_1.default;
@@ -61,11 +61,11 @@ class ContentType {
61
61
  * JSON to the specified file path.
62
62
  */
63
63
  async writeFixContent() {
64
- var _a;
64
+ var _a, _b;
65
65
  let canWrite = true;
66
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));
67
+ if (!this.config.flags['copy-dir'] && !((_a = this.config.flags['external-config']) === null || _a === void 0 ? void 0 : _a.skipConfirm)) {
68
+ canWrite = (_b = this.config.flags.yes) !== null && _b !== void 0 ? _b : (await cli_utilities_1.ux.confirm(messages_1.commonMsg.FIX_CONFIRMATION));
69
69
  }
70
70
  if (canWrite) {
71
71
  (0, fs_1.writeFileSync)((0, path_1.join)(this.folderPath, this.config.moduleConfig[this.moduleName].fileName), JSON.stringify(this.schema));
@@ -380,8 +380,8 @@ class ContentType {
380
380
  const refExist = (0, find_1.default)(this.gfSchema, { uid: reference_to });
381
381
  if (!refExist) {
382
382
  this.missingRefs[this.currentUid].push(refErrorObj);
383
+ return block;
383
384
  }
384
- return refExist;
385
385
  }
386
386
  block.schema = this.runFixOnSchema(tree, block.schema);
387
387
  if ((0, isEmpty_1.default)(block.schema)) {
@@ -48,8 +48,10 @@ class Entries {
48
48
  const { uid, title } = entry;
49
49
  this.currentUid = uid;
50
50
  this.currentTitle = title;
51
- this.missingRefs[this.currentUid] = [];
52
- this.lookForReference([{ uid, name: title }], ctSchema, this.entries[entryUid]);
51
+ if (!this.missingRefs[this.currentUid]) {
52
+ this.missingRefs[this.currentUid] = [];
53
+ }
54
+ this.lookForReference([{ locale: code, uid, name: title }], ctSchema, this.entries[entryUid]);
53
55
  this.log((0, messages_1.$t)(messages_1.auditMsg.SCAN_ENTRY_SUCCESS_MSG, {
54
56
  title,
55
57
  local: code,
@@ -103,9 +105,10 @@ class Entries {
103
105
  * JSON to the specified file path.
104
106
  */
105
107
  async writeFixContent(filePath, schema) {
108
+ var _a;
106
109
  let canWrite = true;
107
110
  if (this.fix) {
108
- if (!this.config.flags['copy-dir']) {
111
+ if (!this.config.flags['copy-dir'] && !((_a = this.config.flags['external-config']) === null || _a === void 0 ? void 0 : _a.skipConfirm)) {
109
112
  canWrite = this.config.flags.yes || (await cli_utilities_1.ux.confirm(messages_1.commonMsg.FIX_CONFIRMATION));
110
113
  }
111
114
  if (canWrite) {
@@ -330,6 +333,9 @@ class Entries {
330
333
  // NOTE Global field Fix
331
334
  schema.forEach((field) => {
332
335
  const { uid, data_type } = field;
336
+ if (!Object(entry).hasOwnProperty(uid)) {
337
+ return;
338
+ }
333
339
  switch (data_type) {
334
340
  case 'global_field':
335
341
  entry[uid] = this.fixGlobalFieldReferences([...tree, { uid: field.uid, name: field.display_name, data_type: field.data_type }], field, entry[uid]);
@@ -447,17 +453,19 @@ class Entries {
447
453
  });
448
454
  }
449
455
  else {
450
- entry.children = entry.children
451
- .map((child) => {
452
- const refExist = this.jsonRefCheck(tree, field, child);
453
- if (!refExist)
454
- return null;
455
- if ((0, isEmpty_1.default)(child.children)) {
456
- child = this.fixJsonRteMissingReferences(tree, field, child);
457
- }
458
- return child;
459
- })
460
- .filter((val) => val);
456
+ if (entry === null || entry === void 0 ? void 0 : entry.children) {
457
+ entry.children = entry.children
458
+ .map((child) => {
459
+ const refExist = this.jsonRefCheck(tree, field, child);
460
+ if (!refExist)
461
+ return null;
462
+ if (!(0, isEmpty_1.default)(child.children)) {
463
+ child = this.fixJsonRteMissingReferences(tree, field, child);
464
+ }
465
+ return child;
466
+ })
467
+ .filter((val) => val);
468
+ }
461
469
  }
462
470
  return entry;
463
471
  }
@@ -16,3 +16,7 @@ export type PrintType = {
16
16
  bold?: boolean;
17
17
  color?: typeof Color;
18
18
  };
19
+ export type JSONFlagOptions = {
20
+ hidden?: boolean;
21
+ description?: string;
22
+ };
@@ -1,4 +1,5 @@
1
- import { IFlags, IncludeFlags } from '../types';
1
+ import { FlagDefinition } from '@contentstack/cli-utilities';
2
+ import { IFlags, IncludeFlags, JSONFlagOptions } from '../types';
2
3
  /**
3
4
  * The function `getTableFlags` returns a set of table flags based on the specified columns, with
4
5
  * updated descriptions and help groups.
@@ -7,4 +8,11 @@ import { IFlags, IncludeFlags } from '../types';
7
8
  * @returns an object of type `IncludeFlags<IFlags, keyof IFlags>`.
8
9
  */
9
10
  declare function getTableFlags(columns?: (keyof IFlags)[]): IncludeFlags<IFlags, keyof IFlags>;
10
- export { getTableFlags };
11
+ /**
12
+ * The function `getJsonInputFlags` returns a flag definition for parsing JSON input.
13
+ * @param {JSONFlagOptions} options - The `options` parameter is an object that contains the following
14
+ * properties:
15
+ * @returns a `FlagDefinition` object.
16
+ */
17
+ declare function getJsonInputFlags(options?: JSONFlagOptions): FlagDefinition<Record<string, unknown>, Record<string, unknown>>;
18
+ export { getTableFlags, getJsonInputFlags };
package/lib/util/flags.js CHANGED
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getTableFlags = void 0;
3
+ exports.getJsonInputFlags = exports.getTableFlags = void 0;
4
4
  const cli_utilities_1 = require("@contentstack/cli-utilities");
5
5
  const messages_1 = require("../messages");
6
+ const defaultJSONOptions = { description: 'Provide JSON input' };
6
7
  /**
7
8
  * The function `getTableFlags` returns a set of table flags based on the specified columns, with
8
9
  * updated descriptions and help groups.
@@ -24,3 +25,25 @@ function getTableFlags(columns = ['columns', 'sort', 'filter', 'csv', 'no-trunca
24
25
  return flags;
25
26
  }
26
27
  exports.getTableFlags = getTableFlags;
28
+ /**
29
+ * The function `getJsonInputFlags` returns a flag definition for parsing JSON input.
30
+ * @param {JSONFlagOptions} options - The `options` parameter is an object that contains the following
31
+ * properties:
32
+ * @returns a `FlagDefinition` object.
33
+ */
34
+ function getJsonInputFlags(options = defaultJSONOptions) {
35
+ const { hidden, description = defaultJSONOptions.description } = options;
36
+ return cli_utilities_1.Flags.custom({
37
+ hidden,
38
+ description,
39
+ parse: async (input, _opts) => {
40
+ try {
41
+ return JSON.parse(input);
42
+ }
43
+ catch (error) {
44
+ throw new Error('Invalid JSON');
45
+ }
46
+ },
47
+ });
48
+ }
49
+ exports.getJsonInputFlags = getJsonInputFlags;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.1",
2
+ "version": "1.3.2",
3
3
  "commands": {
4
4
  "cm:stacks:audit:fix": {
5
5
  "id": "cm:stacks:audit:fix",
@@ -98,6 +98,13 @@
98
98
  "hidden": true,
99
99
  "allowNo": false
100
100
  },
101
+ "external-config": {
102
+ "name": "external-config",
103
+ "type": "option",
104
+ "description": "Provide JSON input",
105
+ "hidden": true,
106
+ "multiple": false
107
+ },
101
108
  "columns": {
102
109
  "name": "columns",
103
110
  "type": "option",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentstack/cli-audit",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Contentstack audit plugin",
5
5
  "author": "Contentstack CLI",
6
6
  "homepage": "https://github.com/contentstack/cli",
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "@contentstack/cli-command": "~1.2.16",
22
- "@contentstack/cli-utilities": "~1.5.9",
22
+ "@contentstack/cli-utilities": "~1.5.10",
23
23
  "@oclif/plugin-help": "^5",
24
24
  "@oclif/plugin-plugins": "^4.1.9",
25
25
  "chalk": "^4.1.2",