@smartbear/mcp 0.12.1 → 0.13.2
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 +30 -6
- package/dist/bugsnag/client/api/CurrentUser.js +50 -26
- package/dist/bugsnag/client/api/Error.js +156 -93
- package/dist/bugsnag/client/api/Project.js +398 -276
- package/dist/bugsnag/client/api/api.js +4087 -3837
- package/dist/bugsnag/client/api/base.js +155 -173
- package/dist/bugsnag/client/api/configuration.js +28 -25
- package/dist/bugsnag/client/filters.js +11 -20
- package/dist/bugsnag/client.js +1398 -1281
- package/dist/bugsnag/input-schemas.js +39 -57
- package/dist/collaborator/client.js +335 -371
- package/dist/common/bugsnag.js +5 -3
- package/dist/common/cache.js +50 -57
- package/dist/common/client-registry.js +106 -119
- package/dist/common/info.js +7 -3
- package/dist/common/register-clients.js +0 -16
- package/dist/common/server.js +270 -228
- package/dist/common/tools.js +19 -0
- package/dist/common/transport-http.js +252 -343
- package/dist/common/transport-stdio.js +40 -37
- package/dist/common/zod-utils.js +20 -0
- package/dist/index.js +18 -23
- package/dist/package.json.js +11 -0
- package/dist/pactflow/client/ai.js +142 -169
- package/dist/pactflow/client/base.js +41 -51
- package/dist/pactflow/client/prompt-utils.js +93 -84
- package/dist/pactflow/client/prompts.js +95 -92
- package/dist/pactflow/client/tools.js +94 -83
- package/dist/pactflow/client/utils.js +60 -64
- package/dist/pactflow/client.js +399 -320
- package/dist/qmetry/client/api/client-api.js +43 -41
- package/dist/qmetry/client/api/error-handler.js +264 -310
- package/dist/qmetry/client/auto-resolve.js +78 -99
- package/dist/qmetry/client/automation.js +139 -162
- package/dist/qmetry/client/handlers.js +49 -46
- package/dist/qmetry/client/issues.js +133 -115
- package/dist/qmetry/client/project.js +153 -174
- package/dist/qmetry/client/requirement.js +82 -70
- package/dist/qmetry/client/testcase.js +240 -208
- package/dist/qmetry/client/testsuite.js +332 -293
- package/dist/qmetry/client/tools/automation-tools.js +291 -288
- package/dist/qmetry/client/tools/index.js +16 -13
- package/dist/qmetry/client/tools/issue-tools.js +534 -543
- package/dist/qmetry/client/tools/project-tools.js +635 -656
- package/dist/qmetry/client/tools/requirement-tools.js +525 -528
- package/dist/qmetry/client/tools/testcase-tools.js +773 -786
- package/dist/qmetry/client/tools/testsuite-tools.js +1069 -1083
- package/dist/qmetry/client/utils.js +8 -14
- package/dist/qmetry/client.js +111 -109
- package/dist/qmetry/config/constants.js +48 -44
- package/dist/qmetry/config/rest-endpoints.js +51 -48
- package/dist/qmetry/types/automation.js +7 -7
- package/dist/qmetry/types/common.js +763 -1049
- package/dist/qmetry/types/issues.js +26 -19
- package/dist/qmetry/types/project.js +32 -25
- package/dist/qmetry/types/requirements.js +26 -21
- package/dist/qmetry/types/testcase.js +55 -44
- package/dist/qmetry/types/testsuite.js +66 -52
- package/dist/reflect/client.js +284 -226
- package/dist/swagger/client/api.js +645 -662
- package/dist/swagger/client/configuration.js +31 -33
- package/dist/swagger/client/portal-types.js +204 -244
- package/dist/swagger/client/registry-types.js +62 -96
- package/dist/swagger/client/tools.js +148 -158
- package/dist/swagger/client/user-management-types.js +11 -22
- package/dist/swagger/client.js +143 -135
- package/dist/swagger/config-utils.js +10 -16
- package/dist/zephyr/client.js +43 -42
- package/dist/zephyr/common/api-client.js +35 -30
- package/dist/zephyr/common/auth-service.js +16 -13
- package/dist/zephyr/common/rest-api-schemas.js +3173 -5146
- package/dist/zephyr/tool/environment/get-environments.js +66 -66
- package/dist/zephyr/tool/priority/get-priorities.js +41 -41
- package/dist/zephyr/tool/project/get-project.js +37 -37
- package/dist/zephyr/tool/project/get-projects.js +46 -46
- package/dist/zephyr/tool/status/get-statuses.js +47 -47
- package/dist/zephyr/tool/test-case/get-test-case.js +37 -37
- package/dist/zephyr/tool/test-case/get-test-cases.js +62 -62
- package/dist/zephyr/tool/test-cycle/get-test-cycle.js +37 -37
- package/dist/zephyr/tool/test-cycle/get-test-cycles.js +70 -70
- package/dist/zephyr/tool/test-execution/get-test-execution.js +37 -37
- package/dist/zephyr/tool/test-execution/get-test-executions.js +43 -43
- package/package.json +5 -5
- package/dist/bugsnag/client/api/index.js +0 -6
- package/dist/common/types.js +0 -6
- package/dist/qmetry/client/tools/types.js +0 -1
- package/dist/swagger/client/index.js +0 -6
- package/dist/tests/unit/bugsnag/utils/factories.js +0 -86
- package/dist/zephyr/tool/zephyr-tool.js +0 -1
package/dist/reflect/client.js
CHANGED
|
@@ -1,232 +1,290 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { MCP_SERVER_NAME, MCP_SERVER_VERSION } from "../common/info.js";
|
|
3
|
-
import { ToolError
|
|
3
|
+
import { ToolError } from "../common/tools.js";
|
|
4
4
|
const ConfigurationSchema = z.object({
|
|
5
|
-
|
|
5
|
+
api_token: z.string().describe("Reflect API authentication token")
|
|
6
6
|
});
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
class ReflectClient {
|
|
8
|
+
headers = {};
|
|
9
|
+
name = "Reflect";
|
|
10
|
+
toolPrefix = "reflect";
|
|
11
|
+
configPrefix = "Reflect";
|
|
12
|
+
config = ConfigurationSchema;
|
|
13
|
+
async configure(_server, config, _cache) {
|
|
14
|
+
this.headers = {
|
|
15
|
+
"X-API-KEY": `${config.api_token}`,
|
|
16
|
+
"Content-Type": "application/json",
|
|
17
|
+
"User-Agent": `${MCP_SERVER_NAME}/${MCP_SERVER_VERSION}`
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
isConfigured() {
|
|
21
|
+
return Object.keys(this.headers).length !== 0;
|
|
22
|
+
}
|
|
23
|
+
async listReflectSuites() {
|
|
24
|
+
const response = await fetch("https://api.reflect.run/v1/suites", {
|
|
25
|
+
method: "GET",
|
|
26
|
+
headers: this.headers
|
|
27
|
+
});
|
|
28
|
+
return response.json();
|
|
29
|
+
}
|
|
30
|
+
async listSuiteExecutions(suiteId) {
|
|
31
|
+
const response = await fetch(
|
|
32
|
+
`https://api.reflect.run/v1/suites/${suiteId}/executions`,
|
|
33
|
+
{
|
|
34
|
+
method: "GET",
|
|
35
|
+
headers: this.headers
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
return response.json();
|
|
39
|
+
}
|
|
40
|
+
async getSuiteExecutionStatus(suiteId, executionId) {
|
|
41
|
+
const response = await fetch(
|
|
42
|
+
`https://api.reflect.run/v1/suites/${suiteId}/executions/${executionId}`,
|
|
43
|
+
{
|
|
44
|
+
method: "GET",
|
|
45
|
+
headers: this.headers
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
return response.json();
|
|
49
|
+
}
|
|
50
|
+
async executeSuite(suiteId) {
|
|
51
|
+
const response = await fetch(
|
|
52
|
+
`https://api.reflect.run/v1/suites/${suiteId}/executions`,
|
|
53
|
+
{
|
|
54
|
+
method: "POST",
|
|
55
|
+
headers: this.headers
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
return response.json();
|
|
59
|
+
}
|
|
60
|
+
async cancelSuiteExecution(suiteId, executionId) {
|
|
61
|
+
const response = await fetch(
|
|
62
|
+
`https://api.reflect.run/v1/suites/${suiteId}/executions/${executionId}/cancel`,
|
|
63
|
+
{
|
|
64
|
+
method: "PATCH",
|
|
65
|
+
headers: this.headers
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
return response.json();
|
|
69
|
+
}
|
|
70
|
+
async listReflectTests() {
|
|
71
|
+
const response = await fetch("https://api.reflect.run/v1/tests", {
|
|
72
|
+
method: "GET",
|
|
73
|
+
headers: this.headers
|
|
74
|
+
});
|
|
75
|
+
return response.json();
|
|
76
|
+
}
|
|
77
|
+
async runReflectTest(testId) {
|
|
78
|
+
const response = await fetch(
|
|
79
|
+
`https://api.reflect.run/v1/tests/${testId}/executions`,
|
|
80
|
+
{
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers: this.headers
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
return response.json();
|
|
86
|
+
}
|
|
87
|
+
async getReflectTestStatus(_testId, executionId) {
|
|
88
|
+
const response = await fetch(
|
|
89
|
+
`https://api.reflect.run/v1/executions/${executionId}`,
|
|
90
|
+
{
|
|
91
|
+
method: "GET",
|
|
92
|
+
headers: this.headers
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
return response.json();
|
|
96
|
+
}
|
|
97
|
+
async registerTools(register, _getInput) {
|
|
98
|
+
register(
|
|
99
|
+
{
|
|
100
|
+
title: "List Suites",
|
|
101
|
+
summary: "Retrieve a list of all reflect suites available",
|
|
102
|
+
parameters: []
|
|
103
|
+
},
|
|
104
|
+
async (_args, _extra) => {
|
|
105
|
+
const response = await this.listReflectSuites();
|
|
106
|
+
return {
|
|
107
|
+
content: [{ type: "text", text: JSON.stringify(response) }]
|
|
19
108
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const response = await
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}, async (args, _extra) => {
|
|
199
|
-
if (!args.testId)
|
|
200
|
-
throw new ToolError("testId argument is required");
|
|
201
|
-
const response = await this.runReflectTest(args.testId);
|
|
202
|
-
return {
|
|
203
|
-
content: [{ type: "text", text: JSON.stringify(response) }],
|
|
204
|
-
};
|
|
205
|
-
});
|
|
206
|
-
register({
|
|
207
|
-
title: "Get Test Status",
|
|
208
|
-
summary: "Get the status of a reflect test execution",
|
|
209
|
-
parameters: [
|
|
210
|
-
{
|
|
211
|
-
name: "testId",
|
|
212
|
-
type: z.string(),
|
|
213
|
-
description: "ID of the reflect test to run",
|
|
214
|
-
required: true,
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
name: "executionId",
|
|
218
|
-
type: z.string(),
|
|
219
|
-
description: "ID of the reflect test execution to get status for",
|
|
220
|
-
required: true,
|
|
221
|
-
},
|
|
222
|
-
],
|
|
223
|
-
}, async (args, _extra) => {
|
|
224
|
-
if (!args.testId || !args.executionId)
|
|
225
|
-
throw new ToolError("Both testId and executionId arguments are required");
|
|
226
|
-
const response = await this.getReflectTestStatus(args.testId, args.executionId);
|
|
227
|
-
return {
|
|
228
|
-
content: [{ type: "text", text: JSON.stringify(response) }],
|
|
229
|
-
};
|
|
230
|
-
});
|
|
231
|
-
}
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
register(
|
|
112
|
+
{
|
|
113
|
+
title: "List Suite Executions",
|
|
114
|
+
summary: "List all executions for a given suite",
|
|
115
|
+
parameters: [
|
|
116
|
+
{
|
|
117
|
+
name: "suiteId",
|
|
118
|
+
type: z.string(),
|
|
119
|
+
description: "ID of the reflect suite to list executions for",
|
|
120
|
+
required: true
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
async (args, _extra) => {
|
|
125
|
+
if (!args.suiteId) throw new ToolError("suiteId argument is required");
|
|
126
|
+
const response = await this.listSuiteExecutions(args.suiteId);
|
|
127
|
+
return {
|
|
128
|
+
content: [{ type: "text", text: JSON.stringify(response) }]
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
register(
|
|
133
|
+
{
|
|
134
|
+
title: "Get Suite Execution Status",
|
|
135
|
+
summary: "Get the status of a reflect suite execution",
|
|
136
|
+
parameters: [
|
|
137
|
+
{
|
|
138
|
+
name: "suiteId",
|
|
139
|
+
type: z.string(),
|
|
140
|
+
description: "ID of the reflect suite to get execution status for",
|
|
141
|
+
required: true
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: "executionId",
|
|
145
|
+
type: z.string(),
|
|
146
|
+
description: "ID of the reflect suite execution to get status for",
|
|
147
|
+
required: true
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
},
|
|
151
|
+
async (args, _extra) => {
|
|
152
|
+
if (!args.suiteId || !args.executionId)
|
|
153
|
+
throw new ToolError(
|
|
154
|
+
"Both suiteId and executionId arguments are required"
|
|
155
|
+
);
|
|
156
|
+
const response = await this.getSuiteExecutionStatus(
|
|
157
|
+
args.suiteId,
|
|
158
|
+
args.executionId
|
|
159
|
+
);
|
|
160
|
+
return {
|
|
161
|
+
content: [{ type: "text", text: JSON.stringify(response) }]
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
register(
|
|
166
|
+
{
|
|
167
|
+
title: "Execute Suite",
|
|
168
|
+
summary: "Execute a reflect suite",
|
|
169
|
+
parameters: [
|
|
170
|
+
{
|
|
171
|
+
name: "suiteId",
|
|
172
|
+
type: z.string(),
|
|
173
|
+
description: "ID of the reflect suite to list executions for",
|
|
174
|
+
required: true
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
async (args, _extra) => {
|
|
179
|
+
if (!args.suiteId) throw new ToolError("suiteId argument is required");
|
|
180
|
+
const response = await this.executeSuite(args.suiteId);
|
|
181
|
+
return {
|
|
182
|
+
content: [{ type: "text", text: JSON.stringify(response) }]
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
);
|
|
186
|
+
register(
|
|
187
|
+
{
|
|
188
|
+
title: "Cancel Suite Execution",
|
|
189
|
+
summary: "Cancel a reflect suite execution",
|
|
190
|
+
parameters: [
|
|
191
|
+
{
|
|
192
|
+
name: "suiteId",
|
|
193
|
+
type: z.string(),
|
|
194
|
+
description: "ID of the reflect suite to cancel execution for",
|
|
195
|
+
required: true
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: "executionId",
|
|
199
|
+
type: z.string(),
|
|
200
|
+
description: "ID of the reflect suite execution to cancel",
|
|
201
|
+
required: true
|
|
202
|
+
}
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
async (args, _extra) => {
|
|
206
|
+
if (!args.suiteId || !args.executionId)
|
|
207
|
+
throw new ToolError(
|
|
208
|
+
"Both suiteId and executionId arguments are required"
|
|
209
|
+
);
|
|
210
|
+
const response = await this.cancelSuiteExecution(
|
|
211
|
+
args.suiteId,
|
|
212
|
+
args.executionId
|
|
213
|
+
);
|
|
214
|
+
return {
|
|
215
|
+
content: [{ type: "text", text: JSON.stringify(response) }]
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
);
|
|
219
|
+
register(
|
|
220
|
+
{
|
|
221
|
+
title: "List Tests",
|
|
222
|
+
summary: "List all reflect tests",
|
|
223
|
+
parameters: []
|
|
224
|
+
},
|
|
225
|
+
async (_args, _extra) => {
|
|
226
|
+
const response = await this.listReflectTests();
|
|
227
|
+
return {
|
|
228
|
+
content: [{ type: "text", text: JSON.stringify(response) }]
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
);
|
|
232
|
+
register(
|
|
233
|
+
{
|
|
234
|
+
title: "Run Test",
|
|
235
|
+
summary: "Run a reflect test",
|
|
236
|
+
parameters: [
|
|
237
|
+
{
|
|
238
|
+
name: "testId",
|
|
239
|
+
type: z.string(),
|
|
240
|
+
description: "ID of the reflect test to run",
|
|
241
|
+
required: true
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
},
|
|
245
|
+
async (args, _extra) => {
|
|
246
|
+
if (!args.testId) throw new ToolError("testId argument is required");
|
|
247
|
+
const response = await this.runReflectTest(args.testId);
|
|
248
|
+
return {
|
|
249
|
+
content: [{ type: "text", text: JSON.stringify(response) }]
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
);
|
|
253
|
+
register(
|
|
254
|
+
{
|
|
255
|
+
title: "Get Test Status",
|
|
256
|
+
summary: "Get the status of a reflect test execution",
|
|
257
|
+
parameters: [
|
|
258
|
+
{
|
|
259
|
+
name: "testId",
|
|
260
|
+
type: z.string(),
|
|
261
|
+
description: "ID of the reflect test to run",
|
|
262
|
+
required: true
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
name: "executionId",
|
|
266
|
+
type: z.string(),
|
|
267
|
+
description: "ID of the reflect test execution to get status for",
|
|
268
|
+
required: true
|
|
269
|
+
}
|
|
270
|
+
]
|
|
271
|
+
},
|
|
272
|
+
async (args, _extra) => {
|
|
273
|
+
if (!args.testId || !args.executionId)
|
|
274
|
+
throw new ToolError(
|
|
275
|
+
"Both testId and executionId arguments are required"
|
|
276
|
+
);
|
|
277
|
+
const response = await this.getReflectTestStatus(
|
|
278
|
+
args.testId,
|
|
279
|
+
args.executionId
|
|
280
|
+
);
|
|
281
|
+
return {
|
|
282
|
+
content: [{ type: "text", text: JSON.stringify(response) }]
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
);
|
|
286
|
+
}
|
|
232
287
|
}
|
|
288
|
+
export {
|
|
289
|
+
ReflectClient
|
|
290
|
+
};
|