trello-mcp-server

by v4lheru
Verified
/** * Trello Service * * Main service class for interacting with the Trello API. * Provides authentication and common functionality for all Trello resources. */ import { BaseService } from './base-service.js'; import config from '../config.js'; /** * Service for interacting with the Trello API */ export class TrelloService extends BaseService { private static instance: TrelloService; private apiKey: string; private token: string; /** * Private constructor to enforce singleton pattern * @param apiKey - Trello API key * @param token - Trello API token */ private constructor(apiKey: string, token: string) { super( 'https://api.trello.com/1', { 'Content-Type': 'application/json', 'Accept': 'application/json' } ); this.apiKey = apiKey; this.token = token; } /** * Initializes the TrelloService singleton instance * @param apiKey - Trello API key * @param token - Trello API token * @returns The singleton instance of TrelloService */ public static initialize(apiKey: string, token: string): TrelloService { if (!TrelloService.instance) { TrelloService.instance = new TrelloService(apiKey, token); } return TrelloService.instance; } /** * Gets the singleton instance of TrelloService * @returns The singleton instance of TrelloService * @throws Error if service hasn't been initialized */ public static getInstance(): TrelloService { if (!TrelloService.instance) { throw new Error('TrelloService not initialized. Call initialize() first.'); } return TrelloService.instance; } /** * Adds authentication parameters to a URL * @param url - The URL to add authentication to * @returns The URL with authentication parameters */ protected addAuth(url: string): string { const separator = url.includes('?') ? '&' : '?'; return `${url}${separator}key=${this.apiKey}&token=${this.token}`; } /** * Makes a GET request to the Trello API * @param endpoint - The API endpoint to call * @param params - Query parameters to include * @returns Promise resolving to the response data */ async get<T>(endpoint: string, params: Record<string, any> = {}): Promise<T> { return this.makeRequest(async () => { const queryParams = new URLSearchParams(); // Add all params to the query string for (const [key, value] of Object.entries(params)) { if (value !== undefined && value !== null) { if (Array.isArray(value)) { queryParams.append(key, value.join(',')); } else { queryParams.append(key, String(value)); } } } const queryString = queryParams.toString(); const url = this.addAuth(`${endpoint}${queryString ? `?${queryString}` : ''}`); const response = await this.client.get(url); return response.data; }); } /** * Makes a POST request to the Trello API * @param endpoint - The API endpoint to call * @param data - The data to send in the request body * @param params - Additional query parameters * @returns Promise resolving to the response data */ async post<T>(endpoint: string, data: any = {}, params: Record<string, any> = {}): Promise<T> { return this.makeRequest(async () => { const queryParams = new URLSearchParams(); // Add all params to the query string for (const [key, value] of Object.entries(params)) { if (value !== undefined && value !== null) { if (Array.isArray(value)) { queryParams.append(key, value.join(',')); } else { queryParams.append(key, String(value)); } } } const queryString = queryParams.toString(); const url = this.addAuth(`${endpoint}${queryString ? `?${queryString}` : ''}`); const response = await this.client.post(url, data); return response.data; }); } /** * Makes a PUT request to the Trello API * @param endpoint - The API endpoint to call * @param data - The data to send in the request body * @param params - Additional query parameters * @returns Promise resolving to the response data */ async put<T>(endpoint: string, data: any = {}, params: Record<string, any> = {}): Promise<T> { return this.makeRequest(async () => { const queryParams = new URLSearchParams(); // Add all params to the query string for (const [key, value] of Object.entries(params)) { if (value !== undefined && value !== null) { if (Array.isArray(value)) { queryParams.append(key, value.join(',')); } else { queryParams.append(key, String(value)); } } } const queryString = queryParams.toString(); const url = this.addAuth(`${endpoint}${queryString ? `?${queryString}` : ''}`); const response = await this.client.put(url, data); return response.data; }); } /** * Makes a DELETE request to the Trello API * @param endpoint - The API endpoint to call * @param params - Query parameters to include * @returns Promise resolving to the response data */ async delete<T>(endpoint: string, params: Record<string, any> = {}): Promise<T> { return this.makeRequest(async () => { const queryParams = new URLSearchParams(); // Add all params to the query string for (const [key, value] of Object.entries(params)) { if (value !== undefined && value !== null) { if (Array.isArray(value)) { queryParams.append(key, value.join(',')); } else { queryParams.append(key, String(value)); } } } const queryString = queryParams.toString(); const url = this.addAuth(`${endpoint}${queryString ? `?${queryString}` : ''}`); const response = await this.client.delete(url); return response.data; }); } /** * Creates a URL with query parameters for the Trello API * @param endpoint - The API endpoint * @param params - Query parameters to include * @returns The URL with query parameters */ protected createUrl(endpoint: string, params: Record<string, any> = {}): string { const queryParams = new URLSearchParams(); // Add all params to the query string for (const [key, value] of Object.entries(params)) { if (value !== undefined && value !== null) { if (Array.isArray(value)) { queryParams.append(key, value.join(',')); } else { queryParams.append(key, String(value)); } } } const queryString = queryParams.toString(); return this.addAuth(`${endpoint}${queryString ? `?${queryString}` : ''}`); } }