ClickUp MCP Server

by windalfin
Verified
/** * ClickUp Folder Service * * Handles all operations related to folders in ClickUp, including: * - Creating folders * - Retrieving folders * - Updating folders * - Deleting folders * - Finding folders by name */ import { AxiosError } from 'axios'; import { BaseClickUpService, ErrorCode, ClickUpServiceError, ServiceResponse } from './base.js'; import { ClickUpFolder, CreateFolderData } from './types.js'; import { WorkspaceService } from './workspace.js'; export class FolderService extends BaseClickUpService { private workspaceService: WorkspaceService | null = null; /** * Creates an instance of FolderService * @param apiKey - ClickUp API key * @param teamId - ClickUp team ID * @param baseUrl - Optional custom API URL * @param workspaceService - Optional workspace service for lookups */ constructor( apiKey: string, teamId: string, baseUrl?: string, workspaceService?: WorkspaceService ) { super(apiKey, teamId, baseUrl); this.workspaceService = workspaceService || null; } /** * Helper method to handle errors consistently * @param error The error that occurred * @param message Optional custom error message * @returns A ClickUpServiceError */ private handleError(error: any, message?: string): ClickUpServiceError { if (error instanceof ClickUpServiceError) { return error; } return new ClickUpServiceError( message || `Folder service error: ${error.message}`, ErrorCode.UNKNOWN, error ); } /** * Create a new folder in a space * @param spaceId The ID of the space to create the folder in * @param folderData The data for the new folder * @returns The created folder */ async createFolder(spaceId: string, folderData: CreateFolderData): Promise<ClickUpFolder> { try { this.logOperation('createFolder', { spaceId, ...folderData }); const response = await this.client.post<ClickUpFolder>( `/space/${spaceId}/folder`, folderData ); return response.data; } catch (error) { throw this.handleError(error, `Failed to create folder in space ${spaceId}`); } } /** * Get a folder by its ID * @param folderId The ID of the folder to retrieve * @returns The folder details */ async getFolder(folderId: string): Promise<ClickUpFolder> { try { this.logOperation('getFolder', { folderId }); const response = await this.client.get<ClickUpFolder>( `/folder/${folderId}` ); return response.data; } catch (error) { throw this.handleError(error, `Failed to get folder ${folderId}`); } } /** * Update an existing folder * @param folderId The ID of the folder to update * @param updateData The data to update on the folder * @returns The updated folder */ async updateFolder(folderId: string, updateData: Partial<CreateFolderData>): Promise<ClickUpFolder> { try { this.logOperation('updateFolder', { folderId, ...updateData }); const response = await this.client.put<ClickUpFolder>( `/folder/${folderId}`, updateData ); return response.data; } catch (error) { throw this.handleError(error, `Failed to update folder ${folderId}`); } } /** * Delete a folder * @param folderId The ID of the folder to delete * @returns Success indicator */ async deleteFolder(folderId: string): Promise<ServiceResponse<void>> { try { this.logOperation('deleteFolder', { folderId }); await this.client.delete(`/folder/${folderId}`); return { success: true }; } catch (error) { throw this.handleError(error, `Failed to delete folder ${folderId}`); } } /** * Get all folders in a space * @param spaceId The ID of the space to get folders from * @returns Array of folders in the space */ async getFoldersInSpace(spaceId: string): Promise<ClickUpFolder[]> { this.logOperation('getFoldersInSpace', { spaceId }); try { const response = await this.client.get<{ folders: ClickUpFolder[] }>( `/space/${spaceId}/folder` ); return response.data.folders; } catch (error) { throw this.handleError(error, `Failed to get folders in space ${spaceId}`); } } /** * Find a folder by its name in a space * @param spaceId The ID of the space to search in * @param folderName The name of the folder to find * @returns The folder if found, otherwise null */ async findFolderByName(spaceId: string, folderName: string): Promise<ClickUpFolder | null> { this.logOperation('findFolderByName', { spaceId, folderName }); try { const folders = await this.getFoldersInSpace(spaceId); const matchingFolder = folders.find(folder => folder.name.toLowerCase() === folderName.toLowerCase() ); return matchingFolder || null; } catch (error) { throw this.handleError(error, `Failed to find folder by name in space ${spaceId}`); } } }