deepsource-mcp-server
Version:
Model Context Protocol server for DeepSource
142 lines • 5.38 kB
JavaScript
/**
* @fileoverview Base client for interacting with the DeepSource API
* This module provides a base client class with core functionality.
*/
import axios from 'axios';
import { createLogger } from '../utils/logging/logger.js';
import { handleApiError } from '../utils/errors/handlers.js';
/**
* Default configuration for the DeepSource client
* @private
*/
const DEFAULT_CONFIG = {
baseURL: 'https://api.deepsource.io/graphql/',
timeout: 30000,
};
/**
* Base client for DeepSource API with core HTTP functionality
* @class
* @public
*/
export class BaseDeepSourceClient {
/**
* HTTP client for making API requests to DeepSource
* @protected
*/
client;
/**
* Logger instance for the client
* @protected
*/
logger = createLogger('DeepSourceClient');
/**
* Creates a new BaseDeepSourceClient instance
* @param apiKey - The DeepSource API key for authentication
* @param config - Optional configuration options
* @throws {Error} When apiKey is not provided
* @public
*/
constructor(apiKey, config = {}) {
if (!apiKey) {
throw new Error('DeepSource API key is required');
}
// Merge default config with provided config
const mergedConfig = {
...DEFAULT_CONFIG,
...config,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiKey}`,
...config.headers,
},
};
this.client = axios.create(mergedConfig);
}
/**
* Execute a GraphQL query against the DeepSource API
* @param query The GraphQL query to execute
* @returns The query response data
* @throws {ClassifiedError} When the query fails
* @protected
*/
async executeGraphQL(query) {
try {
// Log full query for debugging
this.logger.debug('Executing GraphQL query', {
query,
queryLength: query.length,
requestHeaders: this.client.defaults.headers,
});
// Execute the query
const startTime = Date.now();
const response = await this.client.post('', { query });
const duration = Date.now() - startTime;
this.logger.debug('GraphQL response received', {
status: response.status,
statusText: response.statusText,
duration: `${duration}ms`,
dataSize: JSON.stringify(response.data).length,
hasData: Boolean(response.data?.data),
hasErrors: Boolean(response.data?.errors),
});
// Check for GraphQL errors in the response
if (response.data.errors) {
this.logger.error('GraphQL query returned errors', {
errors: response.data.errors,
query: query.substring(0, 100) + (query.length > 100 ? '...' : ''),
});
throw new Error(`GraphQL Errors: ${JSON.stringify(response.data.errors)}`);
}
return response.data;
}
catch (error) {
// Log detailed error information
this.logger.error('Error executing GraphQL query', {
errorType: typeof error,
errorName: error instanceof Error ? error.name : 'Unknown error type',
errorMessage: error instanceof Error ? error.message : String(error),
errorResponse: error?.response
? {
status: error.response.status,
statusText: error.response.statusText,
data: error.response.data,
}
: 'No response data available',
query: query.substring(0, 100) + (query.length > 100 ? '...' : ''),
});
// Handle the error properly
const handledError = handleApiError(error);
this.logger.debug('Handled API error', {
originalMessage: error instanceof Error ? error.message : String(error),
handledMessage: handledError.message,
handledName: handledError.name,
});
throw handledError;
}
}
/**
* Execute a GraphQL mutation against the DeepSource API
* @param mutation The GraphQL mutation to execute
* @returns The mutation response data
* @throws {ClassifiedError} When the mutation fails
* @protected
*/
async executeGraphQLMutation(mutation) {
try {
this.logger.debug('Executing GraphQL mutation', { mutation });
const response = await this.client.post('', { query: mutation });
// Check for GraphQL errors in the response
if (response.data.errors) {
this.logger.error('GraphQL mutation returned errors', response.data.errors);
throw new Error(`GraphQL Errors: ${JSON.stringify(response.data.errors)}`);
}
return response.data;
}
catch (error) {
this.logger.error('Error executing GraphQL mutation', error);
throw handleApiError(error);
}
}
}
//# sourceMappingURL=base-client.js.map