@smartbear/mcp 0.6.0 → 0.8.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 +37 -3
- package/dist/api-hub/client/api.js +387 -0
- package/dist/api-hub/client/configuration.js +27 -0
- package/dist/api-hub/client/index.js +5 -0
- package/dist/api-hub/client/portal-types.js +131 -0
- package/dist/api-hub/client/registry-types.js +69 -0
- package/dist/api-hub/client/tools.js +98 -0
- package/dist/api-hub/client.js +70 -404
- package/dist/bugsnag/client/api/CurrentUser.js +19 -13
- package/dist/bugsnag/client/api/Error.js +45 -57
- package/dist/bugsnag/client/api/Project.js +35 -30
- package/dist/bugsnag/client/api/base.js +24 -9
- package/dist/bugsnag/client/api/filters.js +9 -9
- package/dist/bugsnag/client.js +281 -373
- package/dist/common/info.js +1 -1
- package/dist/common/server.js +39 -28
- package/dist/index.js +18 -4
- package/dist/pactflow/client/ai.js +20 -20
- package/dist/pactflow/client/base.js +48 -13
- package/dist/pactflow/client/prompts.js +10 -12
- package/dist/pactflow/client/tools.js +18 -18
- package/dist/pactflow/client/utils.js +1 -1
- package/dist/pactflow/client.js +23 -15
- package/dist/qmetry/client/api/client-api.js +39 -0
- package/dist/qmetry/client/handlers.js +11 -0
- package/dist/qmetry/client/project.js +27 -0
- package/dist/qmetry/client/testcase.js +104 -0
- package/dist/qmetry/client/tools.js +222 -0
- package/dist/qmetry/client.js +95 -0
- package/dist/qmetry/config/constants.js +12 -0
- package/dist/qmetry/config/rest-endpoints.js +11 -0
- package/dist/qmetry/types/common.js +174 -0
- package/dist/qmetry/types/testcase.js +19 -0
- package/dist/reflect/client.js +14 -14
- package/dist/zephyr/client.js +16 -0
- package/dist/zephyr/common/api-client.js +27 -0
- package/dist/zephyr/common/auth-service.js +14 -0
- package/dist/zephyr/common/types.js +35 -0
- package/dist/zephyr/tool/project/get-projects.js +54 -0
- package/dist/zephyr/tool/zephyr-tool.js +1 -0
- package/package.json +8 -6
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { BaseAPI, pickFieldsFromArray } from
|
|
1
|
+
import { BaseAPI, pickFieldsFromArray } from "./base.js";
|
|
2
|
+
import { ProjectAPI } from "./Project.js";
|
|
2
3
|
// --- API Class ---
|
|
3
4
|
export class CurrentUserAPI extends BaseAPI {
|
|
4
|
-
static filterFields = [
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
static filterFields = [
|
|
6
|
+
"collaborators_url",
|
|
7
|
+
"projects_url",
|
|
8
|
+
"upgrade_url",
|
|
9
|
+
];
|
|
10
|
+
static organizationFields = ["id", "name", "slug"];
|
|
7
11
|
constructor(configuration) {
|
|
8
12
|
super(configuration, CurrentUserAPI.filterFields);
|
|
9
13
|
}
|
|
@@ -12,23 +16,25 @@ export class CurrentUserAPI extends BaseAPI {
|
|
|
12
16
|
* GET /user/organizations
|
|
13
17
|
*/
|
|
14
18
|
async listUserOrganizations(options = {}) {
|
|
15
|
-
const { admin,
|
|
19
|
+
const { admin, ...queryOptions } = options;
|
|
16
20
|
const params = new URLSearchParams();
|
|
17
21
|
if (admin !== undefined)
|
|
18
|
-
params.append(
|
|
22
|
+
params.append("admin", String(admin));
|
|
19
23
|
for (const [key, value] of Object.entries(queryOptions)) {
|
|
20
24
|
if (value !== undefined)
|
|
21
25
|
params.append(key, String(value));
|
|
22
26
|
}
|
|
23
|
-
const url = params.toString()
|
|
27
|
+
const url = params.toString()
|
|
28
|
+
? `/user/organizations?${params}`
|
|
29
|
+
: "/user/organizations";
|
|
24
30
|
const data = await this.request({
|
|
25
|
-
method:
|
|
31
|
+
method: "GET",
|
|
26
32
|
url,
|
|
27
|
-
}
|
|
33
|
+
});
|
|
28
34
|
// Only return allowed fields
|
|
29
35
|
return {
|
|
30
36
|
...data,
|
|
31
|
-
body: pickFieldsFromArray(data.body || [], CurrentUserAPI.organizationFields)
|
|
37
|
+
body: pickFieldsFromArray(data.body || [], CurrentUserAPI.organizationFields),
|
|
32
38
|
};
|
|
33
39
|
}
|
|
34
40
|
/**
|
|
@@ -49,12 +55,12 @@ export class CurrentUserAPI extends BaseAPI {
|
|
|
49
55
|
? `/organizations/${organizationId}/projects?${params}`
|
|
50
56
|
: `/organizations/${organizationId}/projects`;
|
|
51
57
|
const data = await this.request({
|
|
52
|
-
method:
|
|
58
|
+
method: "GET",
|
|
53
59
|
url,
|
|
54
|
-
}
|
|
60
|
+
});
|
|
55
61
|
return {
|
|
56
62
|
...data,
|
|
57
|
-
body: pickFieldsFromArray(data.body || [],
|
|
63
|
+
body: pickFieldsFromArray(data.body || [], ProjectAPI.projectFields),
|
|
58
64
|
};
|
|
59
65
|
}
|
|
60
66
|
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { BaseAPI } from
|
|
2
|
-
import { toQueryString } from
|
|
1
|
+
import { BaseAPI } from "./base.js";
|
|
2
|
+
import { toQueryString } from "./filters.js";
|
|
3
3
|
export const ErrorOperations = [
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
16
|
];
|
|
17
17
|
export const ReopenConditions = [
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
"occurs_after",
|
|
19
|
+
"n_occurrences_in_m_hours",
|
|
20
|
+
"n_additional_occurrences",
|
|
21
|
+
"n_additional_users",
|
|
22
22
|
];
|
|
23
23
|
// --- API Class ---
|
|
24
24
|
export class ErrorAPI extends BaseAPI {
|
|
@@ -40,38 +40,26 @@ export class ErrorAPI extends BaseAPI {
|
|
|
40
40
|
? `/projects/${projectId}/errors/${errorId}?${params}`
|
|
41
41
|
: `/projects/${projectId}/errors/${errorId}`;
|
|
42
42
|
return (await this.request({
|
|
43
|
-
method:
|
|
43
|
+
method: "GET",
|
|
44
44
|
url,
|
|
45
45
|
}));
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
49
|
-
* GET /errors/{error_id}/latest_event
|
|
50
|
-
*/
|
|
51
|
-
async viewLatestEventOnError(errorId, options = {}) {
|
|
52
|
-
const params = new URLSearchParams();
|
|
53
|
-
for (const [key, value] of Object.entries(options)) {
|
|
54
|
-
if (value !== undefined)
|
|
55
|
-
params.append(key, String(value));
|
|
56
|
-
}
|
|
57
|
-
const url = params.toString()
|
|
58
|
-
? `/errors/${errorId}/latest_event?${params}`
|
|
59
|
-
: `/errors/${errorId}/latest_event`;
|
|
60
|
-
return (await this.request({
|
|
61
|
-
method: 'GET',
|
|
62
|
-
url,
|
|
63
|
-
}));
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* List the Events on a Project
|
|
48
|
+
* Get the latest Event in a Project, with optional filters
|
|
67
49
|
* GET /projects/{project_id}/events
|
|
68
50
|
*/
|
|
69
|
-
async
|
|
51
|
+
async getLatestEventOnProject(projectId, queryString = "") {
|
|
70
52
|
const url = `/projects/${projectId}/events${queryString}`;
|
|
71
|
-
|
|
72
|
-
method:
|
|
53
|
+
const response = await this.request({
|
|
54
|
+
method: "GET",
|
|
73
55
|
url,
|
|
74
56
|
});
|
|
57
|
+
return {
|
|
58
|
+
...response,
|
|
59
|
+
body: response.body && response.body.length > 0
|
|
60
|
+
? response.body[0]
|
|
61
|
+
: undefined, // Return only the latest event
|
|
62
|
+
};
|
|
75
63
|
}
|
|
76
64
|
/**
|
|
77
65
|
* View an Event by ID
|
|
@@ -87,7 +75,7 @@ export class ErrorAPI extends BaseAPI {
|
|
|
87
75
|
? `/projects/${projectId}/events/${eventId}?${params}`
|
|
88
76
|
: `/projects/${projectId}/events/${eventId}`;
|
|
89
77
|
return (await this.request({
|
|
90
|
-
method:
|
|
78
|
+
method: "GET",
|
|
91
79
|
url,
|
|
92
80
|
}));
|
|
93
81
|
}
|
|
@@ -98,10 +86,10 @@ export class ErrorAPI extends BaseAPI {
|
|
|
98
86
|
async listProjectErrors(projectId, options = {}) {
|
|
99
87
|
let url = `/projects/${projectId}/errors`;
|
|
100
88
|
// Next links need to be used as-is to ensure results are consistent, so only the page size can be modified
|
|
101
|
-
if (options.
|
|
102
|
-
const nextUrl = new URL(options.
|
|
89
|
+
if (options.next_url !== undefined) {
|
|
90
|
+
const nextUrl = new URL(options.next_url);
|
|
103
91
|
if (options.per_page !== undefined) {
|
|
104
|
-
nextUrl.searchParams.set(
|
|
92
|
+
nextUrl.searchParams.set("per_page", options.per_page.toString());
|
|
105
93
|
}
|
|
106
94
|
url = nextUrl.toString();
|
|
107
95
|
}
|
|
@@ -116,25 +104,25 @@ export class ErrorAPI extends BaseAPI {
|
|
|
116
104
|
}
|
|
117
105
|
// Add pagination and sorting parameters
|
|
118
106
|
if (options.base !== undefined) {
|
|
119
|
-
params.append(
|
|
107
|
+
params.append("base", options.base);
|
|
120
108
|
}
|
|
121
109
|
if (options.sort !== undefined) {
|
|
122
|
-
params.append(
|
|
110
|
+
params.append("sort", options.sort);
|
|
123
111
|
}
|
|
124
112
|
if (options.direction !== undefined) {
|
|
125
|
-
params.append(
|
|
113
|
+
params.append("direction", options.direction);
|
|
126
114
|
}
|
|
127
115
|
if (options.per_page !== undefined) {
|
|
128
|
-
params.append(
|
|
116
|
+
params.append("per_page", options.per_page.toString());
|
|
129
117
|
}
|
|
130
118
|
if (params.size > 0) {
|
|
131
119
|
url = `/projects/${projectId}/errors?${params}`;
|
|
132
120
|
}
|
|
133
121
|
}
|
|
134
122
|
return (await this.request({
|
|
135
|
-
method:
|
|
123
|
+
method: "GET",
|
|
136
124
|
url,
|
|
137
|
-
}));
|
|
125
|
+
}, false));
|
|
138
126
|
}
|
|
139
127
|
/**
|
|
140
128
|
* Update an Error on a Project
|
|
@@ -150,7 +138,7 @@ export class ErrorAPI extends BaseAPI {
|
|
|
150
138
|
? `/projects/${projectId}/errors/${errorId}?${params}`
|
|
151
139
|
: `/projects/${projectId}/errors/${errorId}`;
|
|
152
140
|
return (await this.request({
|
|
153
|
-
method:
|
|
141
|
+
method: "PATCH",
|
|
154
142
|
url,
|
|
155
143
|
body: data,
|
|
156
144
|
}));
|
|
@@ -168,21 +156,21 @@ export class ErrorAPI extends BaseAPI {
|
|
|
168
156
|
});
|
|
169
157
|
}
|
|
170
158
|
if (options.summary_size !== undefined) {
|
|
171
|
-
params.append(
|
|
159
|
+
params.append("summary_size", options.summary_size.toString());
|
|
172
160
|
}
|
|
173
161
|
if (options.pivots && options.pivots.length > 0) {
|
|
174
|
-
options.pivots.forEach(pivot => {
|
|
175
|
-
params.append(
|
|
162
|
+
options.pivots.forEach((pivot) => {
|
|
163
|
+
params.append("pivots[]", pivot);
|
|
176
164
|
});
|
|
177
165
|
}
|
|
178
166
|
if (options.per_page !== undefined) {
|
|
179
|
-
params.append(
|
|
167
|
+
params.append("per_page", options.per_page.toString());
|
|
180
168
|
}
|
|
181
169
|
const url = params.toString()
|
|
182
170
|
? `/projects/${projectId}/errors/${errorId}/pivots?${params}`
|
|
183
171
|
: `/projects/${projectId}/errors/${errorId}/pivots`;
|
|
184
172
|
return await this.request({
|
|
185
|
-
method:
|
|
173
|
+
method: "GET",
|
|
186
174
|
url,
|
|
187
175
|
});
|
|
188
176
|
}
|
|
@@ -1,8 +1,27 @@
|
|
|
1
|
-
import { BaseAPI, pickFieldsFromArray
|
|
1
|
+
import { BaseAPI, pickFieldsFromArray } from "./base.js";
|
|
2
2
|
// --- API Class ---
|
|
3
3
|
export class ProjectAPI extends BaseAPI {
|
|
4
|
-
static
|
|
5
|
-
|
|
4
|
+
static projectFields = [
|
|
5
|
+
"id",
|
|
6
|
+
"name",
|
|
7
|
+
"slug",
|
|
8
|
+
"api_key",
|
|
9
|
+
"stability_target_type",
|
|
10
|
+
"target_stability",
|
|
11
|
+
"critical_stability",
|
|
12
|
+
];
|
|
13
|
+
static filterFields = [
|
|
14
|
+
"errors_url",
|
|
15
|
+
"events_url",
|
|
16
|
+
"url",
|
|
17
|
+
"html_url",
|
|
18
|
+
];
|
|
19
|
+
static eventFieldFields = [
|
|
20
|
+
"custom",
|
|
21
|
+
"display_id",
|
|
22
|
+
"filter_options",
|
|
23
|
+
"pivot_options",
|
|
24
|
+
];
|
|
6
25
|
static buildFields = [
|
|
7
26
|
"id",
|
|
8
27
|
"release_time",
|
|
@@ -29,11 +48,6 @@ export class ProjectAPI extends BaseAPI {
|
|
|
29
48
|
"accumulative_daily_users_seen",
|
|
30
49
|
"accumulative_daily_users_with_unhandled",
|
|
31
50
|
];
|
|
32
|
-
static stabilityFields = [
|
|
33
|
-
"critical_stability",
|
|
34
|
-
"target_stability",
|
|
35
|
-
"stability_target_type",
|
|
36
|
-
];
|
|
37
51
|
constructor(configuration) {
|
|
38
52
|
super(configuration, ProjectAPI.filterFields);
|
|
39
53
|
}
|
|
@@ -46,13 +60,13 @@ export class ProjectAPI extends BaseAPI {
|
|
|
46
60
|
async listProjectEventFields(projectId) {
|
|
47
61
|
const url = `/projects/${projectId}/event_fields`;
|
|
48
62
|
const data = await this.request({
|
|
49
|
-
method:
|
|
63
|
+
method: "GET",
|
|
50
64
|
url,
|
|
51
65
|
});
|
|
52
66
|
// Only return allowed fields
|
|
53
67
|
return {
|
|
54
68
|
...data,
|
|
55
|
-
body: pickFieldsFromArray(data.body || [], ProjectAPI.eventFieldFields)
|
|
69
|
+
body: pickFieldsFromArray(data.body || [], ProjectAPI.eventFieldFields),
|
|
56
70
|
};
|
|
57
71
|
}
|
|
58
72
|
/**
|
|
@@ -65,25 +79,11 @@ export class ProjectAPI extends BaseAPI {
|
|
|
65
79
|
async createProject(organizationId, data) {
|
|
66
80
|
const url = `/organizations/${organizationId}/projects`;
|
|
67
81
|
return await this.request({
|
|
68
|
-
method:
|
|
82
|
+
method: "POST",
|
|
69
83
|
url,
|
|
70
84
|
body: data,
|
|
71
85
|
});
|
|
72
86
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Retrieves the stability targets for a specific project.
|
|
75
|
-
* GET /projects/{project_id} (with internal header)
|
|
76
|
-
* @param projectId The ID of the project.
|
|
77
|
-
* @returns A promise that resolves to the project's stability targets.
|
|
78
|
-
*/
|
|
79
|
-
async getProjectStabilityTargets(projectId) {
|
|
80
|
-
const url = `/projects/${projectId}`;
|
|
81
|
-
const response = await this.request({
|
|
82
|
-
method: "GET",
|
|
83
|
-
url,
|
|
84
|
-
});
|
|
85
|
-
return pickFields(response.body || {}, ProjectAPI.stabilityFields);
|
|
86
|
-
}
|
|
87
87
|
/**
|
|
88
88
|
* Lists builds for a specific project.
|
|
89
89
|
* GET /projects/{project_id}/releases
|
|
@@ -92,11 +92,12 @@ export class ProjectAPI extends BaseAPI {
|
|
|
92
92
|
* @returns A promise that resolves to an array of `ListReleasesResponse` objects.
|
|
93
93
|
*/
|
|
94
94
|
async listBuilds(projectId, opts) {
|
|
95
|
-
const url = opts.next_url ??
|
|
95
|
+
const url = opts.next_url ??
|
|
96
|
+
`/projects/${projectId}/releases${opts.release_stage ? `?release_stage=${opts.release_stage}` : ""}`;
|
|
96
97
|
const response = await this.request({
|
|
97
98
|
method: "GET",
|
|
98
99
|
url,
|
|
99
|
-
});
|
|
100
|
+
}, false);
|
|
100
101
|
return {
|
|
101
102
|
...response,
|
|
102
103
|
body: pickFieldsFromArray(response.body || [], ProjectAPI.buildFields),
|
|
@@ -124,11 +125,15 @@ export class ProjectAPI extends BaseAPI {
|
|
|
124
125
|
* @returns A promise that resolves to an array of `ReleaseSummaryResponse` objects.
|
|
125
126
|
*/
|
|
126
127
|
async listReleases(projectId, opts) {
|
|
127
|
-
const url = opts.next_url ??
|
|
128
|
+
const url = opts.next_url ??
|
|
129
|
+
`/projects/${projectId}/release_groups?` +
|
|
130
|
+
`release_stage_name=${opts.release_stage_name ?? "production"}&` +
|
|
131
|
+
`visible_only=${opts.visible_only ?? false}&` +
|
|
132
|
+
`top_only=${opts.top_only ?? false}`;
|
|
128
133
|
const response = await this.request({
|
|
129
134
|
method: "GET",
|
|
130
|
-
url
|
|
131
|
-
});
|
|
135
|
+
url,
|
|
136
|
+
}, false);
|
|
132
137
|
return {
|
|
133
138
|
...response,
|
|
134
139
|
body: pickFieldsFromArray(response.body || [], ProjectAPI.releaseFields),
|
|
@@ -10,7 +10,7 @@ export function pickFields(obj, keys) {
|
|
|
10
10
|
}
|
|
11
11
|
// Utility to pick only allowed fields from an array of objects
|
|
12
12
|
export function pickFieldsFromArray(arr, keys) {
|
|
13
|
-
return arr.map(obj => pickFields(obj, keys));
|
|
13
|
+
return arr.map((obj) => pickFields(obj, keys));
|
|
14
14
|
}
|
|
15
15
|
// Utility to extract next URL path from Link header
|
|
16
16
|
export function getNextUrlPathFromHeader(headers, basePath) {
|
|
@@ -24,11 +24,21 @@ export function getNextUrlPathFromHeader(headers, basePath) {
|
|
|
24
24
|
return null;
|
|
25
25
|
return match.replace(basePath, "");
|
|
26
26
|
}
|
|
27
|
+
// Utility to extract total count from headers
|
|
28
|
+
export function getTotalCountFromHeader(headers) {
|
|
29
|
+
if (!headers)
|
|
30
|
+
return null;
|
|
31
|
+
const totalCount = headers.get("X-Total-Count");
|
|
32
|
+
if (!totalCount)
|
|
33
|
+
return null;
|
|
34
|
+
const parsed = parseInt(totalCount, 10);
|
|
35
|
+
return Number.isNaN(parsed) ? null : parsed;
|
|
36
|
+
}
|
|
27
37
|
// Ensure URL is absolute
|
|
28
38
|
// The MCP tools exposed use only the path for pagination
|
|
29
39
|
// For making requests, we need to ensure the URL is absolute
|
|
30
40
|
export function ensureFullUrl(url, basePath) {
|
|
31
|
-
return url.startsWith(
|
|
41
|
+
return url.startsWith("http") ? url : `${basePath}${url}`;
|
|
32
42
|
}
|
|
33
43
|
export class BaseAPI {
|
|
34
44
|
configuration;
|
|
@@ -37,12 +47,12 @@ export class BaseAPI {
|
|
|
37
47
|
this.configuration = configuration;
|
|
38
48
|
this.filterFields = filterFields || [];
|
|
39
49
|
}
|
|
40
|
-
async request(options,
|
|
50
|
+
async request(options, fetchAll = true) {
|
|
41
51
|
const headers = {
|
|
42
52
|
...this.configuration.headers,
|
|
43
53
|
...options.headers,
|
|
44
54
|
};
|
|
45
|
-
headers
|
|
55
|
+
headers.Authorization = `token ${this.configuration.authToken}`;
|
|
46
56
|
const fetchOptions = {
|
|
47
57
|
method: options.method,
|
|
48
58
|
headers,
|
|
@@ -52,6 +62,9 @@ export class BaseAPI {
|
|
|
52
62
|
let nextUrl = options.url;
|
|
53
63
|
let apiResponse;
|
|
54
64
|
do {
|
|
65
|
+
if (!this.configuration.basePath) {
|
|
66
|
+
throw new Error("Base path is not configured for API requests");
|
|
67
|
+
}
|
|
55
68
|
nextUrl = ensureFullUrl(nextUrl, this.configuration.basePath);
|
|
56
69
|
const response = await fetch(nextUrl, fetchOptions);
|
|
57
70
|
if (!response.ok) {
|
|
@@ -60,19 +73,21 @@ export class BaseAPI {
|
|
|
60
73
|
}
|
|
61
74
|
apiResponse = {
|
|
62
75
|
status: response.status,
|
|
63
|
-
headers: response.headers
|
|
76
|
+
headers: response.headers,
|
|
64
77
|
};
|
|
65
78
|
const data = await response.json();
|
|
66
|
-
|
|
79
|
+
nextUrl = getNextUrlPathFromHeader(response.headers, this.configuration.basePath);
|
|
80
|
+
if (Array.isArray(data)) {
|
|
67
81
|
results = results.concat(data);
|
|
68
|
-
nextUrl =
|
|
82
|
+
apiResponse.nextUrl = nextUrl;
|
|
69
83
|
}
|
|
70
84
|
else {
|
|
71
85
|
apiResponse.body = data;
|
|
72
86
|
}
|
|
73
|
-
} while (
|
|
74
|
-
if (
|
|
87
|
+
} while (fetchAll && nextUrl);
|
|
88
|
+
if (results.length > 0) {
|
|
75
89
|
apiResponse.body = results;
|
|
90
|
+
apiResponse.totalCount = getTotalCountFromHeader(apiResponse.headers);
|
|
76
91
|
}
|
|
77
92
|
if (Array.isArray(apiResponse.body)) {
|
|
78
93
|
apiResponse.body.forEach(this.sanitizeResponse.bind(this));
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
export const FilterValueSchema = z.object({
|
|
9
|
-
type: z.enum([
|
|
9
|
+
type: z.enum(["eq", "ne", "empty"]),
|
|
10
10
|
value: z.union([z.string(), z.boolean(), z.number()]),
|
|
11
11
|
});
|
|
12
12
|
export const FilterObjectSchema = z.record(z.array(FilterValueSchema));
|
|
@@ -18,7 +18,7 @@ export const FilterObjectSchema = z.record(z.array(FilterValueSchema));
|
|
|
18
18
|
*/
|
|
19
19
|
export function equals(value) {
|
|
20
20
|
return {
|
|
21
|
-
type:
|
|
21
|
+
type: "eq",
|
|
22
22
|
value,
|
|
23
23
|
};
|
|
24
24
|
}
|
|
@@ -30,7 +30,7 @@ export function equals(value) {
|
|
|
30
30
|
*/
|
|
31
31
|
export function notEquals(value) {
|
|
32
32
|
return {
|
|
33
|
-
type:
|
|
33
|
+
type: "ne",
|
|
34
34
|
value,
|
|
35
35
|
};
|
|
36
36
|
}
|
|
@@ -42,7 +42,7 @@ export function notEquals(value) {
|
|
|
42
42
|
*/
|
|
43
43
|
export function empty(isEmpty) {
|
|
44
44
|
return {
|
|
45
|
-
type:
|
|
45
|
+
type: "empty",
|
|
46
46
|
value: isEmpty.toString(),
|
|
47
47
|
};
|
|
48
48
|
}
|
|
@@ -55,7 +55,7 @@ export function empty(isEmpty) {
|
|
|
55
55
|
*/
|
|
56
56
|
export function relativeTime(value, unit) {
|
|
57
57
|
return {
|
|
58
|
-
type:
|
|
58
|
+
type: "eq",
|
|
59
59
|
value: `${value}${unit}`,
|
|
60
60
|
};
|
|
61
61
|
}
|
|
@@ -67,7 +67,7 @@ export function relativeTime(value, unit) {
|
|
|
67
67
|
*/
|
|
68
68
|
export function isoTime(date) {
|
|
69
69
|
return {
|
|
70
|
-
type:
|
|
70
|
+
type: "eq",
|
|
71
71
|
value: date.toISOString(),
|
|
72
72
|
};
|
|
73
73
|
}
|
|
@@ -128,8 +128,8 @@ export function addFilter(filters, field, filterValue) {
|
|
|
128
128
|
* @returns The updated FilterObject for chaining
|
|
129
129
|
*/
|
|
130
130
|
export function addTimeRange(filters, since, before) {
|
|
131
|
-
addFilter(filters,
|
|
132
|
-
addFilter(filters,
|
|
131
|
+
addFilter(filters, "event.since", isoTime(since));
|
|
132
|
+
addFilter(filters, "event.before", isoTime(before));
|
|
133
133
|
return filters;
|
|
134
134
|
}
|
|
135
135
|
/**
|
|
@@ -141,7 +141,7 @@ export function addTimeRange(filters, since, before) {
|
|
|
141
141
|
* @returns The updated FilterObject for chaining
|
|
142
142
|
*/
|
|
143
143
|
export function addRelativeTimeRange(filters, amount, unit) {
|
|
144
|
-
addFilter(filters,
|
|
144
|
+
addFilter(filters, "event.since", relativeTime(amount, unit));
|
|
145
145
|
return filters;
|
|
146
146
|
}
|
|
147
147
|
/**
|