bump-cli 2.9.5 → 2.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -88,7 +88,7 @@ $ bump --help
88
88
  The Bump.sh CLI is used to interact with your API documentation hosted on Bump.sh by using the API of developers.bump.sh
89
89
 
90
90
  VERSION
91
- bump-cli/2.9.3 linux-x64 node-v20.18.1
91
+ bump-cli/2.9.5 linux-x64 node-v20.18.1
92
92
 
93
93
  USAGE
94
94
  $ bump [COMMAND]
@@ -178,7 +178,7 @@ Please check `bump deploy --help` for more usage details.
178
178
  ### The `diff` command
179
179
 
180
180
  Using the `diff` command can help to spot differences between the local API
181
- document and the latest deployed version.
181
+ document and the latest deployed version.
182
182
 
183
183
  #### Public API diffs
184
184
 
@@ -196,7 +196,7 @@ Modified: GET /consommations
196
196
  By default the command will always exit with a successful return code. If you
197
197
  want to use this command in a CI environment and want the command to fail **in
198
198
  case of a breaking change**, you will need to add the `--fail-on-breaking` flag
199
- to your diff command.
199
+ to your diff command.
200
200
 
201
201
  By default if the environment variable `CI=1` is present (in most continuous
202
202
  integration environment), the flag will be enabled. In that case you can disable
@@ -230,6 +230,14 @@ bump diff path/to/your/file.yml path/to/your/next-file.yml --doc my-documentatio
230
230
 
231
231
  Please check `bump diff --help` for full usage details.
232
232
 
