@oclif/plugin-command-snapshot 5.0.10 → 5.1.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.
@@ -10,6 +10,5 @@ export default class SchemaCompare extends SnapshotCommand {
10
10
  filepath: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
11
  };
12
12
  run(): Promise<SchemaComparison>;
13
- private generateLatestSchema;
14
13
  private readExistingSchema;
15
14
  }
@@ -6,8 +6,8 @@ import * as fs from 'node:fs';
6
6
  import * as path from 'node:path';
7
7
  import * as semver from 'semver';
8
8
  import SnapshotCommand from '../../snapshot-command.js';
9
- import { getKeyNameFromFilename } from '../../util.js';
10
- import { SchemaGenerator, getAllFiles } from './generate.js';
9
+ import { GLOB_PATTERNS, getAllFiles, getKeyNameFromFilename } from '../../util.js';
10
+ import { SchemaGenerator } from './generate.js';
11
11
  function isNumber(n) {
12
12
  return Number.isInteger(Number(n));
13
13
  }
@@ -25,6 +25,19 @@ export default class SchemaCompare extends SnapshotCommand {
25
25
  }),
26
26
  };
27
27
  async run() {
28
+ const strategy = typeof this.config.pjson.oclif?.commands === 'string' ? 'pattern' : this.config.pjson.oclif?.commands?.strategy;
29
+ const commandsDir = typeof this.config.pjson.oclif?.commands === 'string'
30
+ ? this.config.pjson.oclif?.commands
31
+ : this.config.pjson.oclif?.commands?.target;
32
+ const commandGlobs = typeof this.config.pjson.oclif?.commands === 'string'
33
+ ? GLOB_PATTERNS
34
+ : this.config.pjson.oclif?.commands?.globPatterns;
35
+ if (strategy === 'single') {
36
+ this.error('This command is not supported for single command CLIs');
37
+ }
38
+ if (strategy === 'explicit') {
39
+ this.error('This command is not supported for explicit command discovery');
40
+ }
28
41
  const { flags } = await this.parse(SchemaCompare);
29
42
  try {
30
43
  fs.accessSync(flags.filepath);
@@ -34,7 +47,8 @@ export default class SchemaCompare extends SnapshotCommand {
34
47
  return [];
35
48
  }
36
49
  const existingSchema = this.readExistingSchema(flags.filepath);
37
- const latestSchema = await this.generateLatestSchema();
50
+ const generator = new SchemaGenerator({ base: this, commandGlobs, commandsDir });
51
+ const latestSchema = await generator.generate();
38
52
  this.debug('existingSchema', existingSchema);
39
53
  this.debug('latestSchema', latestSchema);
40
54
  const changes = diff(latestSchema, existingSchema);
@@ -89,15 +103,11 @@ export default class SchemaCompare extends SnapshotCommand {
89
103
  }
90
104
  }
91
105
  this.log();
92
- const bin = process.platform === 'win32' ? 'bin\\dev.cmd' : 'bin/dev';
106
+ const bin = process.platform === 'win32' ? 'bin\\dev.cmd' : 'bin/dev.js';
93
107
  this.log('If intended, please update the schema file(s) and run again:', chalk.bold(`${bin} ${toConfiguredId('schema:generate', this.config)}`));
94
108
  process.exitCode = 1;
95
109
  return changes;
96
110
  }
