bump-cli 2.9.10 → 2.9.12

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
@@ -37,9 +37,9 @@ The Bump.sh CLI is a node package currently distributed via NPM. This means you
37
37
 
38
38
  _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/bump-sh-api-documentation-changelog)._
39
39
 
40
+ > [!NOTE]
40
41
  > You can download a standalone package directly from the latest
41
42
  > Github release assets if you don’t use Node.
42
- {: .info}
43
43
 
44
44
  ### Global installation
45
45
 
@@ -124,8 +124,8 @@ When an API is updated, the documentation should be updated at the same time. Th
124
124
  bump deploy path/to/api-document.yml --doc my-documentation --token $DOC_TOKEN
125
125
  ```
126
126
 
127
- > You can find your own `my-documentation` slug and `$DOC_TOKEN` api key from your [documentation settings](https://bump.sh/docs).
128
- {: .info}
127
+ > [!TIP]
128
+ > You can find your own `my-documentation` slug and `$DOC_TOKEN` api key from your [documentation settings](https://bump.sh/dashboard).
129
129
 
130
130
  You can also deploy a given API document to a different branch of your documentation with the `--branch <branch-name>` parameter. Please note the branch will be created if it doesn’t exist. More details about the branching feature are available on [this dedicated help page](https://docs.bump.sh/help/branching). E.g. deploy the API document to the `staging` branch of the documentation:
131
131
 
@@ -141,8 +141,8 @@ If you already have a hub in your [Bump.sh](https://bump.sh) account, you can au
141
141
  bump deploy dir/path/to/apis/ --auto-create --hub my-hub --token $HUB_TOKEN
142
142
  ```
143
143
 
