bump-cli 2.8.2 → 2.9.0-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.
Files changed (72) hide show
  1. package/README.md +12 -12
  2. package/bin/dev.cmd +3 -0
  3. package/bin/dev.js +6 -0
  4. package/bin/run.js +5 -0
  5. package/{lib → dist}/api/error.d.ts +6 -9
  6. package/dist/api/error.js +97 -0
  7. package/{lib → dist}/api/index.d.ts +13 -13
  8. package/dist/api/index.js +46 -0
  9. package/dist/api/models.js +1 -0
  10. package/{lib → dist}/api/vars.js +10 -14
  11. package/dist/args.d.ts +4 -0
  12. package/{lib → dist}/args.js +11 -15
  13. package/dist/base-command.d.ts +7 -0
  14. package/dist/base-command.js +18 -0
  15. package/dist/commands/deploy.d.ts +24 -0
  16. package/dist/commands/deploy.js +158 -0
  17. package/dist/commands/diff.d.ts +21 -0
  18. package/dist/commands/diff.js +110 -0
  19. package/dist/commands/overlay.d.ts +13 -0
  20. package/dist/commands/overlay.js +53 -0
  21. package/dist/commands/preview.d.ts +15 -0
  22. package/dist/commands/preview.js +83 -0
  23. package/{lib/core/definition_directory.d.ts → dist/core/definition-directory.d.ts} +10 -8
  24. package/dist/core/definition-directory.js +149 -0
  25. package/{lib → dist}/core/deploy.d.ts +7 -10
  26. package/{lib → dist}/core/deploy.js +39 -47
  27. package/{lib → dist}/core/diff.d.ts +12 -15
  28. package/{lib → dist}/core/diff.js +88 -97
  29. package/{lib → dist}/core/overlay.d.ts +2 -2
  30. package/{lib → dist}/core/overlay.js +36 -41
  31. package/{lib → dist}/core/utils/file.d.ts +4 -4
  32. package/dist/core/utils/file.js +36 -0
  33. package/dist/core/utils/prompts.d.ts +1 -0
  34. package/dist/core/utils/prompts.js +13 -0
  35. package/{lib → dist}/definition.d.ts +31 -30
  36. package/dist/definition.js +240 -0
  37. package/dist/flags.d.ts +48 -0
  38. package/dist/flags.js +120 -0
  39. package/dist/index.d.ts +16 -0
  40. package/dist/index.js +15 -0
  41. package/oclif.manifest.json +281 -1
  42. package/package.json +62 -56
  43. package/bin/run +0 -5
  44. package/lib/api/error.js +0 -96
  45. package/lib/api/index.js +0 -64
  46. package/lib/api/models.js +0 -2
  47. package/lib/args.d.ts +0 -15
  48. package/lib/cli/index.d.ts +0 -31
  49. package/lib/cli/index.js +0 -14
  50. package/lib/cli/styled/success.d.ts +0 -1
  51. package/lib/cli/styled/success.js +0 -11
  52. package/lib/command.d.ts +0 -9
  53. package/lib/command.js +0 -31
  54. package/lib/commands/deploy.d.ts +0 -27
  55. package/lib/commands/deploy.js +0 -164
  56. package/lib/commands/diff.d.ts +0 -24
  57. package/lib/commands/diff.js +0 -119
  58. package/lib/commands/overlay.d.ts +0 -16
  59. package/lib/commands/overlay.js +0 -56
  60. package/lib/commands/preview.d.ts +0 -19
  61. package/lib/commands/preview.js +0 -83
  62. package/lib/core/definition_directory.js +0 -138
  63. package/lib/core/utils/file.js +0 -41
  64. package/lib/core/utils/prompts.d.ts +0 -1
  65. package/lib/core/utils/prompts.js +0 -21
  66. package/lib/definition.js +0 -218
  67. package/lib/flags.d.ts +0 -20
  68. package/lib/flags.js +0 -116
  69. package/lib/index.d.ts +0 -7
  70. package/lib/index.js +0 -14
  71. package/{lib → dist}/api/models.d.ts +20 -20
  72. package/{lib → dist}/api/vars.d.ts +3 -3
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Bump CLI
2
2
 