233
+ #### Diffs with overlayed source files
234
+
235
+ The `bump diff` command also supports [overlays](#the-overlay-command). This means you can pass the `--overlay my-overlay-file.yml` flag to the command and it will apply the overlay on both files **before** running the diff. E.g.:
236
+
237
+ ```shell
238
+ bump diff --overlay my-overlay.yml path/to/your/file.yml path/to/your/next-file.yml
239
+ ```
240
+
233
241
  ### The `preview` command
234
242
 
235
243
  When writing documentation, you might want to preview how it renders on Bump.sh.
@@ -14,6 +14,7 @@ export default class Diff extends BaseCommand<typeof Diff> {
14
14
  'fail-on-breaking': import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
15
  format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
16
  hub: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
17
+ overlay: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
18
  token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
19
  };
19
20
  displayCompareResult(result: DiffResponse, format: string, failOnBreaking: boolean): Promise<void>;
@@ -48,6 +48,7 @@ export default class Diff extends BaseCommand {
48
48
  'fail-on-breaking': flagsBuilder.failOnBreaking({ allowNo: true }),
49
49
  format: flagsBuilder.format(),
50
50
  hub: flagsBuilder.hub(),
51
+ overlay: flagsBuilder.overlay(),
51
52
  token: flagsBuilder.token({ required: false }),
52
53
  };
53
54
  async displayCompareResult(result, format, failOnBreaking) {
@@ -78,13 +79,14 @@ export default class Diff extends BaseCommand {
78
79
  */
79
80
  async run() {
80
81
  const { args, flags } = await this.parse(Diff);
81
- const [documentation, hub, branch, token, format, expires] = [
82
+ const [documentation, hub, branch, token, format, expires, overlays] = [
82
83
  flags.doc,
83
84
  flags.hub,
84
85
  flags.branch,
85
86
  flags.token,
86
87
  flags.format,
87
88
  flags.expires,
89
+ flags.overlay,
88
90
  ];
89
91
  if (format === 'text') {
90
92
  if (args.otherFile) {
@@ -98,7 +100,7 @@ export default class Diff extends BaseCommand {
98
100
  throw new CLIError('Please provide a second file argument or login with an existing token');
99
101
  }
100
102
  ux.action.status = '...diff on Bump.sh in progress';
101
- const diff = await new CoreDiff(this.config).run(args.file, args.otherFile, documentation, hub, branch, token, format, expires);
103
+ const diff = await new CoreDiff(this.config).run(args.file, args.otherFile, documentation, hub, branch, token, format, expires, overlays);
102
104
  ux.action.stop();
103
105
  if (diff) {
104
106
  await this.displayCompareResult(diff, format, flags['fail-on-breaking']);
@@ -29,12 +29,12 @@ ${chalk.dim('$ bump overlay DEFINITION_FILE OVERLAY_FILE > destination/file.json
29
29
  async run() {
30
30
  const { args, flags } = await this.parse(Overlay);
31
31
  const outputPath = flags.out;
32
+ const { file, overlay } = args;
32
33
  ux.action.start("* Let's apply the overlay to the main definition");
33
34
  ux.action.status = '...loading definition file';
34
- const api = await API.load(args.file);
35
+ const api = await API.load(file);
35
36
  ux.action.status = '...applying overlay';
36
- await api.applyOverlay(args.overlay);
37
- const [overlayedDefinition] = api.extractDefinition(outputPath);
37
+ const [overlayedDefinition] = await api.extractDefinition(outputPath, [overlay]);
38
38
  ux.action.stop();
39
39
  if (outputPath) {
40
40
  await mkdir(dirname(outputPath), { recursive: true });
@@ -37,7 +37,7 @@ export default class Preview extends BaseCommand {
37
37
  }
38
38
  async preview(file, open = false, currentPreview = undefined) {
39
39
  const api = await API.load(file);
40
- const [definition, references] = api.extractDefinition();
40
+ const [definition, references] = await api.extractDefinition();
41
41
  this.d(`${file} looks like an ${api.specName} spec version ${api.version}`);
42
42
  const request = {
43
43
  definition,
@@ -28,16 +28,7 @@ export class Deploy {
28
28
  }
29
29
  async run(api, dryRun, documentation, token, hub, autoCreate, documentationName, branch, overlay, temporary) {
30
30
  let version;
31
- if (overlay) {
32
- /* eslint-disable no-await-in-loop */
33
- // Alternatively we can apply all overlays in parallel
34
- // https://stackoverflow.com/questions/48957022/unexpected-await-inside-a-loop-no-await-in-loop
35
- for (const overlayFile of overlay) {
36
- await api.applyOverlay(overlayFile);
37
- }
38
- /* eslint-enable no-await-in-loop */
39
- }
40
- const [definition, references] = api.extractDefinition();
31
+ const [definition, references] = await api.extractDefinition(undefined, overlay);
41
32
  const request = {
42
33
  auto_create_documentation: autoCreate && !dryRun,
43
34
  branch_name: branch,
@@ -8,14 +8,14 @@ export declare class Diff {
8
8
  constructor(config?: Config);
9
9
  get bumpClient(): BumpApi;
10
10
  get pollingPeriod(): number;
11
- createDiff(file1: string, file2: string, expires: string | undefined): Promise<DiffResponse | undefined>;
12
- createVersion(file: string, documentation: string, token: string, hub: string | undefined, branch_name: string | undefined, previous_version_id?: string | undefined): Promise<VersionResponse | undefined>;
11
+ createDiff(file1: string, file2: string, expires: string | undefined, overlays?: string[] | undefined): Promise<DiffResponse | undefined>;
12
+ createVersion(file: string, documentation: string, token: string, hub: string | undefined, branch_name: string | undefined, previous_version_id?: string | undefined, overlays?: string[] | undefined): Promise<VersionResponse | undefined>;
13
13
  d(formatter: any, ...args: any[]): void;
14
14
  extractDiff(versionWithDiff: VersionResponse & WithDiff): DiffResponse;
15
15
  isVersion(result: DiffResponse | VersionResponse): result is VersionResponse;
16
16
  isVersionWithDiff(result: DiffResponse | (VersionResponse & WithDiff)): result is VersionResponse & WithDiff;
17
17
  pollingDelay(): Promise<void>;
18
- run(file1: string, file2: string | undefined, documentation: string | undefined, hub: string | undefined, branch: string | undefined, token: string | undefined, format: string, expires: string | undefined): Promise<DiffResponse | undefined>;
18
+ run(file1: string, file2: string | undefined, documentation: string | undefined, hub: string | undefined, branch: string | undefined, token: string | undefined, format: string, expires: string | undefined, overlays: string[] | undefined): Promise<DiffResponse | undefined>;
19
19
  waitResult(result: DiffResponse | VersionResponse, token: string | undefined, opts: {
20
20
  format: string;
21
21
  timeout: number;
package/dist/core/diff.js CHANGED
@@ -22,11 +22,11 @@ export class Diff {
22
22
  get pollingPeriod() {
23
23
  return process.env.BUMP_POLLING_PERIOD ? Number(process.env.BUMP_POLLING_PERIOD) : 1000;
24
24
  }
25
- async createDiff(file1, file2, expires) {
25
+ async createDiff(file1, file2, expires, overlays) {
26
26
  const api = await API.load(file1);
27
- const [previous_definition, previous_references] = api.extractDefinition();
27
+ const [previous_definition, previous_references] = await api.extractDefinition(undefined, overlays);
28
28
  const api2 = await API.load(file2);
29
- const [definition, references] = api2.extractDefinition();
29
+ const [definition, references] = await api2.extractDefinition(undefined, overlays);
30
30
  const request = {
31
31
  definition,
32
32
  expires_at: expires,
@@ -47,9 +47,9 @@ export class Diff {
47
47
  }
48
48
  }
49
49
  }
50
- async createVersion(file, documentation, token, hub, branch_name, previous_version_id = undefined) {
50
+ async createVersion(file, documentation, token, hub, branch_name, previous_version_id = undefined, overlays) {
51
51
  const api = await API.load(file);
52
- const [definition, references] = api.extractDefinition();
52
+ const [definition, references] = await api.extractDefinition(undefined, overlays);
53
53
  const request = {
54
54
  branch_name,
55
55
  definition,
@@ -98,12 +98,12 @@ export class Diff {
98
98
  async pollingDelay() {
99
99
  await this.delay(this.pollingPeriod);
100
100
  }
101
- async run(file1, file2, documentation, hub, branch, token, format, expires) {
101
+ async run(file1, file2, documentation, hub, branch, token, format, expires, overlays) {
102
102
  if (!this._config)
103
103
  this._config = await Config.load(resolve(import.meta.dirname, './../../'));
104
104
  let diffVersion;
105
105
  if (file2 && (!documentation || !token)) {
106
- diffVersion = await this.createDiff(file1, file2, expires);
106
+ diffVersion = await this.createDiff(file1, file2, expires, overlays);
107
107
  }
108
108
  else {
109
109
  if (!documentation || !token) {
@@ -19,7 +19,7 @@ declare class API {
19
19
  static isOpenAPIOverlay(definition: JSONSchema4Object | JSONSchema6Object): definition is OpenAPIOverlay;
20
20
  static load(path: string): Promise<API>;
21
21
  applyOverlay(overlayPath: string): Promise<void>;
22
- extractDefinition(outputPath?: string): [string, APIReference[]];
22
+ extractDefinition(outputPath?: string, overlays?: string[] | undefined): Promise<[string, APIReference[]]>;
23
23
  getSpec(definition: APIDefinition): SpecSchema;
24
24
  getSpecName(definition: APIDefinition): string;
25
25
  getVersion(definition: APIDefinition): string;
@@ -124,9 +124,24 @@ class API {
124
124
  if (!API.isOpenAPIOverlay(overlayDefinition)) {
125
125
  throw new Error(`${overlayPath} does not look like an OpenAPI overlay`);
126
126
  }
127
+ for (const reference of overlay.references) {
128
+ // Keep overlay reference data only if there's no existing refs with the same location
129
+ if (this.references.every((existing) => existing.location !== reference.location)) {
130
+ this.references.push(reference);
131
+ }
132
+ }
127
133
  this.overlayedDefinition = await new Overlay().run(currentDefinition, overlayDefinition);
128
134
  }
129
- extractDefinition(outputPath) {
135
+ async extractDefinition(outputPath, overlays) {
136
+ if (overlays) {
137
+ /* eslint-disable no-await-in-loop */
138
+ // Alternatively we can apply all overlays in parallel
139
+ // https://stackoverflow.com/questions/48957022/unexpected-await-inside-a-loop-no-await-in-loop
140
+ for (const overlayFile of overlays) {
141
+ await this.applyOverlay(overlayFile);
142
+ }
143
+ /* eslint-enable no-await-in-loop */
144
+ }
130
145
  const references = [];
131
146
  for (let i = 0; i < this.references.length; i++) {
132
147
  const reference = this.references[i];
@@ -220,7 +235,7 @@ class API {
220
235
  serializeDefinition(outputPath) {
221
236
  if (this.overlayedDefinition) {
222
237
  const { comments } = parseWithPointers(this.rawDefinition, { attachComments: true });
223
- const dumpOptions = { comments, lineWidth: Number.POSITIVE_INFINITY };
238
+ const dumpOptions = { comments, lineWidth: Number.POSITIVE_INFINITY, noRefs: true };
224
239
  return this.guessFormat(outputPath) === 'json'
225
240
  ? JSON.stringify(this.overlayedDefinition)
226
241
  : safeStringify(this.overlayedDefinition, dumpOptions);
@@ -192,6 +192,14 @@
192
192
  "multiple": false,
193
193
  "type": "option"
194
194
  },
195
+ "overlay": {
196
+ "char": "o",
197
+ "description": "Path or URL of overlay file(s) to apply before deploying",
198
+ "name": "overlay",
199
+ "hasDynamicHelp": false,
200
+ "multiple": true,
201
+ "type": "option"
202
+ },
195
203
  "token": {
196
204
  "char": "t",
197
205
  "description": "Documentation or Hub token. Can be provided via BUMP_TOKEN environment variable",
@@ -284,5 +292,5 @@
284
292
  "strict": true
285
293
  }
286
294
  },
287
- "version": "2.9.5"
295
+ "version": "2.9.6"
288
296
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bump-cli",
3
3
  "description": "The Bump CLI is used to interact with your API documentation hosted on Bump.sh by using the API of developers.bump.sh",
4
- "version": "2.9.5",
4
+ "version": "2.9.6",
5
5
  "author": "Paul Bonaud <paulr@bump.sh>",
6
6
  "bin": {
7
7
  "bump": "./bin/run.js"
@@ -29,7 +29,7 @@
29
29
  "np": "^10.1.0",
30
30
  "nyc": "^17.1.0",
31
31
  "oclif": "^4",
32
- "shx": "^0.3.3",
32
+ "shx": "^0.4.0",
33
33
  "sinon": "^19.0.2",
34
34
  "ts-node": "^10",
35
35
  "typescript": "^5"