97
- async generateLatestSchema() {
98
- const generator = new SchemaGenerator(this);
99
- return generator.generate();
100
- }
101
111
  readExistingSchema(filePath) {
102
112
  const contents = fs.readdirSync(filePath);
103
113
  const folderIsVersioned = contents.every((c) => semver.valid(c));
@@ -8,12 +8,19 @@ export type Schemas = {
8
8
  hooks: SchemasMap;
9
9
  };
10
10
  export type GenerateResponse = string[];
11
- export declare function getAllFiles(dirPath: string, ext: string, allFiles?: string[]): string[];
11
+ type SchemaGenerateOptions = {
12
+ base: SnapshotCommand;
13
+ commandGlobs?: string[];
14
+ commandsDir?: string;
15
+ ignoreVoid?: boolean;
16
+ };
12
17
  export declare class SchemaGenerator {
13
18
  private base;
14
- private ignoreVoid;
15
19
  private classToId;
16
- constructor(base: SnapshotCommand, ignoreVoid?: boolean);
20
+ private commandGlobs;
21
+ private commandsDir;
22
+ private ignoreVoid;
23
+ constructor(options: SchemaGenerateOptions);
17
24
  generate(): Promise<Schemas>;
18
25
  private determineCommandId;
19
26
  private generateSchema;
@@ -43,3 +50,4 @@ export default class SchemaGenerate extends SnapshotCommand {
43
50
  };
44
51
  run(): Promise<GenerateResponse>;
45
52
  }
53
+ export {};
@@ -1,35 +1,22 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import chalk from 'chalk';
3
+ import { globbySync } from 'globby';
3
4
  import * as fs from 'node:fs';
4
5
  import * as path from 'node:path';
5
6
  import { createGenerator } from 'ts-json-schema-generator';
6
7
  import SnapshotCommand from '../../snapshot-command.js';
7
- import { getSchemaFileName } from '../../util.js';
8
- export function getAllFiles(dirPath, ext, allFiles = []) {
9
- let files = [];
10
- try {
11
- files = fs.readdirSync(dirPath);
12
- }
13
- catch { }
14
- for (const file of files) {
15
- const fPath = path.join(dirPath, file);
16
- if (fs.statSync(fPath).isDirectory()) {
17
- allFiles = getAllFiles(fPath, ext, allFiles);
18
- }
19
- else if (file.endsWith(ext)) {
20
- allFiles.push(fPath);
21
- }
22
- }
23
- return allFiles;
24
- }
8
+ import { GLOB_PATTERNS, getAllFiles, getSchemaFileName } from '../../util.js';
25
9
  export class SchemaGenerator {
26
10
  base;
27
- ignoreVoid;
28
11
  classToId = {};
29
- // eslint-disable-next-line no-useless-constructor
30
- constructor(base, ignoreVoid = true) {
31
- this.base = base;
32
- this.ignoreVoid = ignoreVoid;
12
+ commandGlobs;
13
+ commandsDir;
14
+ ignoreVoid;
15
+ constructor(options) {
16
+ this.base = options.base;
17
+ this.ignoreVoid = options.ignoreVoid ?? true;
18
+ this.commandsDir = options.commandsDir;
19
+ this.commandGlobs = options.commandGlobs ?? GLOB_PATTERNS;
33
20
  }
34
21
  async generate() {
35
22
  for (const cmd of this.base.commands) {
@@ -81,7 +68,11 @@ export class SchemaGenerator {
81
68
  }
82
69
  }
83
70
  getAllCmdFiles() {
84
- const { rootDir } = this.getDirs();
71
+ const { outDir, rootDir } = this.getDirs();
72
+ if (this.commandsDir) {
73
+ const commandsSrcDir = path.resolve(this.base.config.root, this.commandsDir).replace(outDir, rootDir);
74
+ return globbySync(this.commandGlobs, { absolute: true, cwd: commandsSrcDir });
75
+ }
85
76
  return getAllFiles(path.join(rootDir, 'commands'), '.ts');
86
77
  }
87
78
  getAllHookFiles() {
@@ -180,8 +171,21 @@ export default class SchemaGenerate extends SnapshotCommand {
180
171
  }),
181
172
  };
182
173
  async run() {
174
+ const strategy = typeof this.config.pjson.oclif?.commands === 'string' ? 'pattern' : this.config.pjson.oclif?.commands?.strategy;
175
+ const commandsDir = typeof this.config.pjson.oclif?.commands === 'string'
176
+ ? this.config.pjson.oclif?.commands
177
+ : this.config.pjson.oclif?.commands?.target;
178
+ const commandGlobs = typeof this.config.pjson.oclif?.commands === 'string'
179
+ ? GLOB_PATTERNS
180
+ : this.config.pjson.oclif?.commands?.globPatterns;
181
+ if (strategy === 'single') {
182
+ this.error('This command is not supported for single command CLIs');
183
+ }
184
+ if (strategy === 'explicit') {
185
+ this.error('This command is not supported for explicit command discovery');
186
+ }
183
187
  const { flags } = await this.parse(SchemaGenerate);
184
- const generator = new SchemaGenerator(this, flags.ignorevoid);
188
+ const generator = new SchemaGenerator({ base: this, commandGlobs, commandsDir, ignoreVoid: flags.ignorevoid });
185
189
  const schemas = await generator.generate();
186
190
  const directory = flags.filepath.replace('{version}', this.config.version);
187
191
  fs.mkdirSync(directory, { recursive: true });
package/lib/util.d.ts CHANGED
@@ -10,3 +10,5 @@ export declare const getSchemaFileName: (cmdId: string) => string;
10
10
  * @returns {string} - command ID
11
11
  */
12
12
  export declare const getKeyNameFromFilename: (file: string) => string;
13
+ export declare const getAllFiles: (dirPath: string, ext: string, allFiles?: string[]) => string[];
14
+ export declare const GLOB_PATTERNS: string[];
package/lib/util.js CHANGED
@@ -1,3 +1,5 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
1
3
  /**
2
4
  * Get the file name for a given command ID replacing "-" with "__" and ":" with "-"
3
5
  * @param cmdId - command ID
@@ -13,3 +15,19 @@ export const getSchemaFileName = (cmdId) => {
13
15
  * @returns {string} - command ID
14
16
  */
15
17
  export const getKeyNameFromFilename = (file) => file.replaceAll('-', ':').replaceAll('__', '-').replace('.json', '');
18
+ export const getAllFiles = (dirPath, ext, allFiles = []) => safeReadDirSync(dirPath)
19
+ .flatMap((f) => f.isDirectory() ? getAllFiles(path.join(dirPath, f.name), ext, allFiles) : path.join(dirPath, f.name))
20
+ .filter((f) => f.endsWith(ext));
21
+ const safeReadDirSync = (dirPath) => {
22
+ try {
23
+ // TODO: use recursive option when available in Node 20
24
+ return fs.readdirSync(dirPath, { withFileTypes: true });
25
+ }
26
+ catch {
27
+ return [];
28
+ }
29
+ };
30
+ export const GLOB_PATTERNS = [
31
+ '**/*.+(js|cjs|mjs|ts|tsx|mts|cts)',
32
+ '!**/*.+(d.ts|test.ts|test.js|spec.ts|spec.js|d.mts|d.cts)?(x)',
33
+ ];
package/oclif.lock CHANGED
@@ -1311,6 +1311,39 @@
1311
1311
  node-gyp "^8.2.0"
1312
1312
  read-package-json-fast "^2.0.1"
1313
1313
 
1314
+ "@oclif/core@3.21.0":
1315
+ version "3.21.0"
1316
+ resolved "https://registry.yarnpkg.com/@oclif/core/-/core-3.21.0.tgz#a235704e66589c8c104ccd616d0a8f1f36cf693e"
1317
+ integrity sha512-xR7qGPOWtOnYmdYocSn6oEh2oTQLsPOXoj3HYGpb26V3WulwF8Cm33WPnMsSISv4ben3Rtc5i59u9O5NnuG42g==
1318
+ dependencies:
1319
+ "@types/cli-progress" "^3.11.5"
1320
+ ansi-escapes "^4.3.2"
1321
+ ansi-styles "^4.3.0"
1322
+ cardinal "^2.1.1"
1323
+ chalk "^4.1.2"
1324
+ clean-stack "^3.0.1"
1325
+ cli-progress "^3.12.0"
1326
+ color "^4.2.3"
1327
+ debug "^4.3.4"
1328
+ ejs "^3.1.9"
1329
+ get-package-type "^0.1.0"
1330
+ globby "^11.1.0"
1331
+ hyperlinker "^1.0.0"
1332
+ indent-string "^4.0.0"
1333
+ is-wsl "^2.2.0"
1334
+ js-yaml "^3.14.1"
1335
+ natural-orderby "^2.0.3"
1336
+ object-treeify "^1.1.33"
1337
+ password-prompt "^1.1.3"
1338
+ slice-ansi "^4.0.0"
1339
+ string-width "^4.2.3"
1340
+ strip-ansi "^6.0.1"
1341
+ supports-color "^8.1.1"
1342
+ supports-hyperlinks "^2.2.0"
1343
+ widest-line "^3.1.0"
1344
+ wordwrap "^1.0.0"
1345
+ wrap-ansi "^7.0.0"
1346
+
1314
1347
  "@oclif/core@^2.15.0":
1315
1348
  version "2.15.0"
1316
1349
  resolved "https://registry.yarnpkg.com/@oclif/core/-/core-2.15.0.tgz#f27797b30a77d13279fba88c1698fc34a0bd0d2a"
@@ -1345,7 +1378,7 @@
1345
1378
  wordwrap "^1.0.0"
1346
1379
  wrap-ansi "^7.0.0"
1347
1380
 
1348
- "@oclif/core@^3.18.1", "@oclif/core@^3.19.2", "@oclif/core@^3.19.3", "@oclif/core@^3.20.0":
1381
+ "@oclif/core@^3.18.1", "@oclif/core@^3.19.2", "@oclif/core@^3.19.3":
1349
1382
  version "3.20.0"
1350
1383
  resolved "https://registry.yarnpkg.com/@oclif/core/-/core-3.20.0.tgz#534458dc6e8c46d8f03906aaadaca079e16a6554"
1351
1384
  integrity sha512-8BajhglY8frYGAS1whAukeouFZUN9MgQoLfNXtScPVEAjPlaD2BbSIAYQH2yF2qb/iVvbj/1DwYS3gqicYOq1A==
@@ -1532,6 +1565,11 @@
1532
1565
  resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"
1533
1566
  integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
1534
1567
 
1568
+ "@sindresorhus/merge-streams@^2.1.0":
1569
+ version "2.2.1"
1570
+ resolved "https://registry.yarnpkg.com/@sindresorhus/merge-streams/-/merge-streams-2.2.1.tgz#82b5e1e135ef62ef8b522d6e7f43ad360a69f294"
1571
+ integrity sha512-255V7MMIKw6aQ43Wbqp9HZ+VHn6acddERTLiiLnlcPLU9PdTq9Aijl12oklAgUEblLWye+vHLzmqBx6f2TGcZw==
1572
+
1535
1573
  "@sinonjs/commons@^1.7.0":
1536
1574
  version "1.8.3"
1537
1575
  resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
@@ -4105,7 +4143,7 @@ fast-glob@^3.2.9:
4105
4143
  merge2 "^1.3.0"
4106
4144
  micromatch "^4.0.4"
4107
4145
 
4108
- fast-glob@^3.3.0:
4146
+ fast-glob@^3.3.0, fast-glob@^3.3.2:
4109
4147
  version "3.3.2"
4110
4148
  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
4111
4149
  integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==
@@ -4552,6 +4590,18 @@ globby@^13.1.2:
4552
4590
  merge2 "^1.4.1"
4553
4591
  slash "^4.0.0"
4554
4592
 
4593
+ globby@^14.0.1:
4594
+ version "14.0.1"
4595
+ resolved "https://registry.yarnpkg.com/globby/-/globby-14.0.1.tgz#a1b44841aa7f4c6d8af2bc39951109d77301959b"
4596
+ integrity sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==
4597
+ dependencies:
4598
+ "@sindresorhus/merge-streams" "^2.1.0"
4599
+ fast-glob "^3.3.2"
4600
+ ignore "^5.2.4"
4601
+ path-type "^5.0.0"
4602
+ slash "^5.1.0"
4603
+ unicorn-magic "^0.1.0"
4604
+
4555
4605
  gopd@^1.0.1:
4556
4606
  version "1.0.1"
4557
4607
  resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
@@ -6575,6 +6625,11 @@ path-type@^4.0.0:
6575
6625
  resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
6576
6626
  integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
6577
6627
 
6628
+ path-type@^5.0.0:
6629
+ version "5.0.0"
6630
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-5.0.0.tgz#14b01ed7aea7ddf9c7c3f46181d4d04f9c785bb8"
6631
+ integrity sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==
6632
+
6578
6633
  pathval@^1.1.1:
6579
6634
  version "1.1.1"
6580
6635
  resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d"
@@ -7179,6 +7234,11 @@ slash@^4.0.0:
7179
7234
  resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"
7180
7235
  integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
7181
7236
 
7237
+ slash@^5.1.0:
7238
+ version "5.1.0"
7239
+ resolved "https://registry.yarnpkg.com/slash/-/slash-5.1.0.tgz#be3adddcdf09ac38eebe8dcdc7b1a57a75b095ce"
7240
+ integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==
7241
+
7182
7242
  slice-ansi@^4.0.0:
7183
7243
  version "4.0.0"
7184
7244
  resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b"
@@ -7764,6 +7824,11 @@ undici-types@~5.26.4:
7764
7824
  resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
7765
7825
  integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
7766
7826
 
7827
+ unicorn-magic@^0.1.0:
7828
+ version "0.1.0"
7829
+ resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.1.0.tgz#1bb9a51c823aaf9d73a8bfcd3d1a23dde94b0ce4"
7830
+ integrity sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==
7831
+
7767
7832
  unique-filename@^1.1.1:
7768
7833
  version "1.1.1"
7769
7834
  resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230"
@@ -145,5 +145,5 @@
145
145
  ]
146
146
  }
147
147
  },
148
- "version": "5.0.10"
148
+ "version": "5.1.0"
149
149
  }
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@oclif/plugin-command-snapshot",
3
3
  "description": "generates and compares OCLIF plugins snapshot files",
4
- "version": "5.0.10",
4
+ "version": "5.1.0",
5
5
  "author": "Salesforce",
6
6
  "bugs": "https://github.com/oclif/plugin-command-snapshot/issues",
7
7
  "dependencies": {
8
- "@oclif/core": "^3.20.0",
8
+ "@oclif/core": "3.21.0",
9
9
  "@types/lodash.difference": "^4.5.9",
10
10
  "chalk": "^5.3.0",
11
+ "globby": "^14.0.1",
11
12
  "just-diff": "^5.2.0",
12
13
  "lodash.difference": "^4.5.0",
13
14
  "lodash.get": "^4.4.2",