@oclif/plugin-command-snapshot 3.1.3 → 3.2.0

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.
@@ -3,12 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const path = require("path");
4
4
  const fs = require("fs");
5
5
  const semver = require("semver");
6
- const _ = require("lodash");
6
+ const lodash_1 = require("lodash");
7
7
  const just_diff_1 = require("just-diff");
8
8
  const core_1 = require("@oclif/core");
9
9
  const snapshot_command_1 = require("../../snapshot-command");
10
10
  const generate_1 = require("./generate");
11
11
  const chalk_1 = require("chalk");
12
+ function isNumber(n) {
13
+ return Number.isInteger(Number(n));
14
+ }
15
+ function isMeaningless(n) {
16
+ const meaninglessKeys = ['$comment', '__computed'];
17
+ return meaninglessKeys.includes(n);
18
+ }
12
19
  class SchemaCompare extends snapshot_command_1.SnapshotCommand {
13
20
  async run() {
14
21
  const { flags } = await this.parse(SchemaCompare);
@@ -28,25 +35,34 @@ class SchemaCompare extends snapshot_command_1.SnapshotCommand {
28
35
  this.log('No changes have been detected.');
29
36
  return [];
30
37
  }
31
- const humandReadableChanges = {};
38
+ const humanReadableChanges = {};
32
39
  for (const change of changes) {
40
+ const lastPathElement = change.path[change.path.length - 1];
41
+ if (isMeaningless(lastPathElement))
42
+ continue;
33
43
  const objPath = change.path.join('.');
34
- const existing = _.get(existingSchema, objPath);
35
- const latest = _.get(latestSchema, objPath);
44
+ const existing = (0, lodash_1.get)(existingSchema, objPath);
45
+ const latest = (0, lodash_1.get)(latestSchema, objPath);
36
46
  const [commandId] = objPath.split('.definitions');
37
47
  const readablePath = objPath.replace(`${commandId}.`, '');
38
- if (!humandReadableChanges[commandId]) {
39
- humandReadableChanges[commandId] = [];
48
+ if (!humanReadableChanges[commandId]) {
49
+ humanReadableChanges[commandId] = [];
40
50
  }
51
+ const lastElementIsNum = isNumber(lastPathElement);
52
+ const basePath = lastElementIsNum ? readablePath.replace(`.${lastPathElement}`, '') : readablePath;
41
53
  switch (change.op) {
42
54
  case 'replace':
43
- humandReadableChanges[commandId].push(`${(0, chalk_1.underline)(readablePath)} was changed from ${(0, chalk_1.cyan)(existing)} to ${(0, chalk_1.cyan)(latest)}`);
55
+ humanReadableChanges[commandId].push(`${(0, chalk_1.underline)(readablePath)} was changed from ${(0, chalk_1.cyan)(existing)} to ${(0, chalk_1.cyan)(latest)}`);
44
56
  break;
45
57
  case 'add':
46
- humandReadableChanges[commandId].push(`${(0, chalk_1.underline)(readablePath)} was ${(0, chalk_1.cyan)('added')} to latest schema`);
58
+ humanReadableChanges[commandId].push(lastElementIsNum ?
59
+ `Array item at ${(0, chalk_1.underline)(basePath)} was ${(0, chalk_1.cyan)('added')} to latest schema` :
60
+ `${(0, chalk_1.underline)(readablePath)} was ${(0, chalk_1.cyan)('added')} to latest schema`);
47
61
  break;
48
62
  case 'remove':
49
- humandReadableChanges[commandId].push(`${(0, chalk_1.underline)(readablePath)} was ${(0, chalk_1.cyan)('not found')} in latest schema`);
63
+ humanReadableChanges[commandId].push(lastElementIsNum ?
64
+ `Array item at ${(0, chalk_1.underline)(basePath)} was ${(0, chalk_1.cyan)('not found')} in latest schema` :
65
+ `${(0, chalk_1.underline)(readablePath)} was ${(0, chalk_1.cyan)('not found')} in latest schema`);
50
66
  break;
51
67
  default:
52
68
  break;
@@ -54,7 +70,7 @@ class SchemaCompare extends snapshot_command_1.SnapshotCommand {
54
70
  }
55
71
  this.log();
56
72
  this.log((0, chalk_1.bold)((0, chalk_1.red)('Found the following schema changes:')));
57
- for (const [commandId, changes] of Object.entries(humandReadableChanges)) {
73
+ for (const [commandId, changes] of Object.entries(humanReadableChanges)) {
58
74
  this.log();
59
75
  this.log((0, chalk_1.bold)(commandId));
60
76
  for (const change of changes) {
@@ -62,7 +78,8 @@ class SchemaCompare extends snapshot_command_1.SnapshotCommand {
62
78
  }
63
79
  }
64
80
  this.log();
65
- this.log('If intended, please update the schema file(s) and run again.');
81
+ const bin = process.platform === 'win32' ? 'bin\\dev.cmd' : 'bin/dev';
82
+ this.log('If intended, please update the schema file(s) and run again:', (0, chalk_1.bold)(`${bin} ${(0, core_1.toConfiguredId)('schema:generate', this.config)}`));
66
83
  process.exitCode = 1;
67
84
  return changes;
68
85
  }
@@ -11,9 +11,9 @@ export declare type GenerateResponse = string[];
11
11
  export declare function getAllFiles(dirPath: string, ext: string, allFiles?: string[]): string[];
12
12
  export declare class SchemaGenerator {
13
13
  private base;
14
- private ignorevoid;
14
+ private ignoreVoid;
15
15
  private classToId;
16
- constructor(base: SnapshotCommand, ignorevoid?: boolean);
16
+ constructor(base: SnapshotCommand, ignoreVoid?: boolean);
17
17
  generate(): Promise<Schemas>;
18
18
  private generateSchema;
19
19
  private getAllCmdFiles;
@@ -13,7 +13,7 @@ function getAllFiles(dirPath, ext, allFiles = []) {
13
13
  files = fs.readdirSync(dirPath);
14
14
  }
15
15
  catch (_a) { }
16
- files.forEach(file => {
16
+ for (const file of files) {
17
17
  const fPath = path.join(dirPath, file);
18
18
  if (fs.statSync(fPath).isDirectory()) {
19
19
  allFiles = getAllFiles(fPath, ext, allFiles);
@@ -21,14 +21,14 @@ function getAllFiles(dirPath, ext, allFiles = []) {
21
21
  else if (file.endsWith(ext)) {
22
22
  allFiles.push(fPath);
23
23
  }
24
- });
24
+ }
25
25
  return allFiles;
26
26
  }
27
27
  exports.getAllFiles = getAllFiles;
28
28
  class SchemaGenerator {
29
- constructor(base, ignorevoid = true) {
29
+ constructor(base, ignoreVoid = true) {
30
30
  this.base = base;
31
- this.ignorevoid = ignorevoid;
31
+ this.ignoreVoid = ignoreVoid;
32
32
  this.classToId = {};
33
33
  }
34
34
  async generate() {
@@ -40,7 +40,7 @@ class SchemaGenerator {
40
40
  const cmdSchemas = {};
41
41
  for (const file of this.getAllCmdFiles()) {
42
42
  const { returnType, commandId } = this.parseCmdFile(file);
43
- if (this.ignorevoid && returnType === 'void')
43
+ if (this.ignoreVoid && returnType === 'void')
44
44
  continue;
45
45
  cmdSchemas[commandId] = this.generateSchema(returnType, file);
46
46
  }
@@ -63,12 +63,8 @@ class SchemaGenerator {
63
63
  return (0, ts_json_schema_generator_1.createGenerator)(config).createSchema(config.type);
64
64
  }
65
65
  catch (error) {
66
- if (error.message.toLowerCase().includes('no root type')) {
67
- throw new Error(`Schema generator could not find the ${(0, chalk_1.red)(returnType)} type. Please make sure that ${(0, chalk_1.red)(returnType)} is exported.`);
68
- }
69
- else {
70
- throw error;
71
- }
66
+ const error_ = error.message.toLowerCase().includes('no root type') ? new Error(`Schema generator could not find the ${(0, chalk_1.red)(returnType)} type. Please make sure that ${(0, chalk_1.red)(returnType)} is exported.`) : error;
67
+ throw error_;
72
68
  }
73
69
  }
74
70
  getAllCmdFiles() {
@@ -77,8 +73,9 @@ class SchemaGenerator {
77
73
  }
78
74
  getAllHookFiles() {
79
75
  var _a, _b;
76
+ // eslint-disable-next-line unicorn/no-array-reduce
80
77
  const hookFiles = Object.values((_b = (_a = this.base.config.pjson.oclif) === null || _a === void 0 ? void 0 : _a.hooks) !== null && _b !== void 0 ? _b : {}).reduce((x, y) => {
81
- return Array.isArray(y) ? x.concat(y) : x.concat([y]);
78
+ return Array.isArray(y) ? [...x, ...y] : [...x, y];
82
79
  }, []);
83
80
  const { rootDir, outDir } = this.getDirs();
84
81
  return hookFiles.map(h => `${path.resolve(h)}.ts`.replace(outDir, rootDir));
@@ -130,13 +127,13 @@ class SchemaGenerator {
130
127
  return { returnType, hookId };
131
128
  }
132
129
  validateReturnType(returnType, commandId) {
133
- const notAllowed = this.ignorevoid ? ['any', 'unknown'] : ['any', 'unknown', 'void'];
134
- const vaugeTypes = ['JsonMap', 'JsonCollection', 'AnyJson'];
130
+ const notAllowed = this.ignoreVoid ? ['any', 'unknown'] : ['any', 'unknown', 'void'];
131
+ const vagueTypes = ['JsonMap', 'JsonCollection', 'AnyJson'];
135
132
  if (notAllowed.includes(returnType)) {
136
133
  throw new Error(`${returnType} (from ${commandId}) is not allowed. Please use a more specific type.`);
137
134
  }
138
- else if (vaugeTypes.includes(returnType)) {
139
- throw new Error(`${returnType} (from ${commandId}) is too vauge. Please use a more specific type.`);
135
+ else if (vagueTypes.includes(returnType)) {
136
+ throw new Error(`${returnType} (from ${commandId}) is too vague. Please use a more specific type.`);
140
137
  }
141
138
  }
142
139
  determineCommandId(contents) {
@@ -16,7 +16,7 @@ class Compare extends snapshot_command_1.SnapshotCommand {
16
16
  async compareSnapshot(initialCommands, updatedCommands) {
17
17
  const removedCommands = [];
18
18
  const diffCommands = [];
19
- initialCommands.forEach(initialCommand => {
19
+ for (const initialCommand of initialCommands) {
20
20
  const updatedCommand = updatedCommands.find(updatedCommand => {
21
21
  // Protect against old snapshot files that don't have the plugin entry filled out.
22
22
  const samePlugin = initialCommand.plugin ? initialCommand.plugin === updatedCommand.plugin : true;
@@ -40,7 +40,7 @@ class Compare extends snapshot_command_1.SnapshotCommand {
40
40
  else {
41
41
  removedCommands.push(initialCommand.command);
42
42
  }
43
- });
43
+ }
44
44
  const initialCommandNames = initialCommands.map(initialCommand => initialCommand.command);
45
45
  const updatedCommandNames = updatedCommands.map(updatedCommand => updatedCommand.name);
46
46
  const addedCommands = _.difference(updatedCommandNames, initialCommandNames);
@@ -51,30 +51,30 @@ class Compare extends snapshot_command_1.SnapshotCommand {
51
51
  // Fail the process since there are changes to the snapshot file
52
52
  process.exitCode = 1;
53
53
  this.log(`The following commands and flags have modified: (${chalk.green('+')} added, ${chalk.red('-')} removed)${os_1.EOL}`);
54
- removedCommands.forEach(command => {
54
+ for (const command of removedCommands) {
55
55
  this.log(chalk.red(`\t-${command}`));
56
- });
57
- addedCommands.forEach(command => {
56
+ }
57
+ for (const command of addedCommands) {
58
58
  this.log(chalk.green(`\t+${command}`));
59
- });
59
+ }
60
60
  const removedProperties = [];
61
- diffCommands.forEach(command => {
61
+ const printCommandDiff = (properties, propertyName) => {
62
+ if (properties.some(prop => prop.added || prop.removed))
63
+ this.log(`\t ${propertyName}:`);
64
+ for (const prop of properties) {
65
+ if (prop.added || prop.removed) {
66
+ const color = prop.added ? chalk.green : chalk.red;
67
+ this.log(color(`\t\t${prop.added ? '+' : '-'}${prop.name}`));
68
+ }
69
+ if (prop.removed)
70
+ removedProperties.push();
71
+ }
72
+ };
73
+ for (const command of diffCommands) {
62
74
  this.log(`\t${command.name}`);
63
- const printCommandDiff = (properties, propertyName) => {
64
- if (properties.find(prop => prop.added || prop.removed))
65
- this.log(`\t ${propertyName}:`);
66
- properties.forEach(prop => {
67
- if (prop.added || prop.removed) {
68
- const color = prop.added ? chalk.green : chalk.red;
69
- this.log(color(`\t\t${prop.added ? '+' : '-'}${prop.name}`));
70
- }
71
- if (prop.removed)
72
- removedProperties.push();
73
- });
74
- };
75
75
  printCommandDiff(command.flags, 'Flags');
76
76
  printCommandDiff(command.alias, 'Aliases');
77
- });
77
+ }
78
78
  this.log(`${os_1.EOL}Command, flag, or alias differences detected. If intended, please update the snapshot file and run again.`);
79
79
  // Check if existent commands, or properties (flags, aliases) have been deleted
80
80
  if (removedCommands.length > 0 || removedProperties.length > 0) {
@@ -104,18 +104,18 @@ class Compare extends snapshot_command_1.SnapshotCommand {
104
104
  const addedProperty = _.difference(updatedPropertyNames, initial);
105
105
  const removedProperty = _.difference(initial, updatedPropertyNames);
106
106
  const changedProperty = [];
107
- updated.forEach(update => {
107
+ for (const update of updated) {
108
108
  if (addedProperty.includes(update.name)) {
109
109
  update.added = true;
110
110
  changedProperty.push(update);
111
111
  }
112
- });
113
- removedProperty.forEach(remove => {
112
+ }
113
+ for (const remove of removedProperty) {
114
114
  changedProperty.push({ name: remove, removed: true });
115
115
  // The removed flags in not included in the updated flags, but we want it to
116
116
  // so it shows removed.
117
117
  updated.push({ name: remove, removed: true });
118
- });
118
+ }
119
119
  return { addedProperty, removedProperty, updated, changedProperty };
120
120
  }
121
121
  get changed() {
@@ -1,4 +1,4 @@
1
- import { Command } from '@oclif/core';
1
+ import { Command, Interfaces } from '@oclif/core';
2
2
  export declare type SnapshotEntry = {
3
3
  command: string;
4
4
  plugin: string;
@@ -6,6 +6,6 @@ export declare type SnapshotEntry = {
6
6
  alias: string[];
7
7
  };
8
8
  export declare abstract class SnapshotCommand extends Command {
9
- get commands(): import("@oclif/core/lib/interfaces").Command.Plugin[];
9
+ get commands(): Interfaces.Command.Loadable[];
10
10
  get entries(): SnapshotEntry[];
11
11
  }
@@ -1 +1 @@
1
- {"version":"3.1.3","commands":{"schema:compare":{"id":"schema:compare","strict":true,"pluginName":"@oclif/plugin-command-snapshot","pluginAlias":"@oclif/plugin-command-snapshot","pluginType":"core","aliases":[],"flags":{"filepath":{"name":"filepath","type":"option","description":"path of the generated snapshot file","multiple":false,"default":"./schemas"}},"args":[]},"schema:generate":{"id":"schema:generate","strict":true,"pluginName":"@oclif/plugin-command-snapshot","pluginAlias":"@oclif/plugin-command-snapshot","pluginType":"core","aliases":[],"flags":{"filepath":{"name":"filepath","type":"option","description":"directory to save the generated schema files; can use \"{version}\" to insert the current CLI/plugin version","multiple":false,"default":"./schemas"},"singlefile":{"name":"singlefile","type":"boolean","description":"put generated schema into a single file","allowNo":false},"ignorevoid":{"name":"ignorevoid","type":"boolean","description":"ignore commands that return void","allowNo":false}},"args":[]},"snapshot:compare":{"id":"snapshot:compare","strict":true,"pluginName":"@oclif/plugin-command-snapshot","pluginAlias":"@oclif/plugin-command-snapshot","pluginType":"core","aliases":[],"flags":{"filepath":{"name":"filepath","type":"option","description":"path of the generated snapshot file","multiple":false,"default":"./command-snapshot.json"}},"args":[]},"snapshot:generate":{"id":"snapshot:generate","strict":true,"pluginName":"@oclif/plugin-command-snapshot","pluginAlias":"@oclif/plugin-command-snapshot","pluginType":"core","aliases":[],"flags":{"filepath":{"name":"filepath","type":"option","description":"path to save the generated snapshot file; can use \"{version}\" to replace the current CLI/plugin version","multiple":false,"default":"./command-snapshot.json"}},"args":[]}}}
1
+ {"version":"3.2.0","commands":{"schema:compare":{"id":"schema:compare","strict":true,"pluginName":"@oclif/plugin-command-snapshot","pluginAlias":"@oclif/plugin-command-snapshot","pluginType":"core","aliases":[],"flags":{"filepath":{"name":"filepath","type":"option","description":"path of the generated snapshot file","multiple":false,"default":"./schemas"}},"args":[]},"schema:generate":{"id":"schema:generate","strict":true,"pluginName":"@oclif/plugin-command-snapshot","pluginAlias":"@oclif/plugin-command-snapshot","pluginType":"core","aliases":[],"flags":{"filepath":{"name":"filepath","type":"option","description":"directory to save the generated schema files; can use \"{version}\" to insert the current CLI/plugin version","multiple":false,"default":"./schemas"},"singlefile":{"name":"singlefile","type":"boolean","description":"put generated schema into a single file","allowNo":false},"ignorevoid":{"name":"ignorevoid","type":"boolean","description":"ignore commands that return void","allowNo":false}},"args":[]},"snapshot:compare":{"id":"snapshot:compare","strict":true,"pluginName":"@oclif/plugin-command-snapshot","pluginAlias":"@oclif/plugin-command-snapshot","pluginType":"core","aliases":[],"flags":{"filepath":{"name":"filepath","type":"option","description":"path of the generated snapshot file","multiple":false,"default":"./command-snapshot.json"}},"args":[]},"snapshot:generate":{"id":"snapshot:generate","strict":true,"pluginName":"@oclif/plugin-command-snapshot","pluginAlias":"@oclif/plugin-command-snapshot","pluginType":"core","aliases":[],"flags":{"filepath":{"name":"filepath","type":"option","description":"path to save the generated snapshot file; can use \"{version}\" to replace the current CLI/plugin version","multiple":false,"default":"./command-snapshot.json"}},"args":[]}}}
package/package.json CHANGED
@@ -1,38 +1,38 @@
1
1
  {
2
2
  "name": "@oclif/plugin-command-snapshot",
3
3
  "description": "generates and compares OCLIF plugins snapshot files",
4
- "version": "3.1.3",
4
+ "version": "3.2.0",
5
5
  "author": "Salesforce",
6
6
  "bugs": "https://github.com/oclif/plugin-command-snapshot/issues",
7
7
  "dependencies": {
8
- "@oclif/core": "^1.3.4",
8
+ "@oclif/core": "^1.16.4",
9
9
  "chalk": "^4.1.2",
10
- "just-diff": "^3.1.1",
11
- "semver": "^7.3.5",
12
- "sinon": "^11.1.2",
13
- "ts-json-schema-generator": "^0.97.0",
14
- "tslib": "^2"
10
+ "just-diff": "^5.1.1",
11
+ "lodash": "^4.17.21",
12
+ "semver": "^7.3.7",
13
+ "ts-json-schema-generator": "^1.1.0",
14
+ "tslib": "^2.4.0"
15
15
  },
16
16
  "devDependencies": {
17
17
  "@commitlint/config-conventional": "^12.1.4",
18
- "@oclif/plugin-help": "^5.1.11",
19
- "@oclif/test": "^2.1.0",
20
- "@types/chai": "^4",
18
+ "@oclif/plugin-help": "^5.1.12",
19
+ "@oclif/test": "^2.1.1",
20
+ "@types/chai": "^4.3.3",
21
21
  "@types/mocha": "^8",
22
22
  "@types/node": "^15",
23
23
  "@types/semver": "^7.3.9",
24
24
  "chai": "^4",
25
25
  "commitlint": "^12.1.4",
26
- "eslint": "^7",
27
- "eslint-config-oclif": "^3.1",
28
- "eslint-config-oclif-typescript": "^0.2",
29
- "globby": "^11",
26
+ "eslint": "^7.32.0",
27
+ "eslint-config-oclif": "^4",
28
+ "eslint-config-oclif-typescript": "^1.0.2",
30
29
  "husky": "6",
31
30
  "mocha": "^8",
32
31
  "nyc": "^15",
33
- "oclif": "^2.4.4",
34
- "ts-node": "^9",
35
- "typescript": "^4.5.5"
32
+ "oclif": "^2.6.3",
33
+ "sinon": "^11.1.2",
34
+ "ts-node": "^10",
35
+ "typescript": "^4.8.3"
36
36
  },
37
37
  "engines": {
38
38
  "node": ">=12.0.0"
@@ -74,4 +74,4 @@
74
74
  "test": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\" --timeout 20000",
75
75
  "version": "oclif readme && git add README.md"
76
76
  }
77
- }
77
+ }