@smartbear/mcp 0.12.0 → 0.12.1
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/dist/bugsnag/client/api/Error.js +52 -14
- package/dist/bugsnag/client/api/Project.js +65 -32
- package/dist/bugsnag/client.js +14 -10
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { toUrlSearchParams } from "../filters.js";
|
|
1
2
|
import { ErrorsApiFetchParamCreator, } from "./api.js";
|
|
2
|
-
import { BaseAPI
|
|
3
|
+
import { BaseAPI } from "./base.js";
|
|
3
4
|
export class ErrorAPI extends BaseAPI {
|
|
4
5
|
static filterFields = ["url", "project_url", "events_url"];
|
|
5
6
|
/**
|
|
@@ -14,9 +15,27 @@ export class ErrorAPI extends BaseAPI {
|
|
|
14
15
|
* Get the latest Event in a Project, with optional filters
|
|
15
16
|
* GET /projects/{project_id}/events
|
|
16
17
|
*/
|
|
17
|
-
async listEventsOnProject(projectId, base, sort, direction, perPage, filters, fullReports) {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
async listEventsOnProject(projectId, base, sort, direction, perPage, filters, fullReports, nextUrl) {
|
|
19
|
+
if (nextUrl) {
|
|
20
|
+
// Don't allow override of these params when using nextUrl
|
|
21
|
+
direction = undefined;
|
|
22
|
+
sort = undefined;
|
|
23
|
+
base = undefined;
|
|
24
|
+
}
|
|
25
|
+
const localVarFetchArgs = ErrorsApiFetchParamCreator(this.configuration).listEventsOnProject(projectId, base ?? undefined, sort, direction, perPage, undefined, // Filters are encoded separately below
|
|
26
|
+
fullReports, undefined);
|
|
27
|
+
const url = new URL(nextUrl ?? localVarFetchArgs.url, this.configuration.basePath);
|
|
28
|
+
if (perPage) {
|
|
29
|
+
// Allow override of per page, even with nextUrl
|
|
30
|
+
url.searchParams.set("per_page", perPage.toString());
|
|
31
|
+
}
|
|
32
|
+
if (!nextUrl && filters) {
|
|
33
|
+
// Apply our own encoding of filters
|
|
34
|
+
toUrlSearchParams(filters).forEach((value, key) => {
|
|
35
|
+
url.searchParams.append(key, value);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return await this.requestArray(url.toString(), localVarFetchArgs.options, false);
|
|
20
39
|
}
|
|
21
40
|
/**
|
|
22
41
|
* View an Event by ID
|
|
@@ -31,19 +50,26 @@ export class ErrorAPI extends BaseAPI {
|
|
|
31
50
|
* GET /projects/{project_id}/errors
|
|
32
51
|
*/
|
|
33
52
|
async listProjectErrors(projectId, base, sort, direction, perPage, filters, nextUrl) {
|
|
34
|
-
const options = getQueryParams(nextUrl, nextUrl ? undefined : filters);
|
|
35
53
|
if (nextUrl) {
|
|
36
|
-
|
|
37
|
-
// Next links need to be used as-is to ensure results are consistent, so only the page size can be modified
|
|
38
|
-
// the others will get overridden
|
|
39
|
-
options.query.per_page = perPage.toString();
|
|
40
|
-
}
|
|
54
|
+
// Don't allow override of these params when using nextUrl
|
|
41
55
|
direction = undefined;
|
|
42
56
|
sort = undefined;
|
|
43
57
|
base = undefined;
|
|
44
58
|
}
|
|
45
|
-
const localVarFetchArgs = ErrorsApiFetchParamCreator(this.configuration).listProjectErrors(projectId, base ?? undefined, sort, direction,
|
|
46
|
-
|
|
59
|
+
const localVarFetchArgs = ErrorsApiFetchParamCreator(this.configuration).listProjectErrors(projectId, base ?? undefined, sort, direction, undefined, undefined, // Filters are encoded separately below
|
|
60
|
+
undefined, undefined);
|
|
61
|
+
const url = new URL(nextUrl ?? localVarFetchArgs.url, this.configuration.basePath);
|
|
62
|
+
if (perPage) {
|
|
63
|
+
// Allow override of per page, even with nextUrl
|
|
64
|
+
url.searchParams.set("per_page", perPage.toString());
|
|
65
|
+
}
|
|
66
|
+
if (!nextUrl && filters) {
|
|
67
|
+
// Apply our own encoding of filters
|
|
68
|
+
toUrlSearchParams(filters).forEach((value, key) => {
|
|
69
|
+
url.searchParams.append(key, value);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return await this.requestArray(url.toString(), localVarFetchArgs.options, false);
|
|
47
73
|
}
|
|
48
74
|
/**
|
|
49
75
|
* Update an Error on a Project
|
|
@@ -58,7 +84,19 @@ export class ErrorAPI extends BaseAPI {
|
|
|
58
84
|
* GET /projects/{project_id}/errors/{error_id}/pivots
|
|
59
85
|
*/
|
|
60
86
|
async getPivotValuesOnAnError(projectId, errorId, filters, summarySize, pivots, perPage) {
|
|
61
|
-
const localVarFetchArgs = ErrorsApiFetchParamCreator(this.configuration).listPivotsOnAnError(projectId, errorId, undefined,
|
|
62
|
-
|
|
87
|
+
const localVarFetchArgs = ErrorsApiFetchParamCreator(this.configuration).listPivotsOnAnError(projectId, errorId, undefined, // filters are encoded separately below
|
|
88
|
+
summarySize, pivots, undefined);
|
|
89
|
+
const url = new URL(localVarFetchArgs.url, this.configuration.basePath);
|
|
90
|
+
if (perPage) {
|
|
91
|
+
// Allow override of per page, even with nextUrl
|
|
92
|
+
url.searchParams.set("per_page", perPage.toString());
|
|
93
|
+
}
|
|
94
|
+
if (filters) {
|
|
95
|
+
// Apply our own encoding of filters
|
|
96
|
+
toUrlSearchParams(filters).forEach((value, key) => {
|
|
97
|
+
url.searchParams.append(key, value);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return await this.requestArray(url.toString(), localVarFetchArgs.options, false);
|
|
63
101
|
}
|
|
64
102
|
}
|
|
@@ -68,21 +68,25 @@ export class ProjectAPI extends BaseAPI {
|
|
|
68
68
|
* Lists releases for a specific project.
|
|
69
69
|
* GET /projects/{project_id}/release_groups
|
|
70
70
|
* @param projectId The ID of the project.
|
|
71
|
-
* @param
|
|
71
|
+
* @param releaseStageName The name of the release stage to filter by.
|
|
72
|
+
* @param topOnly Whether to only include top-level releases.
|
|
73
|
+
* @param visibleOnly Whether to only include visible releases.
|
|
74
|
+
* @param perPage The number of results per page.
|
|
75
|
+
* @param nextUrl Optional URL for next page (overrides other pagination params).
|
|
72
76
|
* @returns A promise that resolves to an array of `ReleaseSummaryResponse` objects.
|
|
73
77
|
*/
|
|
74
78
|
async listProjectReleaseGroups(projectId, releaseStageName, topOnly, visibleOnly, perPage, nextUrl) {
|
|
75
|
-
const options = getQueryParams(nextUrl);
|
|
76
|
-
// Next links need to be used as-is to ensure results are consistent, so only the page size can be modified
|
|
77
|
-
// the others will get overridden
|
|
78
79
|
if (nextUrl) {
|
|
79
|
-
options.query.per_page = perPage ? perPage.toString() : undefined;
|
|
80
80
|
topOnly = undefined;
|
|
81
81
|
visibleOnly = undefined;
|
|
82
82
|
}
|
|
83
|
-
const localVarFetchArgs = ProjectsApiFetchParamCreator(this.configuration).listProjectReleaseGroups(projectId, releaseStageName, topOnly, visibleOnly, perPage, undefined,
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
const localVarFetchArgs = ProjectsApiFetchParamCreator(this.configuration).listProjectReleaseGroups(projectId, releaseStageName, topOnly, visibleOnly, perPage, undefined, undefined);
|
|
84
|
+
const url = new URL(nextUrl ?? localVarFetchArgs.url, this.configuration.basePath);
|
|
85
|
+
if (perPage) {
|
|
86
|
+
// Allow override of per page, even with nextUrl
|
|
87
|
+
url.searchParams.set("per_page", perPage.toString());
|
|
88
|
+
}
|
|
89
|
+
return await this.requestArray(url.toString(), localVarFetchArgs.options, false, // Paginate results
|
|
86
90
|
ProjectAPI.releaseFields);
|
|
87
91
|
}
|
|
88
92
|
/**
|
|
@@ -122,17 +126,25 @@ export class ProjectAPI extends BaseAPI {
|
|
|
122
126
|
* @returns A promise that resolves to an array of span groups.
|
|
123
127
|
*/
|
|
124
128
|
async listProjectSpanGroups(projectId, sort, direction, perPage, offset, filters, starredOnly, nextUrl) {
|
|
125
|
-
const options = getQueryParams(nextUrl);
|
|
126
129
|
if (nextUrl) {
|
|
127
|
-
|
|
130
|
+
sort = undefined;
|
|
131
|
+
direction = undefined;
|
|
132
|
+
offset = undefined;
|
|
128
133
|
}
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
134
|
+
const localVarFetchArgs = ProjectsApiFetchParamCreator(this.configuration).listProjectSpanGroups(projectId, sort, direction, perPage, offset, undefined, // Filters are encoded separately below
|
|
135
|
+
starredOnly, undefined);
|
|
136
|
+
const url = new URL(nextUrl ?? localVarFetchArgs.url, this.configuration.basePath);
|
|
137
|
+
if (perPage) {
|
|
138
|
+
// Allow override of per page, even with nextUrl
|
|
139
|
+
url.searchParams.set("per_page", perPage.toString());
|
|
132
140
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
141
|
+
if (!nextUrl && filters) {
|
|
142
|
+
// Apply our own encoding of filters
|
|
143
|
+
toUrlSearchParams(filters).forEach((value, key) => {
|
|
144
|
+
url.searchParams.append(key, value);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return await this.requestArray(url.toString(), localVarFetchArgs.options, false);
|
|
136
148
|
}
|
|
137
149
|
/**
|
|
138
150
|
* Get detailed information about a specific span group.
|
|
@@ -143,12 +155,15 @@ export class ProjectAPI extends BaseAPI {
|
|
|
143
155
|
* @returns A promise that resolves to the span group.
|
|
144
156
|
*/
|
|
145
157
|
async getProjectSpanGroup(projectId, id, filters) {
|
|
146
|
-
const
|
|
158
|
+
const localVarFetchArgs = ProjectsApiFetchParamCreator(this.configuration).getProjectSpanGroup(projectId, id, undefined, undefined);
|
|
159
|
+
const url = new URL(localVarFetchArgs.url, this.configuration.basePath);
|
|
147
160
|
if (filters) {
|
|
148
|
-
|
|
161
|
+
// Apply our own encoding of filters
|
|
162
|
+
toUrlSearchParams(filters).forEach((value, key) => {
|
|
163
|
+
url.searchParams.append(key, value);
|
|
164
|
+
});
|
|
149
165
|
}
|
|
150
|
-
|
|
151
|
-
return await this.requestObject(localVarFetchArgs.url, localVarFetchArgs.options);
|
|
166
|
+
return await this.requestObject(url.toString(), localVarFetchArgs.options);
|
|
152
167
|
}
|
|
153
168
|
/**
|
|
154
169
|
* Get time-series performance metrics for a span group.
|
|
@@ -159,12 +174,15 @@ export class ProjectAPI extends BaseAPI {
|
|
|
159
174
|
* @returns A promise that resolves to the timeline data.
|
|
160
175
|
*/
|
|
161
176
|
async getProjectSpanGroupTimeline(projectId, id, filters) {
|
|
162
|
-
const
|
|
177
|
+
const localVarFetchArgs = ProjectsApiFetchParamCreator(this.configuration).getProjectSpanGroupTimeline(projectId, id, undefined, undefined);
|
|
178
|
+
const url = new URL(localVarFetchArgs.url, this.configuration.basePath);
|
|
163
179
|
if (filters) {
|
|
164
|
-
|
|
180
|
+
// Apply our own encoding of filters
|
|
181
|
+
toUrlSearchParams(filters).forEach((value, key) => {
|
|
182
|
+
url.searchParams.append(key, value);
|
|
183
|
+
});
|
|
165
184
|
}
|
|
166
|
-
|
|
167
|
-
return await this.requestObject(localVarFetchArgs.url, localVarFetchArgs.options);
|
|
185
|
+
return await this.requestObject(url.toString(), localVarFetchArgs.options);
|
|
168
186
|
}
|
|
169
187
|
/**
|
|
170
188
|
* Get distribution histogram of span durations for a span group.
|
|
@@ -179,8 +197,15 @@ export class ProjectAPI extends BaseAPI {
|
|
|
179
197
|
if (filters) {
|
|
180
198
|
options.query = toUrlSearchParams(filters);
|
|
181
199
|
}
|
|
182
|
-
const localVarFetchArgs = ProjectsApiFetchParamCreator(this.configuration).getProjectSpanGroupDistribution(projectId, id, undefined,
|
|
183
|
-
|
|
200
|
+
const localVarFetchArgs = ProjectsApiFetchParamCreator(this.configuration).getProjectSpanGroupDistribution(projectId, id, undefined, undefined);
|
|
201
|
+
const url = new URL(localVarFetchArgs.url, this.configuration.basePath);
|
|
202
|
+
if (filters) {
|
|
203
|
+
// Apply our own encoding of filters
|
|
204
|
+
toUrlSearchParams(filters).forEach((value, key) => {
|
|
205
|
+
url.searchParams.append(key, value);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
return await this.requestObject(url.toString(), localVarFetchArgs.options);
|
|
184
209
|
}
|
|
185
210
|
/**
|
|
186
211
|
* List individual spans for a specific span group with filtering and sorting.
|
|
@@ -195,15 +220,23 @@ export class ProjectAPI extends BaseAPI {
|
|
|
195
220
|
* @returns A promise that resolves to an array of spans.
|
|
196
221
|
*/
|
|
197
222
|
async listSpansBySpanGroupId(projectId, id, filters, sort, direction, perPage, nextUrl) {
|
|
198
|
-
const options = getQueryParams(nextUrl);
|
|
199
223
|
if (nextUrl) {
|
|
200
|
-
|
|
224
|
+
sort = undefined;
|
|
225
|
+
direction = undefined;
|
|
201
226
|
}
|
|
202
|
-
|
|
203
|
-
|
|
227
|
+
const localVarFetchArgs = ProjectsApiFetchParamCreator(this.configuration).listSpansBySpanGroupId(projectId, id, undefined, sort, direction, perPage, undefined);
|
|
228
|
+
const url = new URL(nextUrl ?? localVarFetchArgs.url, this.configuration.basePath);
|
|
229
|
+
if (perPage) {
|
|
230
|
+
// Allow override of per page, even with nextUrl
|
|
231
|
+
url.searchParams.set("per_page", perPage.toString());
|
|
204
232
|
}
|
|
205
|
-
|
|
206
|
-
|
|
233
|
+
if (!nextUrl && filters) {
|
|
234
|
+
// Apply our own encoding of filters
|
|
235
|
+
toUrlSearchParams(filters).forEach((value, key) => {
|
|
236
|
+
url.searchParams.append(key, value);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return await this.requestArray(url.toString(), localVarFetchArgs.options, false);
|
|
207
240
|
}
|
|
208
241
|
/**
|
|
209
242
|
* List all spans that belong to a specific trace.
|
package/dist/bugsnag/client.js
CHANGED
|
@@ -234,6 +234,17 @@ export class BugsnagClient {
|
|
|
234
234
|
const projectEvents = await Promise.all(projectIds.map((projectId) => this.errorsApi.viewEventById(projectId, eventId).catch((_e) => null)));
|
|
235
235
|
return projectEvents.find((event) => event && !!event.body)?.body || null;
|
|
236
236
|
}
|
|
237
|
+
async validateEventFields(project, fields) {
|
|
238
|
+
if (fields) {
|
|
239
|
+
const eventFields = await this.getProjectEventFields(project);
|
|
240
|
+
const validKeys = new Set(eventFields.map((f) => f.displayId));
|
|
241
|
+
for (const key of Object.keys(fields)) {
|
|
242
|
+
if (!validKeys.has(key)) {
|
|
243
|
+
throw new ToolError(`Invalid filter key: ${key}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
237
248
|
async getInputProject(projectId) {
|
|
238
249
|
if (typeof projectId === "string") {
|
|
239
250
|
const maybeProject = await this.getProject(projectId);
|
|
@@ -389,6 +400,7 @@ export class BugsnagClient {
|
|
|
389
400
|
error: [{ type: "eq", value: params.errorId }],
|
|
390
401
|
...args.filters,
|
|
391
402
|
};
|
|
403
|
+
await this.validateEventFields(project, filters);
|
|
392
404
|
// Get the latest event for this error using the events endpoint with filters
|
|
393
405
|
let latestEvent = null;
|
|
394
406
|
try {
|
|
@@ -554,21 +566,13 @@ export class BugsnagClient {
|
|
|
554
566
|
}, async (args, _extra) => {
|
|
555
567
|
const params = listProjectErrorsInputSchema.parse(args);
|
|
556
568
|
const project = await this.getInputProject(params.projectId);
|
|
557
|
-
// Validate filter keys against cached event fields
|
|
558
|
-
if (params.filters) {
|
|
559
|
-
const eventFields = await this.getProjectEventFields(project);
|
|
560
|
-
const validKeys = new Set(eventFields.map((f) => f.displayId));
|
|
561
|
-
for (const key of Object.keys(params.filters)) {
|
|
562
|
-
if (!validKeys.has(key)) {
|
|
563
|
-
throw new ToolError(`Invalid filter key: ${key}`);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
569
|
const filters = {
|
|
568
570
|
"event.since": [{ type: "eq", value: "30d" }],
|
|
569
571
|
"error.status": [{ type: "eq", value: "open" }],
|
|
570
572
|
...params.filters,
|
|
571
573
|
};
|
|
574
|
+
// Validate filter keys against cached event fields
|
|
575
|
+
await this.validateEventFields(project, filters);
|
|
572
576
|
const response = await this.errorsApi.listProjectErrors(project.id, null, params.sort, params.direction, params.perPage, filters, params.nextUrl);
|
|
573
577
|
const result = {
|
|
574
578
|
data: response.body,
|