3
3
  <p align="center">
4
- <img width="20%" src="https://bump.sh/icon-default-large.png" />
4
+ <img width="20%" src="https://bump.sh/icon-default-maskable-large.png" />
5
5
  </p>
6
6
 
7
7
  <p align="center">
@@ -32,7 +32,7 @@ Under the hood, it uses the API of [developers.bump.sh](https://developers.bump.
32
32
 
33
33
  ## Installation
34
34
 
35
- The Bump.sh CLI is a node package currently distributed via NPM. This means you must have the Node v14+ interpreter installed on your computer or CI servers.
35
+ The Bump.sh CLI is a node package currently distributed via NPM. This means you must have the Node v20+ interpreter installed on your computer or CI servers.
36
36
 
37
37
  _If you are looking to use Bump.sh in a continuous integration environment you might be interested by [our Github Action](https://github.com/marketplace/actions/api-documentation-on-bump)._
38
38
 
@@ -257,7 +257,7 @@ Please check `bump preview --help` for more usage details
257
257
 
258
258
  > This feature implements the [OpenAPI Overlay specification](https://github.com/OAI/Overlay-Specification). It is possible to apply an Overlay to any kind of document, be it an OpenAPI or AsyncAPI definition file.
259
259
 
260
- The Overlay specification of OpenAPI makes it possible to modify the content of an API definition file by adding a layer on top of it. That layer helps add, remove, or change some or all of the content of the original definition.
260
+ The Overlay specification of OpenAPI makes it possible to modify the content of an API definition file by adding a layer on top of it. That layer helps add, remove, or change some or all of the content of the original definition.
261
261
 
262
262
  Technically, the `bump overlay` command will output a modified version of the `[DEFINITION_FILE]` (an OpenAPI or AsyncAPI document) by applying the operations described in the `[OVERLAY_FILE]` Overlay file to the original API document.
263
263
 
@@ -270,34 +270,34 @@ bump overlay api-document.yaml overlay-file.yaml > api-overlayed-document.yaml
270
270
  _Note: you can also apply the overlay during the [`bump deploy` command]((#bump-deploy-file)) with the new `--overlay` flag:_
271
271
 
272
272
  ```shell
273
- bump deploy api-document.yaml --doc my-doc --token my-token --overlay overlay-file.yaml
273
+ bump deploy api-document.yaml --doc my-doc --token my-token --overlay overlay-file.yaml
274
274
  ```
275
275
 
276
276
  ## Development
277
277
 
278
- Make sure to have Node.js (At least v14) installed on your machine.
278
+ Make sure to have Node.js (At least v20) installed on your machine.
279
279
 
280
280
  - Install node dependencies with
281
-
281
+
282
282
  ```sh-session
283
283
  npm install
284
284
  ```
285
-
285
+
286
286
  - Compile the Typescript code
287
-
287
+
288
288
  ```sh-session
289
289
  npm run build
290
290
  npm run clean # to remove build artifacts
291
291
  ```
292
-
292
+
293
293
  - Format the codebase to comply with the linter rules
294
-
294
+
295
295
  ```sh-session
296
296
  npm run fmt
297
297
  ```
298
-
298
+
299
299
  - Run the test suites
300
-
300
+
301
301
  ```sh-session
302
302
  npm run test
303
303
  npm run test-coverage # Run tests with coverage
package/bin/dev.cmd ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node --loader ts-node/esm --no-warnings=ExperimentalWarning "%~dp0\dev" %*
package/bin/dev.js ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env -S node --loader ts-node/esm --disable-warning=ExperimentalWarning
2
+
3
+ // eslint-disable-next-line n/shebang
4
+ import {execute} from '@oclif/core'
5
+
6
+ await execute({development: true, dir: import.meta.url})
package/bin/run.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {execute} from '@oclif/core'
4
+
5
+ await execute({dir: import.meta.url})
@@ -1,16 +1,13 @@
1
- import { CLIError } from '@oclif/errors';
1
+ import { CLIError } from '@oclif/core/errors';
2
2
  import { AxiosError } from 'axios';
3
- import { InvalidDefinitionError } from './models';
4
- declare type MessagesAndExitCode = [string[], number];
3
+ import { InvalidDefinitionError } from './models.js';
4
+ type MessagesAndExitCode = [string[], number];
5
5
  export default class APIError extends CLIError {
6
- http: AxiosError;
7
- exitCode: number;
8
- status?: number;
9
- constructor(httpError: AxiosError, info?: string[], exit?: number);
6
+ constructor(httpError?: AxiosError | undefined, info?: string[], exit?: number);
7
+ static humanAttributeError(attribute: string, messages: unknown): string[];
8
+ static invalidDefinition(error: InvalidDefinitionError): MessagesAndExitCode;
10
9
  static is(error: Error): error is APIError;
11
10
  static notFound(error: Error): MessagesAndExitCode;
12
- static invalidDefinition(error: InvalidDefinitionError): MessagesAndExitCode;
13
- static humanAttributeError(attribute: string, messages: unknown): string[];
14
11
  static unauthenticated(): MessagesAndExitCode;
15
12
  }
16
13
  export {};
@@ -0,0 +1,97 @@
1
+ import { CLIError } from '@oclif/core/errors';
2
+ import chalk from 'chalk';
3
+ import d from 'debug';
4
+ const debug = d('bump-cli:api-client');
5
+ export default class APIError extends CLIError {
6
+ constructor(httpError, info = [], exit = 100) {
7
+ const status = httpError?.response?.status;
8
+ debug(httpError);
9
+ if (httpError) {
10
+ switch (status) {
11
+ case 422: {
12
+ ;
13
+ [info, exit] = APIError.invalidDefinition(httpError.response?.data);
14
+ break;
15
+ }
16
+ case 401: {
17
+ ;
18
+ [info, exit] = APIError.unauthenticated();
19
+ break;
20
+ }
21
+ case 404:
22
+ case 400: {
23
+ ;
24
+ [info, exit] = APIError.notFound(httpError.response?.data);
25
+ break;
26
+ }
27
+ }
28
+ if (info.length > 0) {
29
+ super(info.join('\n'), { exit });
30
+ }
31
+ else {
32
+ super(`Unhandled API error (status: ${status}) (error: ${httpError})`, { exit });
33
+ }
34
+ }
35
+ else {
36
+ super('Unhandled API error', { exit });
37
+ }
38
+ }
39
+ static humanAttributeError(attribute, messages) {
40
+ let info = [];
41
+ if (Array.isArray(messages)) {
42
+ const allMessages = messages
43
+ .map((message, idx) => {
44
+ if (message instanceof Object) {
45
+ return this.humanAttributeError(idx.toString(), message);
46
+ }
47
+ return message;
48
+ })
49
+ .join(', ');
50
+ info.push(`${chalk.underline(attribute)} ${allMessages}`);
51
+ }
52
+ else if (messages instanceof Object) {
53
+ for (const [child, childMessages] of Object.entries(messages)) {
54
+ const childErrors = this.humanAttributeError(`${attribute}.${child}`, childMessages);
55
+ info = [...info, ...childErrors];
56
+ }
57
+ }
58
+ else if (messages) {
59
+ info.push(`${chalk.underline(attribute)} ${messages}`);
60
+ }
61
+ return info;
62
+ }
63
+ static invalidDefinition(error) {
64
+ let info = [];
65
+ const genericMessage = error.message || 'Invalid definition file';
66
+ const exit = 122;
67
+ if (error && 'errors' in error) {
68
+ for (const [attr, message] of Object.entries(error.errors)) {
69
+ const humanErrors = APIError.humanAttributeError(attr, message);
70
+ info = [...info, ...humanErrors];
71
+ }
72
+ }
73
+ else {
74
+ info.push(genericMessage);
75
+ }
76
+ return [info, exit];
77
+ }
78
+ static is(error) {
79
+ return error instanceof CLIError && 'http' in error;
80
+ }
81
+ static notFound(error) {
82
+ const genericMessage = error.message || "It seems the documentation provided doesn't exist.";
83
+ return [
84
+ [
85
+ genericMessage,
86
+ `In a hub context you might want to try the ${chalk.dim('--auto-create')} flag.\nOtherwise, please check the given ${chalk.dim('--doc')}, ${chalk.dim('--token')} or ${chalk.dim('--hub')} flags`,
87
+ ],
88
+ 104,
89
+ ];
90
+ }
91
+ static unauthenticated() {
92
+ return [
93
+ ['You are not allowed to deploy to this documentation.', 'please check your --token flag or BUMP_TOKEN variable'],
94
+ 101,
95
+ ];
96
+ }
97
+ }
@@ -1,22 +1,22 @@
1
- import * as Config from '@oclif/config';
1
+ import { Config } from '@oclif/core';
2
2
  import { AxiosInstance, AxiosResponse } from 'axios';
3
- import { PingResponse, PreviewRequest, PreviewResponse, VersionRequest, VersionResponse, DiffRequest, DiffResponse, WithDiff } from './models';
4
- import APIError from './error';
3
+ import { DiffRequest, DiffResponse, PingResponse, PreviewRequest, PreviewResponse, VersionRequest, VersionResponse, WithDiff } from './models.js';
5
4
  declare class BumpApi {
6
- protected config: Config.IConfig;
5
+ protected config: Config;
7
6
  protected readonly client: AxiosInstance;
8
- constructor(config: Config.IConfig);
7
+ getDiff: (diffId: string, format: string) => Promise<AxiosResponse<DiffResponse>>;
9
8
  getPing: () => Promise<AxiosResponse<PingResponse>>;
10
9
  getVersion: (versionId: string, token: string) => Promise<AxiosResponse<VersionResponse & WithDiff>>;
11
- postPreview: (body?: PreviewRequest | undefined) => Promise<AxiosResponse<PreviewResponse>>;
12
- putPreview: (versionId: string, body?: PreviewRequest | undefined) => Promise<AxiosResponse<PreviewResponse>>;
13
- postVersion: (body: VersionRequest, token: string) => Promise<AxiosResponse<VersionResponse>>;
14
10
  postDiff: (body: DiffRequest) => Promise<AxiosResponse<DiffResponse>>;
15
- getDiff: (diffId: string, format: string) => Promise<AxiosResponse<DiffResponse>>;
11
+ postPreview: (body?: PreviewRequest) => Promise<AxiosResponse<PreviewResponse>>;
16
12
  postValidation: (body: VersionRequest, token: string) => Promise<AxiosResponse<void>>;
17
- private initializeResponseInterceptor;
18
- private handleError;
13
+ postVersion: (body: VersionRequest, token: string) => Promise<AxiosResponse<VersionResponse>>;
14
+ putPreview: (versionId: string, body?: PreviewRequest) => Promise<AxiosResponse<PreviewResponse>>;
19
15
  private authorizationHeader;
16
+ private handleError;
17
+ private initializeResponseInterceptor;
18
+ constructor(config: Config);
20
19
  }
21
- export * from './models';
22
- export { BumpApi, APIError };
20
+ export { default as APIError } from './error.js';
21
+ export { BumpApi };
22
+ export * from './models.js';
@@ -0,0 +1,46 @@
1
+ import axios from 'axios';
2
+ import APIError from './error.js';
3
+ import { vars } from './vars.js';
4
+ class BumpApi {
5
+ config;
6
+ client;
7
+ getDiff = (diffId, format) => this.client.get(`/diffs/${diffId}`, {
8
+ params: { formats: [format] },
9
+ });
10
+ getPing = () => this.client.get('/ping');
11
+ getVersion = (versionId, token) => this.client.get(`/versions/${versionId}`, {
12
+ headers: this.authorizationHeader(token),
13
+ });
14
+ postDiff = (body) => this.client.post('/diffs', body);
15
+ postPreview = (body) => this.client.post('/previews', body);
16
+ postValidation = (body, token) => this.client.post('/validations', body, {
17
+ headers: this.authorizationHeader(token),
18
+ });
19
+ postVersion = (body, token) => this.client.post('/versions', body, {
20
+ headers: this.authorizationHeader(token),
21
+ });
22
+ putPreview = (versionId, body) => this.client.put(`/previews/${versionId}`, body);
23
+ authorizationHeader = (token) => ({
24
+ Authorization: `Basic ${Buffer.from(token).toString('base64')}`,
25
+ });
26
+ handleError = (error) => Promise.reject(new APIError(error));
27
+ initializeResponseInterceptor = () => {
28
+ this.client.interceptors.response.use((data) => data, this.handleError);
29
+ };
30
+ // Check https://oclif.io/docs/config for details about Config.IConfig
31
+ constructor(config) {
32
+ this.config = config;
33
+ const baseURL = `${vars.apiUrl}${vars.apiBasePath}`;
34
+ const headers = {
35
+ 'User-Agent': vars.apiUserAgent(config.userAgent),
36
+ };
37
+ this.client = axios.create({
38
+ baseURL,
39
+ headers,
40
+ });
41
+ this.initializeResponseInterceptor();
42
+ }
43
+ }
44
+ export { default as APIError } from './error.js';
45
+ export { BumpApi };
46
+ export * from './models.js';
@@ -0,0 +1 @@
1
+ export {};
@@ -1,23 +1,19 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.vars = exports.Vars = void 0;
4
- class Vars {
5
- get host() {
6
- return this.envHost || 'bump.sh';
1
+ export class Vars {
2
+ get apiBasePath() {
3
+ return '/api/v1';
4
+ }
5
+ get apiUrl() {
6
+ return this.host.startsWith('http') ? this.host : `https://${this.host}`;
7
7
  }
8
8
  get envHost() {
9
9
  return process.env.BUMP_HOST;
10
10
  }
11
+ get host() {
12
+ return this.envHost || 'bump.sh';
13
+ }
11
14
  apiUserAgent(base) {
12
15
  const content = [base, process.env.BUMP_USER_AGENT].filter(Boolean);
13
16
  return content.join(' ');
14
17
  }
15
- get apiUrl() {
16
- return this.host.startsWith('http') ? this.host : `https://${this.host}`;
17
- }
18
- get apiBasePath() {
19
- return '/api/v1';
20
- }
21
18
  }
22
- exports.Vars = Vars;
23
- exports.vars = new Vars();
19
+ export const vars = new Vars();
package/dist/args.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ declare const fileArg: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
2
+ declare const otherFileArg: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
3
+ declare const overlayFileArg: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
4
+ export { fileArg, otherFileArg, overlayFileArg };
@@ -1,20 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.overlayFileArg = exports.otherFileArg = exports.fileArg = void 0;
4
- const fileArg = {
1
+ import { Args } from '@oclif/core';
2
+ const fileArg = Args.string({
3
+ description: 'Path or URL to your API documentation file. OpenAPI (2.0 to 3.1.0) and AsyncAPI (2.x) specifications are currently supported.\nPath can also be a directory when deploying to a Hub.',
5
4
  name: 'FILE',
6
5
  required: true,
7
- description: 'Path or URL to your API documentation file. OpenAPI (2.0 to 3.1.0) and AsyncAPI (2.x) specifications are currently supported.\nPath can also be a directory when deploying to a Hub.',
8
- };
9
- exports.fileArg = fileArg;
10
- const otherFileArg = {
11
- name: 'FILE2',
6
+ });
7
+ const otherFileArg = Args.string({
12
8
  description: 'Path or URL to a second API documentation file to compute its diff',
13
- };
14
- exports.otherFileArg = otherFileArg;
15
- const overlayFileArg = {
9
+ name: 'FILE2',
10
+ });
11
+ const overlayFileArg = Args.string({
12
+ description: 'Path or URL to an overlay file',
16
13
  name: 'OVERLAY_FILE',
17
14
  required: true,
18
- description: 'Path or URL to an overlay file',
19
- };
20
- exports.overlayFileArg = overlayFileArg;
15
+ });
16
+ export { fileArg, otherFileArg, overlayFileArg };
@@ -0,0 +1,7 @@
1
+ import { Command } from '@oclif/core';
2
+ import { BumpApi } from './api/index.js';
3
+ export declare abstract class BaseCommand<T extends typeof Command> extends Command {
4
+ protected _bump: BumpApi;
5
+ protected get bump(): BumpApi;
6
+ protected d(formatter: any, ...args: any[]): void;
7
+ }
@@ -0,0 +1,18 @@
1
+ import { Command } from '@oclif/core';
2
+ import debug from 'debug';
3
+ import { BumpApi } from './api/index.js';
4
+ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
5
+ export class BaseCommand extends Command {
6
+ _bump;
7
+ get bump() {
8
+ if (!this._bump)
9
+ this._bump = new BumpApi(this.config);
10
+ return this._bump;
11
+ }
12
+ // Function signature type taken from @types/debug
13
+ // Debugger(formatter: any, ...args: any[]): void;
14
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
15
+ d(formatter, ...args) {
16
+ return debug(`bump-cli:command:${this.constructor.name.toLowerCase()}`)(formatter, ...args);
17
+ }
18
+ }
@@ -0,0 +1,24 @@
1
+ import { BaseCommand } from '../base-command.js';
2
+ import { API } from '../definition.js';
3
+ export default class Deploy extends BaseCommand<typeof Deploy> {
4
+ static args: {
5
+ file: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static description: string;
8
+ static examples: string[];
9
+ static flags: {
10
+ 'auto-create': import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ branch: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
+ doc: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
+ 'doc-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ 'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ 'filename-pattern': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
+ hub: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
17
+ interactive: import("@oclif/core/interfaces").BooleanFlag<boolean>;
18
+ overlay: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
+ token: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
20
+ };
21
+ protected deployDirectory(dir: string, dryRun: boolean, token: string, hub: string, autoCreate: boolean, interactive: boolean, filenamePattern: string, documentationName: string | undefined, branch: string | undefined): Promise<void>;
22
+ protected deploySingleFile(api: API, dryRun: boolean, documentation: string, token: string, hub: string | undefined, autoCreate: boolean, documentationName: string | undefined, branch: string | undefined, overlay?: string | undefined): Promise<void>;
23
+ run(): Promise<void>;
24
+ }
@@ -0,0 +1,158 @@
1
+ import { ux } from '@oclif/core';
2
+ import { CLIError } from '@oclif/core/errors';
3
+ import chalk from 'chalk';
4
+ import { fileArg } from '../args.js';
5
+ import { BaseCommand } from '../base-command.js';
6
+ import { DefinitionDirectory } from '../core/definition-directory.js';
7
+ import { Deploy as CoreDeploy } from '../core/deploy.js';
8
+ import { isDir } from '../core/utils/file.js';
9
+ import { confirm as promptConfirm } from '../core/utils/prompts.js';
10
+ import { API } from '../definition.js';
11
+ import * as flagsBuilder from '../flags.js';
12
+ export default class Deploy extends BaseCommand {
13
+ static args = { file: fileArg };
14
+ static description = 'Create a new version of your documentation from the given file or URL.';
15
+ static examples = [
16
+ `Deploy a new version of ${chalk.underline('an existing documentation')}
17
+
18
+ ${chalk.dim('$ bump deploy FILE --doc <your_doc_id_or_slug> --token <your_doc_token>')}
19
+ * Let's deploy a new documentation version on Bump... done
20
+ * Your new documentation version will soon be ready
21
+ `,
22
+ `Deploy a new version of ${chalk.underline('an existing documentation attached to a hub')}
23
+
24
+ ${chalk.dim('$ bump deploy FILE --doc <doc_slug> --hub <your_hub_id_or_slug> --token <your_doc_token>')}
25
+ * Let's deploy a new documentation version on Bump... done
26
+ * Your new documentation version will soon be ready
27
+ `,
28
+ `Deploy a whole directory of ${chalk.underline('API definitions files to a hub')}
29
+
30
+ ${chalk.dim('$ bump deploy DIR --filename-pattern *-{slug}-api --hub <hub_slug> --token <hub_token>')}
31
+ We've found 2 valid API definitions to deploy
32
+ └─ DIR
33
+ └─ source-my-service-api.yml (OpenAPI spec version 3.1.0)
34
+ └─ source-my-jobs-service-api.yml (AsyncAPI spec version 2.6.0)
35
+
36
+ Let's deploy those documentations to your <hub_slug> hub on Bump.sh
37
+
38
+ * Your new documentation version will soon be ready
39
+ Let's deploy a new version to your my-service documentation on Bump.sh... done
40
+
41
+ * Your new documentation version will soon be ready
42
+ Let's deploy a new version to your my-jobs-service documentation on Bump.sh... done
43
+ `,
44
+ `${chalk.underline('Validate a new documentation version')} before deploying it
45
+
46
+ ${chalk.dim('$ bump deploy FILE --dry-run --doc <doc_slug> --token <your_doc_token>')}
47
+ * Let's validate a new documentation version on Bump... done
48
+ * Definition is valid
49
+ `,
50
+ ];
51
+ static flags = {
52
+ 'auto-create': flagsBuilder.autoCreate(),
53
+ branch: flagsBuilder.branch(),
54
+ doc: flagsBuilder.doc(),
55
+ 'doc-name': flagsBuilder.docName(),
56
+ 'dry-run': flagsBuilder.dryRun(),
57
+ 'filename-pattern': flagsBuilder.filenamePattern(),
58
+ hub: flagsBuilder.hub(),
59
+ interactive: flagsBuilder.interactive(),
60
+ overlay: flagsBuilder.overlay(),
61
+ token: flagsBuilder.token(),
62
+ };
63
+ async deployDirectory(dir, dryRun, token, hub, autoCreate, interactive, filenamePattern, documentationName, branch) {
64
+ const definitionDirectory = new DefinitionDirectory(dir, filenamePattern);
65
+ await definitionDirectory.readDefinitions();
66
+ await ux.action.pauseAsync(async () => {
67
+ definitionDirectory.stdoutDefinitions();
68
+ // In “interactive” mode we ask the user if he wants to add more
69
+ // definitions to deploy. He is thus presented a form to select
70
+ // some files from the target directory.
71
+ if (interactive) {
72
+ let confirm = true;
73
+ if (definitionDirectory.definitionsExists()) {
74
+ confirm = await promptConfirm('Do you want to add more files to deploy?');
75
+ }
76
+ if (confirm) {
77
+ await ux.action.pauseAsync(async () => {
78
+ await definitionDirectory.interactiveSelection();
79
+ });
80
+ }
81
+ }
82
+ });
83
+ if (definitionDirectory.definitionsExists()) {
84
+ await ux.action.pauseAsync(async () => {
85
+ definitionDirectory.stdoutDefinitions();
86
+ if (interactive) {
87
+ await definitionDirectory.sequentialMap(async (definition) => {
88
+ await definitionDirectory.renameToConvention(definition);
89
+ });
90
+ }
91
+ });
92
+ ux.action.status = `...to your ${hub} hub on Bump.sh`;
93
+ await definitionDirectory.sequentialMap(async (definition) => {
94
+ await this.deploySingleFile(definition.definition, dryRun, definition.slug, token, hub, autoCreate, definition.slug || documentationName, branch);
95
+ });
96
+ }
97
+ else {
98
+ throw new CLIError(`No documentation found in ${dir} with the pattern '${filenamePattern}'.\nYou should check with the ${chalk.dim('--filename-pattern')} flag to select your files from your naming convention.\nIf you don't have a naming convention we can help naming your API definition files:\nTry the ${chalk.dim('--interactive')} flag for that.`);
99
+ }
100
+ }
101
+ async deploySingleFile(api, dryRun, documentation, token, hub, autoCreate, documentationName, branch, overlay) {
102
+ ux.action.status = `...a new version to your ${documentation} documentation`;
103
+ const response = await new CoreDeploy(this.bump).run(api, dryRun, documentation, token, hub, autoCreate, documentationName, branch, overlay);
104
+ if (dryRun) {
105
+ ux.stdout(ux.colorize('green', 'Definition is valid'));
106
+ }
107
+ else if (response) {
108
+ process.stdout.write(ux.colorize('green', `Your ${documentation} documentation...`));
109
+ ux.stdout(ux.colorize('green', `has received a new deployment which will soon be ready at:`));
110
+ ux.stdout(ux.colorize('underline', response.doc_public_url));
111
+ }
112
+ else {
113
+ ux.warn(`Your ${documentation} documentation has not changed`);
114
+ }
115
+ }
116
+ /*
117
+ Oclif doesn't type parsed args & flags correctly and especially
118
+ required-ness which is not known by the compiler, thus the use of
119
+ the non-null assertion '!' in this command.
120
+ See https://github.com/oclif/oclif/issues/301 for details
121
+ */
122
+ async run() {
123
+ const { args, flags } = await this.parse(Deploy);
124
+ const [dryRun, documentation, token, hub, autoCreate, interactive, filenamePattern, documentationName, branch, overlay,] = [
125
+ flags['dry-run'],
126
+ flags.doc,
127
+ flags.token,
128
+ flags.hub,
129
+ flags['auto-create'],
130
+ flags.interactive,
131
+ /* Flags.filenamePattern has a default value, so it's always defined. But
132
+ * oclif types doesn't detect it */
133
+ flags['filename-pattern'],
134
+ flags['doc-name'],
135
+ flags.branch,
136
+ flags.overlay,
137
+ ];
138
+ const action = dryRun ? 'validate' : 'deploy';
139
+ ux.action.start(`Let's ${action} on Bump.sh`);
140
+ if (isDir(args.file)) {
141
+ if (hub) {
142
+ await this.deployDirectory(args.file, dryRun, token, hub, autoCreate, interactive, filenamePattern, documentationName, branch);
143
+ }
144
+ else {
145
+ throw new CLIError('Missing required flag --hub when deploying an entire directory');
146
+ }
147
+ }
148
+ else if (documentation) {
149
+ const api = await API.load(args.file);
150
+ this.d(`${args.file} looks like an ${api.specName} spec version ${api.version}`);
151
+ await this.deploySingleFile(api, dryRun, documentation, token, hub, autoCreate, documentationName, branch, overlay);
152
+ }
153
+ else {
154
+ throw new CLIError('Missing required flag --doc=<slug>');
155
+ }
156
+ ux.action.stop();
157
+ }
158
+ }
@@ -0,0 +1,21 @@
1
+ import { DiffResponse } from '../api/models.js';
2
+ import { BaseCommand } from '../base-command.js';
3
+ export default class Diff extends BaseCommand<typeof Diff> {
4
+ static args: {
5
+ file: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ otherFile: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
+ };
8
+ static description: string;
9
+ static examples: string[];
10
+ static flags: {
11
+ branch: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
+ doc: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
+ expires: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ 'fail-on-breaking': import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
+ hub: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
17
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
+ };
19
+ displayCompareResult(result: DiffResponse, format: string, failOnBreaking: boolean): Promise<void>;
20
+ run(): Promise<void>;
21
+ }