Add mcp-gateway/wave-mcp/src/services/wave-client.ts
This commit is contained in:
parent
0adecf4ab0
commit
d3db917469
1 changed files with 62 additions and 0 deletions
62
mcp-gateway/wave-mcp/src/services/wave-client.ts
Normal file
62
mcp-gateway/wave-mcp/src/services/wave-client.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { WaveConfig, GraphQLResponse } from "../types.js";
|
||||||
|
import { WAVE_GRAPHQL_URL, CHARACTER_LIMIT } from "../constants.js";
|
||||||
|
|
||||||
|
export class WaveClient {
|
||||||
|
private accessToken: string;
|
||||||
|
|
||||||
|
constructor(config: WaveConfig) {
|
||||||
|
this.accessToken = config.accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Core GraphQL executor ──────────────────────────────────────────────────
|
||||||
|
|
||||||
|
async query<T = unknown>(
|
||||||
|
query: string,
|
||||||
|
variables?: Record<string, unknown>
|
||||||
|
): Promise<T> {
|
||||||
|
const response = await fetch(WAVE_GRAPHQL_URL, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${this.accessToken}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Accept: "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ query, variables: variables ?? {} }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const text = await response.text().catch(() => "(no body)");
|
||||||
|
throw new Error(
|
||||||
|
`Wave API HTTP error ${response.status} ${response.statusText}: ${text.slice(0, 300)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const json = (await response.json()) as GraphQLResponse<T>;
|
||||||
|
|
||||||
|
if (json.errors?.length) {
|
||||||
|
const messages = json.errors.map((e) => e.message).join("; ");
|
||||||
|
throw new Error(`Wave GraphQL error: ${messages}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json.data === undefined) {
|
||||||
|
throw new Error("Wave API returned no data and no errors.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Formatting helpers ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/** Truncate a JSON response string if it exceeds CHARACTER_LIMIT */
|
||||||
|
static truncate(text: string): string {
|
||||||
|
if (text.length <= CHARACTER_LIMIT) return text;
|
||||||
|
return (
|
||||||
|
text.slice(0, CHARACTER_LIMIT) +
|
||||||
|
`\n\n...[TRUNCATED: response exceeded ${CHARACTER_LIMIT} characters. Use pagination (page, pageSize) to retrieve more data.]`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static formatCurrency(value: number, code: string): string {
|
||||||
|
return `${code} ${value.toFixed(2)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue