@smartbear/mcp 0.2.2 → 0.3.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.
- package/README.md +149 -63
- package/dist/common/templates.js +4 -1
- package/dist/insight-hub/client/api/CurrentUser.js +9 -3
- package/dist/insight-hub/client/api/Error.js +81 -0
- package/dist/insight-hub/client/api/Project.js +19 -1
- package/dist/insight-hub/client/api/base.js +10 -2
- package/dist/insight-hub/client.js +300 -131
- package/dist/package.json +13 -4
- package/dist/tests/unit/common/templates.test.js +149 -0
- package/dist/tests/unit/insight-hub/api-utilities.test.js +31 -0
- package/dist/tests/unit/insight-hub/client.test.js +920 -0
- package/dist/tests/unit/insight-hub/filters.test.js +93 -0
- package/dist/vitest.config.js +57 -0
- package/package.json +13 -4
- package/api-hub/README.md +0 -29
- package/assets/smartbear-logo-dark.svg +0 -17
- package/assets/smartbear-logo-light.svg +0 -17
- package/insight-hub/README.md +0 -42
- package/reflect/README.md +0 -25
package/README.md
CHANGED
|
@@ -1,24 +1,58 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<a href="https://www.smartbear.com">
|
|
3
3
|
<picture>
|
|
4
|
-
<source media="(prefers-color-scheme: dark)" srcset="assets/
|
|
5
|
-
<img alt="SmartBear logo" src="assets/
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://assets.smartbear.com/m/79b99a7ff9c81a9a/original/SmartBear-Logo_Dark-Mode.svg">
|
|
5
|
+
<img alt="SmartBear logo" src="https://assets.smartbear.com/m/105001cc5db1e0bf/original/SmartBear-Logo_Light-Mode.svg">
|
|
6
6
|
</picture>
|
|
7
7
|
</a>
|
|
8
8
|
<h1>SmartBear MCP server</h1>
|
|
9
|
+
|
|
10
|
+
<!-- Badges -->
|
|
11
|
+
<div>
|
|
12
|
+
<a href="https://github.com/SmartBear/smartbear-mcp/actions/workflows/test.yml"><img src="https://github.com/SmartBear/smartbear-mcp/workflows/Test%20Suite/badge.svg" alt="Test Status"></a>
|
|
13
|
+
<a href="https://smartbear.github.io/smartbear-mcp/"><img src="https://img.shields.io/badge/coverage-dynamic-brightgreen" alt="Coverage"></a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/@smartbear/mcp"><img src="https://img.shields.io/npm/v/@smartbear/mcp" alt="npm version"></a>
|
|
15
|
+
<a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/MCP-Compatible-blue" alt="MCP Compatible"></a>
|
|
16
|
+
<a href="https://developer.smartbear.com/smartbear-mcp"><img src="https://img.shields.io/badge/documentation-latest-blue.svg" alt="Documentation"></a>
|
|
17
|
+
</div>
|
|
9
18
|
</div>
|
|
19
|
+
<br />
|
|
20
|
+
|
|
21
|
+
A Model Context Protocol (MCP) server which provides AI assistants with seamless access to SmartBear's suite of testing and monitoring tools, including [Insight Hub](https://www.smartbear.com/insight-hub), [Reflect](https://reflect.run), and [API Hub](https://www.smartbear.com/api-hub).
|
|
22
|
+
|
|
23
|
+
## What is MCP?
|
|
24
|
+
|
|
25
|
+
The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open standard that enables AI assistants to securely connect to external data sources and tools. This server exposes SmartBear's APIs through natural language interfaces, allowing you to query your testing data, analyze performance metrics, and manage test automation directly from your AI workflow.
|
|
26
|
+
|
|
27
|
+
## Supported Tools
|
|
28
|
+
|
|
29
|
+
See individual guides for suggested prompts and supported tools and resources:
|
|
30
|
+
|
|
31
|
+
- [Insight Hub](https://developer.smartbear.com/smartbear-mcp/docs/insight-hub-integration) - Comprehensive error monitoring and debugging capabilities
|
|
32
|
+
- [Test Hub](https://developer.smartbear.com/smartbear-mcp/docs/test-hub-integration) - Test management and execution capabilities
|
|
33
|
+
- [API Hub](https://developer.smartbear.com/smartbear-mcp/docs/api-hub-integration) - Portal management capabilities
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Prerequisites
|
|
37
|
+
|
|
38
|
+
- Node.js 20+ and npm
|
|
39
|
+
- Access to SmartBear products (Insight Hub, Reflect, or API Hub)
|
|
40
|
+
- Valid API tokens for the products you want to integrate
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
10
43
|
|
|
11
|
-
|
|
44
|
+
The MCP server is distributed as an npm package [`@smartbear/mcp`](https://www.npmjs.com/package/@smartbear/mcp), making it easy to integrate into your development workflow.
|
|
12
45
|
|
|
13
|
-
|
|
46
|
+
The server is started with the API key or auth token that you use with your SmartBear product(s). They are optional and can be removed from your configuration if you aren't using the product. For Insight Hub, if you provide a project API key it will narrow down all searches to a single project in your Insight Hub dashboard. Leave this field blank if you wish to interact across multiple projects at a time.
|
|
14
47
|
|
|
15
|
-
|
|
48
|
+
### VS Code with Copilot
|
|
16
49
|
|
|
17
|
-
|
|
50
|
+
For the quickest setup, use the "MCP: Add server…" command in the Command Palette to add the `@smartbear/mcp` npm package.
|
|
18
51
|
|
|
19
|
-
|
|
52
|
+
<details>
|
|
53
|
+
<summary><strong>📋 Manual installation</strong></summary>
|
|
20
54
|
|
|
21
|
-
|
|
55
|
+
Alternatively, you can use `npx` (or globally install) the `@smartbear/mcp` package to run the server and add the following to your `.vscode/mcp.json` file:
|
|
22
56
|
|
|
23
57
|
```json
|
|
24
58
|
{
|
|
@@ -66,76 +100,128 @@ If setting up manually, add the following configuration to `.vscode/mcp.json`:
|
|
|
66
100
|
]
|
|
67
101
|
}
|
|
68
102
|
```
|
|
103
|
+
</details>
|
|
69
104
|
|
|
70
|
-
###
|
|
105
|
+
### Claude Desktop
|
|
71
106
|
|
|
72
|
-
|
|
107
|
+
Add the following configuration to your `claude_desktop_config.json` to launch the MCP server via `npx`:
|
|
73
108
|
|
|
74
|
-
```
|
|
75
|
-
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"mcpServers": {
|
|
112
|
+
"smartbear": {
|
|
113
|
+
"command": "npx",
|
|
114
|
+
"args": [
|
|
115
|
+
"-y",
|
|
116
|
+
"@smartbear/mcp@latest"
|
|
117
|
+
],
|
|
118
|
+
"env": {
|
|
119
|
+
"INSIGHT_HUB_AUTH_TOKEN": "your_personal_auth_token",
|
|
120
|
+
"INSIGHT_HUB_PROJECT_API_KEY": "your_project_api_key",
|
|
121
|
+
"REFLECT_API_TOKEN": "your_reflect_token",
|
|
122
|
+
"API_HUB_API_KEY": "your_api_hub_key"
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
76
127
|
```
|
|
77
128
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
## Supported Tools
|
|
81
|
-
|
|
82
|
-
See individual guides for suggested prompts and supported tools and resources:
|
|
83
|
-
|
|
84
|
-
- [Insight Hub](./insight-hub/README.md)\
|
|
85
|
-
Get your top events and invite your LLM to help you fix them.
|
|
86
|
-
- [Reflect](./reflect/README.md)
|
|
87
|
-
- [API Hub](./api-hub/README.md)
|
|
129
|
+
## Documentation
|
|
88
130
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
- `INSIGHT_HUB_AUTH_TOKEN`: Required for Insight Hub tools. The Auth Token for Insight Hub.
|
|
92
|
-
- `REFLECT_API_TOKEN`: Required for Reflect tools. The Reflect Account API Key for Reflect-based tools.
|
|
93
|
-
- `API_HUB_API_KEY`: Required for API Hub tools. The API Key for API Hub tools.
|
|
94
|
-
- `MCP_SERVER_INSIGHT_HUB_API_KEY`: Optional. If set, enables error reporting of the _MCP_server_ code via the BugSnag SDK. This is useful for debugging and monitoring of the MCP server itself and shouldn't be set to the same API key as your app.
|
|
95
|
-
|
|
96
|
-
See individual guides for product-specific configuration via environment variables.
|
|
131
|
+
For detailed introduction, examples, and advanced configuration visit our 📖 [Full Documentation](https://developer.smartbear.com/smartbear-mcp)
|
|
97
132
|
|
|
98
133
|
## Local Development
|
|
99
134
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
135
|
+
For developers who want to contribute to the SmartBear MCP server, customize its functionality, or work with the latest development features, you can build and run the server directly from source code. This approach gives you full control over the implementation and allows you to make modifications as needed.
|
|
136
|
+
|
|
137
|
+
1. **Clone the repository:**
|
|
138
|
+
```bash
|
|
139
|
+
git clone https://github.com/SmartBear/smartbear-mcp.git
|
|
140
|
+
cd smartbear-mcp
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
2. **Install dependencies:**
|
|
144
|
+
```bash
|
|
145
|
+
npm install
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
3. **Build the server:**
|
|
149
|
+
```bash
|
|
150
|
+
npm run build
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
4. **Add the server to your IDE** configuration updating `.vscode/mcp.json` (or equivalent) to point to your local build
|
|
154
|
+
|
|
155
|
+
<details>
|
|
156
|
+
<summary><strong>📋 VSCode (mcp.json)</strong></summary>
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"servers": {
|
|
161
|
+
"smartbear": {
|
|
162
|
+
"type": "stdio",
|
|
163
|
+
"command": "node",
|
|
164
|
+
"dev": { // <-- To allow debugging in VS Code
|
|
165
|
+
"watch": "dist/**/*.js",
|
|
166
|
+
"debug": {
|
|
167
|
+
"type": "node"
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
"args": ["<PATH_TO_SMARTBEAR_MCP_REPO>/dist/index.js"],
|
|
171
|
+
"env": {
|
|
172
|
+
"INSIGHT_HUB_AUTH_TOKEN": "${input:insight_hub_auth_token}",
|
|
173
|
+
"INSIGHT_HUB_PROJECT_API_KEY": "${input:insight_hub_project_api_key}",
|
|
174
|
+
"REFLECT_API_TOKEN": "${input:reflect_api_token}",
|
|
175
|
+
"API_HUB_API_KEY": "${input:api_hub_api_key}"
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"inputs": [
|
|
180
|
+
{
|
|
181
|
+
"id": "insight_hub_auth_token",
|
|
182
|
+
"type": "promptString",
|
|
183
|
+
"description": "Insight Hub Auth Token - leave blank to disable Insight Hub tools",
|
|
184
|
+
"password": true
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"id": "insight_hub_project_api_key",
|
|
188
|
+
"type": "promptString",
|
|
189
|
+
"description": "Insight Hub Project API Key - for single project interactions",
|
|
190
|
+
"password": false
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"id": "reflect_api_token",
|
|
194
|
+
"type": "promptString",
|
|
195
|
+
"description": "Reflect API Token - leave blank to disable Reflect tools",
|
|
196
|
+
"password": true
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"id": "api_hub_api_key",
|
|
200
|
+
"type": "promptString",
|
|
201
|
+
"description": "API Hub API Key - leave blank to disable API Hub tools",
|
|
202
|
+
"password": true
|
|
203
|
+
}
|
|
204
|
+
]
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
</details>
|
|
103
208
|
|
|
104
|
-
|
|
209
|
+
5. **Local testing** using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector) web interface:
|
|
105
210
|
|
|
106
|
-
```bash
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
```
|
|
211
|
+
```bash
|
|
212
|
+
INSIGHT_HUB_AUTH_TOKEN="your_token" REFLECT_API_TOKEN="your_reflect_token" API_HUB_API_KEY="your_api_hub_key" npx @modelcontextprotocol/inspector npx @smartbear/mcp@latest
|
|
213
|
+
```
|
|
110
214
|
|
|
111
|
-
|
|
215
|
+
## License
|
|
112
216
|
|
|
113
|
-
|
|
217
|
+
This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the [LICENSE](LICENSE.txt) file in the project repository.
|
|
114
218
|
|
|
115
|
-
|
|
116
|
-
{
|
|
117
|
-
"servers": {
|
|
118
|
-
"smartbear": {
|
|
119
|
-
"type": "stdio",
|
|
120
|
-
"command": "node",
|
|
121
|
-
"args": ["<PATH_TO_SMARTBEAR_MCP>/dist/index.js"],
|
|
122
|
-
"env": {
|
|
123
|
-
// ...same as above...
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
"inputs": [
|
|
128
|
-
// ...same as above...
|
|
129
|
-
]
|
|
130
|
-
}
|
|
131
|
-
```
|
|
219
|
+
## Support
|
|
132
220
|
|
|
133
|
-
|
|
221
|
+
* [Search open and closed issues](https://github.com/SmartBear/smartbear-mcp/issues?utf8=✓&q=is%3Aissue) for similar problems
|
|
222
|
+
* [Report a bug or request a feature](https://github.com/SmartBear/smartbear-mcp/issues/new)
|
|
134
223
|
|
|
135
|
-
```bash
|
|
136
|
-
REFLECT_API_TOKEN=your_reflect_token INSIGHT_HUB_AUTH_TOKEN=your_insight_hub_token API_HUB_API_KEY=your_api_hub_api_key node dist/index.js
|
|
137
|
-
```
|
|
138
224
|
|
|
139
|
-
|
|
225
|
+
---
|
|
140
226
|
|
|
141
|
-
|
|
227
|
+
**SmartBear MCP Server** - Bringing the power of SmartBear's testing and monitoring ecosystem to your AI-powered development workflow.
|
package/dist/common/templates.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
export function toolDescriptionTemplate(params) {
|
|
2
|
-
const { summary, useCases, examples, parameters, hints } = params;
|
|
2
|
+
const { summary, useCases, examples, parameters, hints, outputFormat } = params;
|
|
3
3
|
let description = summary;
|
|
4
4
|
// Parameters (essential)
|
|
5
5
|
if (parameters.length > 0) {
|
|
6
6
|
description += `\n\n**Parameters:** ${parameters.map(p => `${p.name} (${p.type})${p.required ? ' *required*' : ''}`).join(', ')}`;
|
|
7
7
|
}
|
|
8
|
+
if (outputFormat) {
|
|
9
|
+
description += `\n\n**Output Format:** ${outputFormat}`;
|
|
10
|
+
}
|
|
8
11
|
// Use Cases
|
|
9
12
|
if (useCases.length > 0) {
|
|
10
13
|
description += `\n\n**Use Cases:** ${useCases.map((uc, i) => `${i + 1}. ${uc}`).join(' ')}`;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseAPI, pickFieldsFromArray } from './base.js';
|
|
2
2
|
// --- API Class ---
|
|
3
3
|
export class CurrentUserAPI extends BaseAPI {
|
|
4
|
-
static organizationFields = ['id', 'name'];
|
|
4
|
+
static organizationFields = ['id', 'name', 'slug'];
|
|
5
5
|
static projectFields = ['id', 'name', 'slug', 'api_key'];
|
|
6
6
|
constructor(configuration) {
|
|
7
7
|
super(configuration);
|
|
@@ -25,7 +25,10 @@ export class CurrentUserAPI extends BaseAPI {
|
|
|
25
25
|
url,
|
|
26
26
|
}, paginate);
|
|
27
27
|
// Only return allowed fields
|
|
28
|
-
return
|
|
28
|
+
return {
|
|
29
|
+
...data,
|
|
30
|
+
body: pickFieldsFromArray(data.body || [], CurrentUserAPI.organizationFields)
|
|
31
|
+
};
|
|
29
32
|
}
|
|
30
33
|
/**
|
|
31
34
|
* List projects for a given organization
|
|
@@ -49,6 +52,9 @@ export class CurrentUserAPI extends BaseAPI {
|
|
|
49
52
|
url,
|
|
50
53
|
}, paginate);
|
|
51
54
|
// Only return allowed fields
|
|
52
|
-
return
|
|
55
|
+
return {
|
|
56
|
+
...data,
|
|
57
|
+
body: pickFieldsFromArray(data.body || [], CurrentUserAPI.projectFields)
|
|
58
|
+
};
|
|
53
59
|
}
|
|
54
60
|
}
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import { BaseAPI } from './base.js';
|
|
2
2
|
import { toQueryString } from './filters.js';
|
|
3
|
+
export const ErrorOperations = [
|
|
4
|
+
'override_severity',
|
|
5
|
+
'assign',
|
|
6
|
+
'create_issue',
|
|
7
|
+
'link_issue',
|
|
8
|
+
'unlink_issue',
|
|
9
|
+
'open',
|
|
10
|
+
'snooze',
|
|
11
|
+
'fix',
|
|
12
|
+
'ignore',
|
|
13
|
+
'delete',
|
|
14
|
+
'discard',
|
|
15
|
+
'undiscard'
|
|
16
|
+
];
|
|
17
|
+
export const ReopenConditions = [
|
|
18
|
+
'occurs_after',
|
|
19
|
+
'n_occurrences_in_m_hours',
|
|
20
|
+
'n_additional_occurrences',
|
|
21
|
+
'n_additional_users'
|
|
22
|
+
];
|
|
3
23
|
// --- API Class ---
|
|
4
24
|
export class ErrorAPI extends BaseAPI {
|
|
5
25
|
constructor(configuration) {
|
|
@@ -41,6 +61,17 @@ export class ErrorAPI extends BaseAPI {
|
|
|
41
61
|
url,
|
|
42
62
|
}));
|
|
43
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* List the Events on a Project
|
|
66
|
+
* GET /projects/{project_id}/events
|
|
67
|
+
*/
|
|
68
|
+
async listEventsOnProject(projectId, queryString = '') {
|
|
69
|
+
const url = `/projects/${projectId}/events${queryString}`;
|
|
70
|
+
return await this.request({
|
|
71
|
+
method: 'GET',
|
|
72
|
+
url,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
44
75
|
/**
|
|
45
76
|
* View an Event by ID
|
|
46
77
|
* GET /projects/{project_id}/events/{event_id}
|
|
@@ -72,4 +103,54 @@ export class ErrorAPI extends BaseAPI {
|
|
|
72
103
|
url,
|
|
73
104
|
}));
|
|
74
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Update an Error on a Project
|
|
108
|
+
* PATCH /projects/{project_id}/errors/{error_id}
|
|
109
|
+
*/
|
|
110
|
+
async updateErrorOnProject(projectId, errorId, data, options = {}) {
|
|
111
|
+
const params = new URLSearchParams();
|
|
112
|
+
for (const [key, value] of Object.entries(options)) {
|
|
113
|
+
if (value !== undefined)
|
|
114
|
+
params.append(key, String(value));
|
|
115
|
+
}
|
|
116
|
+
const url = params.toString()
|
|
117
|
+
? `/projects/${projectId}/errors/${errorId}?${params}`
|
|
118
|
+
: `/projects/${projectId}/errors/${errorId}`;
|
|
119
|
+
return (await this.request({
|
|
120
|
+
method: 'PATCH',
|
|
121
|
+
url,
|
|
122
|
+
body: data,
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* List Pivots on an Error
|
|
127
|
+
* GET /projects/{project_id}/errors/{error_id}/pivots
|
|
128
|
+
*/
|
|
129
|
+
async listErrorPivots(projectId, errorId, options = {}) {
|
|
130
|
+
const params = new URLSearchParams();
|
|
131
|
+
if (options.filters) {
|
|
132
|
+
const filterParams = new URLSearchParams(toQueryString(options.filters));
|
|
133
|
+
filterParams.forEach((value, key) => {
|
|
134
|
+
params.append(key, value);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
if (options.summary_size !== undefined) {
|
|
138
|
+
params.append('summary_size', options.summary_size.toString());
|
|
139
|
+
}
|
|
140
|
+
if (options.pivots && options.pivots.length > 0) {
|
|
141
|
+
options.pivots.forEach(pivot => {
|
|
142
|
+
params.append('pivots[]', pivot);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (options.per_page !== undefined) {
|
|
146
|
+
params.append('per_page', options.per_page.toString());
|
|
147
|
+
}
|
|
148
|
+
const url = params.toString()
|
|
149
|
+
? `/projects/${projectId}/errors/${errorId}/pivots?${params}`
|
|
150
|
+
: `/projects/${projectId}/errors/${errorId}/pivots`;
|
|
151
|
+
return await this.request({
|
|
152
|
+
method: 'GET',
|
|
153
|
+
url,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
75
156
|
}
|
|
@@ -23,6 +23,24 @@ export class ProjectAPI extends BaseAPI {
|
|
|
23
23
|
url,
|
|
24
24
|
});
|
|
25
25
|
// Only return allowed fields
|
|
26
|
-
return
|
|
26
|
+
return {
|
|
27
|
+
...data,
|
|
28
|
+
body: pickFieldsFromArray(data.body || [], ProjectAPI.eventFieldFields)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a Project in an Organization
|
|
33
|
+
* POST /organizations/{organization_id}/projects
|
|
34
|
+
* @param organizationId The organization ID
|
|
35
|
+
* @param data The project creation request body
|
|
36
|
+
* @returns A promise that resolves to the created project
|
|
37
|
+
*/
|
|
38
|
+
async createProject(organizationId, data) {
|
|
39
|
+
const url = `/organizations/${organizationId}/projects`;
|
|
40
|
+
return await this.request({
|
|
41
|
+
method: 'POST',
|
|
42
|
+
url,
|
|
43
|
+
body: data,
|
|
44
|
+
});
|
|
27
45
|
}
|
|
28
46
|
}
|
|
@@ -31,12 +31,17 @@ export class BaseAPI {
|
|
|
31
31
|
const url = options.url.startsWith('http') ? options.url : `${this.configuration.basePath || ''}${options.url}`;
|
|
32
32
|
let results = [];
|
|
33
33
|
let nextUrl = url;
|
|
34
|
+
let apiResponse;
|
|
34
35
|
do {
|
|
35
36
|
const response = await fetch(nextUrl, fetchOptions);
|
|
36
37
|
if (!response.ok) {
|
|
37
38
|
const errorText = await response.text();
|
|
38
39
|
throw new Error(`Request failed with status ${response.status}: ${errorText}`);
|
|
39
40
|
}
|
|
41
|
+
apiResponse = {
|
|
42
|
+
status: response.status,
|
|
43
|
+
headers: response.headers
|
|
44
|
+
};
|
|
40
45
|
const data = await response.json();
|
|
41
46
|
if (paginate) {
|
|
42
47
|
results = results.concat(data);
|
|
@@ -50,9 +55,12 @@ export class BaseAPI {
|
|
|
50
55
|
}
|
|
51
56
|
}
|
|
52
57
|
else {
|
|
53
|
-
|
|
58
|
+
apiResponse.body = data;
|
|
54
59
|
}
|
|
55
60
|
} while (paginate && nextUrl);
|
|
56
|
-
|
|
61
|
+
if (paginate) {
|
|
62
|
+
apiResponse.body = results;
|
|
63
|
+
}
|
|
64
|
+
return apiResponse;
|
|
57
65
|
}
|
|
58
66
|
}
|