144
+ > [!TIP]
144
145
  > You can find your own `my-hub` slug and `$HUB_TOKEN` api key from your [hub settings](https://bump.sh/hubs).
145
- {: .info}
146
146
 
147
147
  Please note, by default, only files named `{slug}-api.[format]` are published. Where `{slug}` is a name for your API and `[format]` is either `yaml` or `json`. Adjust to your file naming convention using the `--filename-pattern <pattern>` option.
148
148
 
@@ -175,6 +175,20 @@ bump deploy path/to/api-document.yml --dry-run --doc my-documentation --token $D
175
175
 
176
176
  Please check `bump deploy --help` for more usage details.
177
177
 
178
+ #### Deploy a workflow document on your MCP server
179
+
180
+ Use the `bump deploy` command with the `--mcp-server` flag to push a workflow definition to your MCP server.
181
+
182
+ ```shell
183
+ bump deploy path/to/flower-document.yml --mcp-server my-mcp-server-id-or-slug --token $BUMP_TOKEN
184
+ ```
185
+
186
+ > [!NOTE]
187
+ > You can find your own `mcp-server-id-or-slug` and `$BUMP_TOKEN` api key from your [MCP server settings](https://bump.sh/dashboard) at 'https://bump.sh/{your-organization}/workflow/set/{mcp-server-id}/tokens'.
188
+
189
+ This feature is currently in closed beta.
190
+ Request an early access at hello@bump.sh
191
+
178
192
  ### The `diff` command
179
193
 
180
194
  Using the `diff` command can help to spot differences between the local API
@@ -271,14 +285,14 @@ bump preview --live --open api-document.yaml
271
285
  - Watch the live preview being updated each time you save your file.
272
286
  - The additional `--open` flag helps to automatically open the preview URL in your browser.
273
287
 
288
+ > [!NOTE]
274
289
  > You can create as many previews as you like without being authenticated. This is a **free and unlimited service**.
275
- {: .info}
276
290
 
277
291
  Please check `bump preview --help` for more usage details
278
292
 
279
293
  ### The `overlay` command
280
294
 
281
- The [Overlay Specification](https://spec.openapis.org/overlay/v1.0.0.html) from the OpenAPI Initiative makes it possible to modify the content of an API definition by adding a layer on top of it. That layer helps adding, removing or changing some or all of the content of the original definition.
295
+ The [Overlay Specification](https://spec.openapis.org/overlay/v1.0.0.html) from the OpenAPI Initiative makes it possible to modify the content of an API definition by adding a layer on top of it. That layer helps adding, removing or changing some or all of the content of the original definition.
282
296
 
283
297
  The `bump overlay` command takes an original API document, applies the changes from the overlay document, and outputs a modified version. No changes are made directly to the original document.
284
298
 
@@ -1,6 +1,6 @@
1
1
  import { Config } from '@oclif/core';
2
2
  import { AxiosInstance, AxiosResponse } from 'axios';
3
- import { DiffRequest, DiffResponse, PingResponse, PreviewRequest, PreviewResponse, VersionRequest, VersionResponse, WithDiff } from './models.js';
3
+ import { DiffRequest, DiffResponse, PingResponse, PreviewRequest, PreviewResponse, VersionRequest, VersionResponse, WithDiff, WorkflowVersionRequest, WorkflowVersionResponse } from './models.js';
4
4
  declare class BumpApi {
5
5
  protected config?: Config | undefined;
6
6
  protected readonly client: AxiosInstance;
@@ -8,6 +8,7 @@ declare class BumpApi {
8
8
  getPing: () => Promise<AxiosResponse<PingResponse>>;
9
9
  getVersion: (versionId: string, token: string) => Promise<AxiosResponse<VersionResponse & WithDiff>>;
10
10
  postDiff: (body: DiffRequest) => Promise<AxiosResponse<DiffResponse>>;
11
+ postMCPServerDeploy: (mcpServerIdOrSlug: string, body: WorkflowVersionRequest, token: string) => Promise<AxiosResponse<WorkflowVersionResponse>>;
11
12
  postPreview: (body?: PreviewRequest) => Promise<AxiosResponse<PreviewResponse>>;
12
13
  postValidation: (body: VersionRequest, token: string) => Promise<AxiosResponse<void>>;
13
14
  postVersion: (body: VersionRequest, token: string) => Promise<AxiosResponse<VersionResponse>>;
package/dist/api/index.js CHANGED
@@ -12,6 +12,9 @@ class BumpApi {
12
12
  headers: this.authorizationHeader(token),
13
13
  });
14
14
  postDiff = (body) => this.client.post('/diffs', body);
15
+ postMCPServerDeploy = (mcpServerIdOrSlug, body, token) => this.client.post(`/mcp_servers/${mcpServerIdOrSlug}/deploy`, body, {
16
+ headers: this.authorizationHeader(token),
17
+ });
15
18
  postPreview = (body) => this.client.post('/previews', body);
16
19
  postValidation = (body, token) => this.client.post('/validations', body, {
17
20
  headers: this.authorizationHeader(token),
@@ -21,7 +24,7 @@ class BumpApi {
21
24
  });
22
25
  putPreview = (versionId, body) => this.client.put(`/previews/${versionId}`, body);
23
26
  authorizationHeader = (token) => ({
24
- Authorization: `Basic ${Buffer.from(token).toString('base64')}`,
27
+ Authorization: `Token ${token}`,
25
28
  });
26
29
  handleError = (error) => Promise.reject(new APIError(error));
27
30
  initializeResponseInterceptor = () => {
@@ -67,3 +67,10 @@ export interface DiffItem {
67
67
  status: string;
68
68
  type: string;
69
69
  }
70
+ export interface WorkflowVersionRequest {
71
+ definition: string;
72
+ }
73
+ export interface WorkflowVersionResponse {
74
+ id: string;
75
+ mcp_server_id: string;
76
+ }
@@ -15,11 +15,13 @@ export default class Deploy extends BaseCommand<typeof Deploy> {
15
15
  'filename-pattern': 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
17
  interactive: import("@oclif/core/interfaces").BooleanFlag<boolean>;
18
+ 'mcp-server': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
19
  overlay: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
20
  preview: import("@oclif/core/interfaces").BooleanFlag<boolean>;
20
21
  token: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
21
22
  };
22
23
  protected deployDirectory(dir: string, dryRun: boolean, token: string, hub: string, autoCreate: boolean, interactive: boolean, filenamePattern: string, documentationName: string | undefined, branch: string | undefined, overlays?: string[] | undefined): Promise<void>;
23
24
  protected deploySingleFile(api: API, dryRun: boolean, documentation: string, token: string, hub: string | undefined, autoCreate: boolean, documentationName: string | undefined, branch: string | undefined, overlay?: string[] | undefined, temporary?: boolean | undefined): Promise<void>;
25
+ protected deploySingleWorkflowFile(workflowDefinition: API, mcpServer: string, token: string): Promise<void>;
24
26
  run(): Promise<void>;
25
27
  }
@@ -7,6 +7,7 @@ import { DefinitionDirectory } from '../core/definition-directory.js';
7
7
  import { Deploy as CoreDeploy } from '../core/deploy.js';
8
8
  import { isDir } from '../core/utils/file.js';
9
9
  import { confirm as promptConfirm } from '../core/utils/prompts.js';
10
+ import { WorkflowDeploy as CoreWorkflowDeploy } from '../core/workflow-deploy.js';
10
11
  import { API } from '../definition.js';
11
12
  import * as flagsBuilder from '../flags.js';
12
13
  export default class Deploy extends BaseCommand {
@@ -46,6 +47,12 @@ Let's deploy a new version to your my-jobs-service documentation on Bump.sh... d
46
47
  ${chalk.dim('$ bump deploy FILE --dry-run --doc <doc_slug> --token <your_doc_token>')}
47
48
  * Let's validate on Bump.sh... done
48
49
  * Definition is valid
50
+ `,
51
+ `Deploy a new workflow document of ${chalk.underline('an existing MCP server')}
52
+
53
+ ${chalk.dim('$ bump deploy FILE --mcp-server <your_mcp_server_id_or_slug> --token <your_organization_token>')}
54
+ * Let's deploy on Bump.sh... done
55
+ * Your <your_mcp_server_id_or_slug> MCP server... has received a new workflow definition which will soon be ready.
49
56
  `,
50
57
  ];
51
58
  static flags = {
@@ -57,6 +64,7 @@ ${chalk.dim('$ bump deploy FILE --dry-run --doc <doc_slug> --token <your_doc_tok
57
64
  'filename-pattern': flagsBuilder.filenamePattern(),
58
65
  hub: flagsBuilder.hub(),
59
66
  interactive: flagsBuilder.interactive(),
67
+ 'mcp-server': flagsBuilder.mcpServer(),
60
68
  overlay: flagsBuilder.overlay(),
61
69
  preview: flagsBuilder.preview(),
62
70
  token: flagsBuilder.token(),
@@ -114,6 +122,17 @@ ${chalk.dim('$ bump deploy FILE --dry-run --doc <doc_slug> --token <your_doc_tok
114
122
  ux.warn(`Your ${documentation} documentation has not changed`);
115
123
  }
116
124
  }
125
+ async deploySingleWorkflowFile(workflowDefinition, mcpServer, token) {
126
+ ux.action.status = `...a new workflow definition to your ${mcpServer} MCP server`;
127
+ const response = await new CoreWorkflowDeploy(this.bump).run(workflowDefinition, mcpServer, token);
128
+ if (response) {
129
+ process.stdout.write(ux.colorize('green', `Your ${mcpServer} MCP server...`));
130
+ ux.stdout(ux.colorize('green', `has received a new workflow definition which will soon be ready.`));
131
+ }
132
+ else {
133
+ ux.warn(`Your ${mcpServer} MCP server has not changed.`);
134
+ }
135
+ }
117
136
  /*
118
137
  Oclif doesn't type parsed args & flags correctly and especially
119
138
  required-ness which is not known by the compiler, thus the use of
@@ -122,7 +141,7 @@ ${chalk.dim('$ bump deploy FILE --dry-run --doc <doc_slug> --token <your_doc_tok
122
141
  */
123
142
  async run() {
124
143
  const { args, flags } = await this.parse(Deploy);
125
- const [dryRun, documentation, token, hub, autoCreate, interactive, filenamePattern, documentationName, branch, overlay, temporary,] = [
144
+ const [dryRun, documentation, token, hub, autoCreate, interactive, filenamePattern, documentationName, branch, overlay, temporary, mcpServer,] = [
126
145
  flags['dry-run'],
127
146
  flags.doc,
128
147
  flags.token,
@@ -137,6 +156,7 @@ ${chalk.dim('$ bump deploy FILE --dry-run --doc <doc_slug> --token <your_doc_tok
137
156
  flags.overlay,
138
157
  /* when --preview is provided, generate temporary version */
139
158
  flags.preview,
159
+ flags['mcp-server'],
140
160
  ];
141
161
  const action = dryRun ? 'validate' : temporary ? 'preview' : 'deploy';
142
162
  ux.action.start(`Let's ${action} on Bump.sh`);
@@ -153,8 +173,12 @@ ${chalk.dim('$ bump deploy FILE --dry-run --doc <doc_slug> --token <your_doc_tok
153
173
  this.d(`${args.file} looks like an ${api.specName} spec version ${api.version}`);
154
174
  await this.deploySingleFile(api, dryRun, documentation, token, hub, autoCreate, documentationName, branch, overlay, temporary);
155
175
  }
176
+ else if (mcpServer) {
177
+ const workflowDefinition = await API.load(args.file);
178
+ await this.deploySingleWorkflowFile(workflowDefinition, mcpServer, token);
179
+ }
156
180
  else {
157
- throw new CLIError('Missing required flag --doc=<slug>');
181
+ throw new CLIError('Missing required flag --doc=<slug> or --mcp-server=<slug>');
158
182
  }
159
183
  ux.action.stop();
160
184
  }
@@ -4,6 +4,7 @@ export declare class Overlay {
4
4
  run(spec: APIDefinition, overlay: OpenAPIOverlay): APIDefinition;
5
5
  private executeAction;
6
6
  private humanName;
7
+ private pathEntryToKey;
7
8
  private remove;
8
9
  private update;
9
10
  }
@@ -76,12 +76,7 @@ export class Overlay {
76
76
  explodedPath.shift();
77
77
  // Take last element from path (which is the thing to act
78
78
  // upon)
79
- let thingToActUpon = explodedPath.pop();
80
- // The last element (e.g. '"price"]' or '0]') contains a final ']'
81
- // so we need to remove it AND we need to parse the element to
82
- // transform the string in either a string or a number
83
- thingToActUpon =
84
- thingToActUpon === undefined ? '$' : (thingToActUpon = JSON.parse(thingToActUpon.slice(0, -1)));
79
+ const thingToActUpon = this.pathEntryToKey(explodedPath.pop());
85
80
  // Reconstruct the stringified path expression targeting the parent
86
81
  const parentPath = explodedPath.join('][');
87
82
  const parent = parentPath.length > 0 ? jsonpath.query(spec, `$[${parentPath}]`) : spec;
@@ -103,6 +98,16 @@ export class Overlay {
103
98
  humanName(action) {
104
99
  return action.description ? `Action '${action.description}'` : 'Action';
105
100
  }
101
+ // The last path entry (e.g. "'price']" or '0]') contains a final
102
+ // ']' so we need to remove it AND we need to replace single quotes
103
+ // to double quotes AND FINALLY parse the element to transform the
104
+ // string in either a string or a number.
105
+ pathEntryToKey(pathEntry) {
106
+ if (pathEntry === undefined) {
107
+ return '$';
108
+ }
109
+ return JSON.parse(pathEntry.slice(0, -1).replaceAll(/(^'|'$)/g, '"'));
110
+ }
106
111
  remove(parent, property_or_index) {
107
112
  if (Array.isArray(parent)) {
108
113
  parent.splice(property_or_index, 1);
@@ -0,0 +1,7 @@
1
+ import type { JSONSchema7 } from 'json-schema';
2
+ declare const _default: {
3
+ schemas: {
4
+ '0.1': JSONSchema7;
5
+ };
6
+ };
7
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import schemaV01 from './v0.1/schema.json' with { type: 'json' };
2
+ export default {
3
+ schemas: {
4
+ '0.1': schemaV01,
5
+ },
6
+ };
@@ -0,0 +1,126 @@
1
+ {
2
+ "title": "Flower 0.1 schema",
3
+ "$schema": "http://json-schema.org/draft-07/schema#",
4
+ "type": "object",
5
+ "required": [
6
+ "flower",
7
+ "id",
8
+ "flows"
9
+ ],
10
+ "additionalProperties": false,
11
+ "patternProperties": {
12
+ "^x-[\\w\\d\\.\\-\\_]+$": {
13
+ "$ref": "#/definitions/specificationExtension"
14
+ }
15
+ },
16
+ "properties": {
17
+ "flower": {
18
+ "type": [
19
+ "string"
20
+ ],
21
+ "enum": [
22
+ "0.1"
23
+ ],
24
+ "description": "The Flower specification version of this document."
25
+ },
26
+ "id": {
27
+ "type": "string",
28
+ "description": "A unique id representing the workflow set."
29
+ },
30
+ "title": {
31
+ "type": "string"
32
+ },
33
+ "description": {
34
+ "type": "string"
35
+ },
36
+ "flows": {
37
+ "type": "array",
38
+ "items": {
39
+ "$ref": "#/definitions/flow"
40
+ }
41
+ }
42
+ },
43
+ "definitions": {
44
+ "flow": {
45
+ "type": "object",
46
+ "properties": {
47
+ "id": {
48
+ "type": "string"
49
+ },
50
+ "description": {
51
+ "type": "string"
52
+ },
53
+ "inputs": {
54
+ "$ref": "#/definitions/schema"
55
+ },
56
+ "outputs": {
57
+ "$ref": "#/definitions/schema"
58
+ },
59
+ "steps": {
60
+ "type": "array",
61
+ "items": {
62
+ "$ref": "#/definitions/step"
63
+ }
64
+ }
65
+ },
66
+ "required": [
67
+ "id",
68
+ "steps"
69
+ ]
70
+ },
71
+ "step": {
72
+ "type": "object",
73
+ "properties": {
74
+ "id": {
75
+ "type": "string"
76
+ },
77
+ "outputs": {
78
+ "$ref": "#/definitions/schema"
79
+ },
80
+ "request": {
81
+ "type": "object",
82
+ "properties": {
83
+ "method": {
84
+ "type": "string"
85
+ },
86
+ "query": {
87
+ "$ref": "#/definitions/schema"
88
+ },
89
+ "url": {
90
+ "type": "string"
91
+ }
92
+ }
93
+ }
94
+ },
95
+ "required": [
96
+ "id",
97
+ "request"
98
+ ]
99
+ },
100
+ "schema": {
101
+ "allOf": [
102
+ {
103
+ "$ref": "http://json-schema.org/draft-07/schema#"
104
+ },
105
+ {
106
+ "type": "object",
107
+ "patternProperties": {
108
+ "^x-[\\w\\d\\.\\-\\_]+$": {
109
+ "$ref": "#/definitions/specificationExtension"
110
+ }
111
+ }
112
+ }
113
+ ]
114
+ },
115
+ "specificationExtension": {
116
+ "oneOf": [
117
+ {
118
+ "type": "object",
119
+ "description": "Any property starting with x- is valid.",
120
+ "additionalProperties": true
121
+ },
122
+ {}
123
+ ]
124
+ }
125
+ }
126
+ }
@@ -0,0 +1,10 @@
1
+ import { BumpApi } from '../api/index.js';
2
+ import { WorkflowVersionRequest, WorkflowVersionResponse } from '../api/models.js';
3
+ import { API } from '../definition.js';
4
+ export declare class WorkflowDeploy {
5
+ private _bump;
6
+ constructor(bumpClient: BumpApi);
7
+ protected createWorkflowVersion(mcpServer: string, request: WorkflowVersionRequest, token: string): Promise<WorkflowVersionResponse | undefined>;
8
+ d(formatter: any, ...args: any[]): void;
9
+ run(workflowDefinition: API, mcpServer: string, token: string): Promise<WorkflowVersionResponse | undefined>;
10
+ }
@@ -0,0 +1,38 @@
1
+ import debug from 'debug';
2
+ export class WorkflowDeploy {
3
+ _bump;
4
+ constructor(bumpClient) {
5
+ this._bump = bumpClient;
6
+ }
7
+ async createWorkflowVersion(mcpServer, request, token) {
8
+ const response = await this._bump.postMCPServerDeploy(mcpServer, request, token);
9
+ let version;
10
+ switch (response.status) {
11
+ case 204: {
12
+ break; // MCP server workflow document already exists
13
+ }
14
+ case 201: {
15
+ version = response.data;
16
+ break;
17
+ }
18
+ default: {
19
+ this.d(`API status response was ${response.status}. Expected 201 or 204.`);
20
+ throw new Error('Unexpected server response. Please contact support at https://bump.sh if this error persists');
21
+ }
22
+ }
23
+ return version;
24
+ }
25
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
26
+ d(formatter, ...args) {
27
+ return debug(`bump-cli:core:deploy`)(formatter, ...args);
28
+ }
29
+ async run(workflowDefinition, mcpServer, token) {
30
+ let version;
31
+ const request = {
32
+ definition: workflowDefinition.rawDefinition,
33
+ };
34
+ // eslint-disable-next-line prefer-const
35
+ version = await this.createWorkflowVersion(mcpServer, request, token);
36
+ return version;
37
+ }
38
+ }
@@ -2,6 +2,7 @@ import { JSONSchema4, JSONSchema4Array, JSONSchema4Object, JSONSchema6, JSONSche
2
2
  type SpecSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
3
3
  declare class SupportedFormat {
4
4
  static readonly asyncapi: Record<string, SpecSchema>;
5
+ static readonly flower: Record<string, SpecSchema>;
5
6
  static readonly openapi: Record<string, SpecSchema>;
6
7
  }
7
8
  declare class API {
@@ -10,19 +11,19 @@ declare class API {
10
11
  overlayedDefinition: APIDefinition | undefined;
11
12
  readonly rawDefinition: string;
12
13
  readonly references: APIReference[];
13
- readonly spec?: SpecSchema;
14
- readonly specName: string;
15
- readonly version: string;
14
+ readonly specName?: string;
15
+ readonly version?: string;
16
16
  constructor(location: string, values: SpecSchema);
17
17
  static isAsyncAPI(definition: JSONSchema4Object | JSONSchema6Object): definition is AsyncAPI;
18
+ static isFlower(definition: JSONSchema4Object | JSONSchema6Object): definition is Flower;
18
19
  static isOpenAPI(definition: JSONSchema4Object | JSONSchema6Object): definition is OpenAPI;
19
20
  static isOpenAPIOverlay(definition: JSONSchema4Object | JSONSchema6Object): definition is OpenAPIOverlay;
20
21
  static load(path: string): Promise<API>;
21
22
  applyOverlay(overlayPath: string): Promise<void>;
22
23
  extractDefinition(outputPath?: string, overlays?: string[] | undefined): Promise<[string, APIReference[]]>;
23
- getSpec(definition: APIDefinition): SpecSchema;
24
- getSpecName(definition: APIDefinition): string;
25
- getVersion(definition: APIDefinition): string;
24
+ getSpec(definition: APIDefinition): SpecSchema | undefined;
25
+ getSpecName(definition: APIDefinition): string | undefined;
26
+ getVersion(definition: APIDefinition): string | undefined;
26
27
  guessFormat(output?: string): string;
27
28
  isMainRefPath(path: string): boolean;
28
29
  resolveContent(values: SpecSchema): [string, APIDefinition];
@@ -35,7 +36,7 @@ type APIReference = {
35
36
  content: string;
36
37
  location: string;
37
38
  };
38
- type APIDefinition = AsyncAPI | OpenAPI | OpenAPIOverlay;
39
+ type APIDefinition = AsyncAPI | Flower | OpenAPI | OpenAPIOverlay;
39
40
  type InfoObject = {
40
41
  readonly description?: string;
41
42
  readonly title: string;
@@ -55,4 +56,7 @@ type AsyncAPI = {
55
56
  readonly asyncapi: string;
56
57
  readonly info: InfoObject;
57
58
  } & JSONSchema4Object;
58
- export { API, APIDefinition, OpenAPIOverlay, SupportedFormat };
59
+ type Flower = {
60
+ readonly flower: string;
61
+ } & JSONSchema4Object;
62
+ export { API, APIDefinition, OpenAPI, OpenAPIOverlay, SupportedFormat };
@@ -5,6 +5,7 @@ import { parseWithPointers, safeStringify } from '@stoplight/yaml';
5
5
  import debug from 'debug';
6
6
  import { default as nodePath } from 'node:path';
7
7
  import { Overlay } from './core/overlay.js';
8
+ import flowerSchemas from './core/schemas/flower-schemas/index.js';
8
9
  import openapiSchemas from './core/schemas/oas-schemas/index.js';
9
10
  class SupportedFormat {
10
11
  static asyncapi = {
@@ -16,6 +17,9 @@ class SupportedFormat {
16
17
  '2.5': asyncapi.schemas['2.5.0'],
17
18
  '2.6': asyncapi.schemas['2.6.0'],
18
19
  };
20
+ static flower = {
21
+ '0.1': flowerSchemas.schemas['0.1'],
22
+ };
19
23
  static openapi = {
20
24
  '2.0': openapiSchemas.schemas['2.0'],
21
25
  '3.0': openapiSchemas.schemas['3.0'],
@@ -40,7 +44,6 @@ class API {
40
44
  overlayedDefinition;
41
45
  rawDefinition;
42
46
  references;
43
- spec;
44
47
  specName;
45
48
  version;
46
49
  constructor(location, values) {
@@ -51,14 +54,16 @@ class API {
51
54
  this.definition = parsed;
52
55
  this.specName = this.getSpecName(parsed);
53
56
  this.version = this.getVersion(parsed);
54
- this.spec = this.getSpec(parsed);
55
- if (this.spec === undefined) {
57
+ if (!this.getSpec(parsed)) {
56
58
  throw new UnsupportedFormat(`${this.specName} ${this.version}`);
57
59
  }
58
60
  }
59
61
  static isAsyncAPI(definition) {
60
62
  return 'asyncapi' in definition;
61
63
  }
64
+ static isFlower(definition) {
65
+ return 'flower' in definition;
66
+ }
62
67
  static isOpenAPI(definition) {
63
68
  return typeof definition.openapi === 'string' || typeof definition.swagger === 'string';
64
69
  }
@@ -159,19 +164,43 @@ class API {
159
164
  if (API.isOpenAPIOverlay(definition)) {
160
165
  return { overlay: { type: 'string' } };
161
166
  }
162
- return SupportedFormat.openapi[this.versionWithoutPatch()];
167
+ if (API.isFlower(definition)) {
168
+ return SupportedFormat.flower[this.versionWithoutPatch()];
169
+ }
170
+ if (API.isOpenAPI(definition)) {
171
+ return SupportedFormat.openapi[this.versionWithoutPatch()];
172
+ }
173
+ return undefined;
163
174
  }
164
175
  getSpecName(definition) {
165
176
  if (API.isAsyncAPI(definition)) {
166
177
  return 'AsyncAPI';
167
178
  }
168
- return 'OpenAPI';
179
+ if (API.isFlower(definition)) {
180
+ return 'Flower';
181
+ }
182
+ if (API.isOpenAPIOverlay(definition)) {
183
+ return 'OpenAPIOverlay';
184
+ }
185
+ if (API.isOpenAPI(definition)) {
186
+ return 'OpenAPI';
187
+ }
188
+ return undefined;
169
189
  }
170
190
  getVersion(definition) {
171
191
  if (API.isAsyncAPI(definition)) {
172
192
  return definition.asyncapi;
173
193
  }
174
- return (definition.openapi || definition.swagger);
194
+ if (API.isFlower(definition)) {
195
+ return definition.flower;
196
+ }
197
+ if (API.isOpenAPIOverlay(definition)) {
198
+ return definition.overlay;
199
+ }
200
+ if (API.isOpenAPI(definition)) {
201
+ return (definition.openapi || definition.swagger);
202
+ }
203
+ return undefined;
175
204
  }
176
205
  guessFormat(output) {
177
206
  return (output || this.location).endsWith('.json') ? 'json' : 'yaml';
@@ -208,11 +237,11 @@ class API {
208
237
  }
209
238
  }
210
239
  const { parsed, raw } = mainReference;
211
- if (!parsed || !raw || !(parsed instanceof Object) || !('info' in parsed)) {
240
+ if (!parsed || !raw || !(parsed instanceof Object) || !('info' in parsed || 'flower' in parsed)) {
212
241
  debug('bump-cli:definition')(`Main location (${this.location}) not found or empty (within ${JSON.stringify(Object.keys(values))})`);
213
- throw new UnsupportedFormat("Definition needs to be an object with at least an 'info' key");
242
+ throw new UnsupportedFormat('Definition needs to be a valid Object');
214
243
  }
215
- if (!API.isOpenAPI(parsed) && !API.isAsyncAPI(parsed) && !API.isOpenAPIOverlay(parsed)) {
244
+ if (!API.isOpenAPI(parsed) && !API.isAsyncAPI(parsed) && !API.isOpenAPIOverlay(parsed) && !API.isFlower(parsed)) {
216
245
  throw new UnsupportedFormat();
217
246
  }
218
247
  return [raw, parsed];
@@ -243,6 +272,9 @@ class API {
243
272
  return this.rawDefinition;
244
273
  }
245
274
  versionWithoutPatch() {
275
+ if (!this.version) {
276
+ return '';
277
+ }
246
278
  const [major, minor] = this.version.split('.', 3);
247
279
  return `${major}.${minor}`;
248
280
  }
package/dist/flags.d.ts CHANGED
@@ -46,4 +46,8 @@ declare const overlay: Interfaces.FlagDefinition<string[], Interfaces.CustomOpti
46
46
  multiple: true;
47
47
  requiredOrDefaulted: false;
48
48
  }>;
49
- export { autoCreate, branch, doc, docName, dryRun, expires, failOnBreaking, filenamePattern, format, hub, interactive, live, open, out, overlay, preview, token, };
49
+ declare const mcpServer: Interfaces.FlagDefinition<string, Interfaces.CustomOptions, {
50
+ multiple: false;
51
+ requiredOrDefaulted: false;
52
+ }>;
53
+ export { autoCreate, branch, doc, docName, dryRun, expires, failOnBreaking, filenamePattern, format, hub, interactive, live, mcpServer, open, out, overlay, preview, token, };
package/dist/flags.js CHANGED
@@ -45,7 +45,7 @@ const token = Flags.custom({
45
45
  if (envToken)
46
46
  return envToken;
47
47
  },
48
- description: 'Documentation or Hub token. Can be provided via BUMP_TOKEN environment variable',
48
+ description: 'Documentation, Hub or Organization token. Can be provided via BUMP_TOKEN environment variable',
49
49
  required: true,
50
50
  });
51
51
  const autoCreate = (opts = {}) => {
@@ -123,4 +123,8 @@ const overlay = Flags.custom({
123
123
  description: 'Path or URL of overlay file(s) to apply before deploying',
124
124
  multiple: true,
125
125
  });
126
- export { autoCreate, branch, doc, docName, dryRun, expires, failOnBreaking, filenamePattern, format, hub, interactive, live, open, out, overlay, preview, token, };
126
+ const mcpServer = Flags.custom({
127
+ char: 'm',
128
+ description: 'MCP server id or slug',
129
+ });
130
+ export { autoCreate, branch, doc, docName, dryRun, expires, failOnBreaking, filenamePattern, format, hub, interactive, live, mcpServer, open, out, overlay, preview, token, };
@@ -11,10 +11,11 @@
11
11
  },
12
12
  "description": "Create a new version of your documentation from the given file or URL.",
13
13
  "examples": [
14
- "Deploy a new version of an existing documentation\n\n$ bump deploy FILE --doc <your_doc_id_or_slug> --token <your_doc_token>\n* Let's deploy on Bump.sh... done\n* Your new documentation version will soon be ready\n",
15
- "Deploy a new version of an existing documentation attached to a hub\n\n$ bump deploy FILE --doc <doc_slug> --hub <your_hub_id_or_slug> --token <your_doc_token>\n* Let's deploy on Bump.sh... done\n* Your new documentation version will soon be ready\n",
16
- "Deploy a whole directory of API definitions files to a hub\n\n$ bump deploy DIR --filename-pattern *-{slug}-api --hub <hub_slug> --token <hub_token>\nWe've found 2 valid API definitions to deploy\n└─ DIR\n └─ source-my-service-api.yml (OpenAPI spec version 3.1.0)\n └─ source-my-jobs-service-api.yml (AsyncAPI spec version 2.6.0)\n\nLet's deploy those documentations to your <hub_slug> hub on Bump.sh\n\n* Your new documentation version will soon be ready\nLet's deploy a new version to your my-service documentation on Bump.sh... done\n\n* Your new documentation version will soon be ready\nLet's deploy a new version to your my-jobs-service documentation on Bump.sh... done\n",
17
- "Validate a new documentation version before deploying it\n\n$ bump deploy FILE --dry-run --doc <doc_slug> --token <your_doc_token>\n* Let's validate on Bump.sh... done\n* Definition is valid\n"
14
+ "Deploy a new version of \u001b[4man existing documentation\u001b[24m\n\n\u001b[2m$ bump deploy FILE --doc <your_doc_id_or_slug> --token <your_doc_token>\u001b[22m\n* Let's deploy on Bump.sh... done\n* Your new documentation version will soon be ready\n",
15
+ "Deploy a new version of \u001b[4man existing documentation attached to a hub\u001b[24m\n\n\u001b[2m$ bump deploy FILE --doc <doc_slug> --hub <your_hub_id_or_slug> --token <your_doc_token>\u001b[22m\n* Let's deploy on Bump.sh... done\n* Your new documentation version will soon be ready\n",
16
+ "Deploy a whole directory of \u001b[4mAPI definitions files to a hub\u001b[24m\n\n\u001b[2m$ bump deploy DIR --filename-pattern *-{slug}-api --hub <hub_slug> --token <hub_token>\u001b[22m\nWe've found 2 valid API definitions to deploy\n└─ DIR\n └─ source-my-service-api.yml (OpenAPI spec version 3.1.0)\n └─ source-my-jobs-service-api.yml (AsyncAPI spec version 2.6.0)\n\nLet's deploy those documentations to your <hub_slug> hub on Bump.sh\n\n* Your new documentation version will soon be ready\nLet's deploy a new version to your my-service documentation on Bump.sh... done\n\n* Your new documentation version will soon be ready\nLet's deploy a new version to your my-jobs-service documentation on Bump.sh... done\n",
17
+ "\u001b[4mValidate a new documentation version\u001b[24m before deploying it\n\n\u001b[2m$ bump deploy FILE --dry-run --doc <doc_slug> --token <your_doc_token>\u001b[22m\n* Let's validate on Bump.sh... done\n* Definition is valid\n",
18
+ "Deploy a new workflow document of \u001b[4man existing MCP server\u001b[24m\n\n\u001b[2m$ bump deploy FILE --mcp-server <your_mcp_server_id_or_slug> --token <your_organization_token>\u001b[22m\n* Let's deploy on Bump.sh... done\n* Your <your_mcp_server_id_or_slug> MCP server... has received a new workflow definition which will soon be ready.\n"
18
19
  ],
19
20
  "flags": {
20
21
  "auto-create": {
@@ -84,6 +85,14 @@
84
85
  "allowNo": false,
85
86
  "type": "boolean"
86
87
  },
88
+ "mcp-server": {
89
+ "char": "m",
90
+ "description": "MCP server id or slug",
91
+ "name": "mcp-server",
92
+ "hasDynamicHelp": false,
93
+ "multiple": false,
94
+ "type": "option"
95
+ },
87
96
  "overlay": {
88
97
  "char": "o",
89
98
  "description": "Path or URL of overlay file(s) to apply before deploying",
@@ -101,10 +110,9 @@
101
110
  },
102
111
  "token": {
103
112
  "char": "t",
104
- "description": "Documentation or Hub token. Can be provided via BUMP_TOKEN environment variable",
113
+ "description": "Documentation, Hub or Organization token. Can be provided via BUMP_TOKEN environment variable",
105
114
  "name": "token",
106
115
  "required": true,
107
- "default": "99f52837852249b328c0a00249f846a3",
108
116
  "hasDynamicHelp": false,
109
117
  "multiple": false,
110
118
  "type": "option"
@@ -203,10 +211,9 @@
203
211
  },
204
212
  "token": {
205
213
  "char": "t",
206
- "description": "Documentation or Hub token. Can be provided via BUMP_TOKEN environment variable",
214
+ "description": "Documentation, Hub or Organization token. Can be provided via BUMP_TOKEN environment variable",
207
215
  "name": "token",
208
216
  "required": false,
209
- "default": "99f52837852249b328c0a00249f846a3",
210
217
  "hasDynamicHelp": false,
211
218
  "multiple": false,
212
219
  "type": "option"
@@ -236,7 +243,7 @@
236
243
  },
237
244
  "description": "Apply an OpenAPI specified overlay to your API definition.",
238
245
  "examples": [
239
- "Apply the OVERLAY_FILE to the existing DEFINITION_FILE. The resulting\ndefinition is output on stdout meaning you can redirect it to a new\nfile.\n\n$ bump overlay DEFINITION_FILE OVERLAY_FILE > destination/file.json\n* Let's apply the overlay to the main definition... done\n"
246
+ "Apply the OVERLAY_FILE to the existing DEFINITION_FILE. The resulting\ndefinition is output on stdout meaning you can redirect it to a new\nfile.\n\n\u001b[2m$ bump overlay DEFINITION_FILE OVERLAY_FILE > destination/file.json\u001b[22m\n* Let's apply the overlay to the main definition... done\n"
240
247
  ],
241
248
  "flags": {
242
249
  "out": {
@@ -294,5 +301,5 @@
294
301
  "strict": true
295
302
  }
296
303
  },
297
- "version": "2.9.10"
304
+ "version": "2.9.12"
298
305
  }
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.10",
4
+ "version": "2.9.12",
5
5
  "author": "Paul Bonaud <paulr@bump.sh>",
6
6
  "bin": {
7
7
  "bump": "./bin/run.js"
@@ -17,7 +17,7 @@
17
17
  "@types/node": "^24",
18
18
  "@types/sinon": "^17.0.3",
19
19
  "@typescript-eslint/eslint-plugin": "^8.13.0",
20
- "chai": "^5.1.2",
20
+ "chai": "^6.2.2",
21
21
  "eslint": "^8",
22
22
  "eslint-config-oclif": "^5",
23
23
  "eslint-config-oclif-typescript": "^3",
@@ -26,11 +26,11 @@
26
26
  "mocha": "^11",
27
27
  "mock-stdin": "^1.0.0",
28
28
  "nock": "^14.0.0-beta.16",
29
- "np": "^10.1.0",
29
+ "np": "^11.0.2",
30
30
  "nyc": "^17.1.0",
31
31
  "oclif": "^4",
32
32
  "shx": "^0.4.0",
33
- "sinon": "^19.0.2",
33
+ "sinon": "^21.0.1",
34
34
  "ts-node": "^10",
35
35
  "typescript": "^5"
36
36
  },
@@ -101,7 +101,7 @@
101
101
  "axios": "^1.7.7",
102
102
  "chalk": "^5.3.0",
103
103
  "debug": "^4.3.7",
104
- "jsonpathly": "^2.0.2",
104
+ "jsonpathly": "^3.0.0",
105
105
  "mergician": "^2.0.2",
106
106
  "open": "^10.1.0"
107
107
  }