import { DattoRMMConfig, DattoRMMDevice, DattoRMMSite, DattoRMMApiResponse, DattoRMMError, } from '@/lib/types/datto-rmm'; export class DattoRMMClientSimple { private config: DattoRMMConfig; constructor(config: DattoRMMConfig) { this.config = config; } /** * Make an API request using Basic authentication directly */ private async makeApiCall( endpoint: string, options: RequestInit = {} ): Promise { // Create Basic auth header using API key and secret const credentials = Buffer.from(`${this.config.apiKey}:${this.config.apiSecret}`).toString('base64'); // Use the base URL directly with v2 API const url = `https://concord-api.centrastage.net/api/v2${endpoint}`; console.log(`Making API call to: ${url}`); const response = await fetch(url, { ...options, headers: { 'Authorization': `Basic ${credentials}`, 'Content-Type': 'application/json', 'Accept': 'application/json', ...options.headers, }, }); if (!response.ok) { const errorText = await response.text(); let errorMessage = `API Error: ${response.status}`; try { const errorData = JSON.parse(errorText) as DattoRMMError; errorMessage = `${errorData.error}: ${errorData.message}`; } catch { errorMessage += ` - ${errorText}`; } console.error('API call failed:', errorMessage); throw new Error(errorMessage); } const responseText = await response.text(); if (!responseText) { return {} as T; } try { return JSON.parse(responseText) as T; } catch (error) { console.error('Failed to parse response:', responseText); throw new Error('Invalid JSON response from API'); } } /** * Get all sites */ async getSites(): Promise { const response = await this.makeApiCall>( '/sites', { method: 'GET' } ); return response.items || []; } /** * Get site by name (for matching with Autotask company) */ async getSiteByName(name: string): Promise { const sites = await this.getSites(); const site = sites.find(s => s.name.toLowerCase() === name.toLowerCase() || s.name.toLowerCase().includes(name.toLowerCase()) ); return site || null; } /** * Get all devices */ async getAllDevices(): Promise { const response = await this.makeApiCall>( '/devices', { method: 'GET' } ); return response.items || []; } /** * Get devices for a specific site */ async getDevicesBySite(siteId: string): Promise { const response = await this.makeApiCall>( `/sites/${siteId}/devices`, { method: 'GET' } ); return response.items || []; } /** * Get devices by site name (matches with company name) */ async getDevicesByCompanyName(companyName: string): Promise { // First, find the site that matches the company name const site = await this.getSiteByName(companyName); if (!site) { console.warn(`No RMM site found for company: ${companyName}`); return []; } // Then get devices for that site return this.getDevicesBySite(site.id); } }