UNPKG

@chargetrip/mcp

Version:

Chargetrip MCP server

149 lines (132 loc) 4.21 kB
import { Client, createClient, fetchExchange, OperationResult, subscriptionExchange, } from '@urql/core'; import fetch from 'cross-fetch'; import { gql } from 'graphql-tag'; import { createClient as wsCreateClient } from 'graphql-ws'; import WebSocket from 'ws'; export class GraphQLClient { /** * @description GraphQL client instance for making requests to the GraphQL API. */ private client: Client; /** * @description The unique id of each request */ private key = 1; /** * @description Singleton instances for the GraphQLClient. */ protected static instance: GraphQLClient = new GraphQLClient(); constructor() { const graphqlEndpoint = process.env.GRAPHQL_ENDPOINT ?? 'https://api.chargetrip.io/graphql'; const graphqlWsEndpoint = process.env.GRAPHQL_WS_ENDPOINT ?? 'wss://api.chargetrip.io/subscription'; const headers: Record<string, string> = { 'x-client-id': process.env.CLIENT_ID!, 'x-app-id': process.env.APP_ID!, }; if (process.env.APP_IDENTIFIER !== undefined) { headers['x-app-identifier'] = process.env.APP_IDENTIFIER!; } if (process.env.APP_FINGERPRINT !== undefined) { headers['x-app-fingerprint'] = process.env.APP_FINGERPRINT!; } const wsClient = wsCreateClient({ url: graphqlWsEndpoint, webSocketImpl: WebSocket, lazy: true, keepAlive: 5000, connectionParams: headers, shouldRetry: () => true, }); this.client = createClient({ url: graphqlEndpoint, requestPolicy: 'network-only', preferGetMethod: false, fetch, fetchOptions: () => ({ headers, cache: 'no-cache', method: 'POST' }), exchanges: [ fetchExchange, subscriptionExchange({ forwardSubscription(request) { const input = { ...request, query: request.query ?? '' }; return { subscribe(sink) { const unsubscribe = wsClient.subscribe(input, sink); return { unsubscribe }; }, }; }, }), ], }); } /** * @description Singleton instance getter for GraphQLClient. * * @returns {GraphQLClient} The singleton instance of GraphQLClient. */ public static getInstance(): GraphQLClient { return GraphQLClient.instance; } /** * @description Executes a GraphQL query. * * @param {string} query The GraphQL query string to execute. * @param {Record<string, any>} [variables] Optional variables for the query. * @returns {Promise<OperationResult<T>>} A promise that resolves to the result of the query. */ async query<T>(query: string, variables?: Record<string, any>): Promise<OperationResult<T>> { const parsedQuery = gql` ${query} `; return this.client .executeQuery<T>({ key: this.key++, query: parsedQuery, variables, }) .toPromise(); } /** * @description Executes a GraphQL mutation. * * @param {string} mutation The GraphQL mutation string to execute. * @param {Record<string, any>} [variables] Optional variables for the mutation. * @returns {Promise<OperationResult<T>>} A promise that resolves to the result of the mutation. */ async mutate<T>(mutation: string, variables?: Record<string, any>): Promise<OperationResult<T>> { const parsedMutation = gql` ${mutation} `; return this.client .executeMutation<T>({ key: this.key++, query: parsedMutation, variables, }) .toPromise(); } /** * @description Executes a GraphQL subscription. * * @param {string} subscription The GraphQL subscription string to execute. * @param {Record<string, any>} [variables] Optional variables for the subscription. * @returns {Observable<OperationResult<T>>} An observable that emits the results of the subscription. */ subscription<T>(subscription: string, variables?: Record<string, any>) { const parsedSubscription = gql` ${subscription} `; return this.client.executeSubscription<T>({ key: this.key++, query: parsedSubscription, variables, }); } }