UNPKG

@brianveltman/sonatype-mcp

Version:

Model Context Protocol server for Sonatype Nexus Repository Manager

158 lines 5.29 kB
import axios from 'axios'; import { createAuthHeaders, validateCredentials } from '../utils/auth.js'; import { handleNexusError, AuthenticationError } from '../utils/errors.js'; export class NexusClient { client; config; constructor(config) { this.config = config; const headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' }; if (validateCredentials(config)) { Object.assign(headers, createAuthHeaders(config)); } this.client = axios.create({ baseURL: config.nexus.baseUrl, timeout: config.nexus.timeout, headers, validateStatus: () => true, ...(config.nexus.validateSsl === false && { httpsAgent: new (require('https').Agent)({ rejectUnauthorized: false }) }) }); this.client.interceptors.request.use((config) => { console.error(`Making request to: ${config.method?.toUpperCase()} ${config.url}`); return config; }, (error) => { console.error('Request interceptor error:', error); return Promise.reject(error); }); this.client.interceptors.response.use((response) => { console.error(`Response: ${response.status} ${response.statusText}`); return response; }, (error) => { console.error('Response interceptor error:', error); return Promise.reject(error); }); } hasCredentials() { return validateCredentials(this.config); } ensureCredentials() { if (!this.hasCredentials()) { throw new AuthenticationError('Nexus credentials not configured. Please set NEXUS_USERNAME and NEXUS_PASSWORD environment variables.'); } } async testConnection() { try { const response = await this.client.get('/service/rest/v1/status/check'); return response.status === 200; } catch (error) { console.error('Connection test failed:', error); return false; } } async get(endpoint, options = {}) { try { if (!endpoint.includes('/status/check') && !endpoint.includes('/status/writable')) { this.ensureCredentials(); } const headers = { ...options.headers }; if (this.hasCredentials()) { Object.assign(headers, createAuthHeaders(this.config)); } const response = await this.client.get(endpoint, { ...options, headers }); if (response.status >= 400) { throw { response }; } return response.data; } catch (error) { handleNexusError(error); } } async post(endpoint, data, options = {}) { if (this.config.server.readOnly) { throw new AuthenticationError('Write operations are disabled in read-only mode'); } this.ensureCredentials(); try { const response = await this.client.post(endpoint, data, { ...options, headers: { ...createAuthHeaders(this.config), ...options.headers } }); if (response.status >= 400) { throw { response }; } return response.data; } catch (error) { handleNexusError(error); } } async put(endpoint, data, options = {}) { if (this.config.server.readOnly) { throw new AuthenticationError('Write operations are disabled in read-only mode'); } this.ensureCredentials(); try { const response = await this.client.put(endpoint, data, { ...options, headers: { ...createAuthHeaders(this.config), ...options.headers } }); if (response.status >= 400) { throw { response }; } return response.data; } catch (error) { handleNexusError(error); } } async delete(endpoint, options = {}) { if (this.config.server.readOnly) { throw new AuthenticationError('Write operations are disabled in read-only mode'); } this.ensureCredentials(); try { const response = await this.client.delete(endpoint, { ...options, headers: { ...createAuthHeaders(this.config), ...options.headers } }); if (response.status >= 400) { throw { response }; } return response.data; } catch (error) { handleNexusError(error); } } async getServerInfo() { return this.get('/service/rest/v1/status'); } isReadOnly() { return this.config.server.readOnly; } getBaseUrl() { return this.config.nexus.baseUrl; } } //# sourceMappingURL=nexus-client.js.map