Skip to main content
Glama
contributors.controller.ts11.1 kB
import type { ControllerResponse } from "../../shared/types/common.types.js"; import { ErrorType, McpError } from "../../shared/utils/error.util.js"; import { handleControllerError } from "../../shared/utils/error-handler.util.js"; import { Logger } from "../../shared/utils/logger.util.js"; import { formatAddContributorsResult, formatContributorDetails, formatContributorsList, formatRemoveContributorResult, formatUpdateContributorResult, } from "./contributors.formatter.js"; import { contributorsService } from "./contributors.service.js"; import type { AddContributorsToolArgsType, GetContributorToolArgsType, GetCurrentUserToolArgsType, ListContributorsToolArgsType, RemoveContributorToolArgsType, UpdateContributorToolArgsType, } from "./contributors.types.js"; /** * @namespace ContributorsController * @description Controller responsible for handling Lokalise Contributors API operations. * It orchestrates calls to the contributors service, applies defaults, * maps options, and formats the response using the formatter. */ /** * @function listContributors * @description Fetches a list of contributors from a Lokalise project. * @memberof ContributorsController * @param {ListContributorsToolArgsType} args - Arguments containing project ID and pagination options * @returns {Promise<ControllerResponse>} A promise that resolves to the standard controller response containing the formatted contributors list in Markdown. * @throws {McpError} Throws an McpError (handled by `handleControllerError`) if the service call fails or returns an error. */ async function listContributors( args: ListContributorsToolArgsType, ): Promise<ControllerResponse> { const methodLogger = Logger.forContext( "contributors.controller.ts", "listContributors", ); methodLogger.debug("Getting Lokalise contributors list...", args); try { // Validate project ID if (!args.projectId || typeof args.projectId !== "string") { throw new McpError( "Project ID is required and must be a string.", ErrorType.API_ERROR, ); } // Validate pagination parameters if (args.limit !== undefined && (args.limit < 1 || args.limit > 100)) { throw new McpError( "Invalid limit parameter. Must be between 1 and 100.", ErrorType.API_ERROR, ); } if (args.page !== undefined && args.page < 1) { throw new McpError( "Invalid page parameter. Must be 1 or greater.", ErrorType.API_ERROR, ); } // Call service layer const result = await contributorsService.list(args); // Format response using the formatter const formattedContent = formatContributorsList(result); methodLogger.debug("Contributors list fetched successfully", { projectId: args.projectId, contributorsCount: result.items?.length || 0, }); return { content: formattedContent, }; } catch (error: unknown) { throw handleControllerError(error, { source: "ContributorsController.listContributors", entityType: "Contributors", entityId: args.projectId, operation: "listing", }); } } /** * @function getContributor * @description Fetches details of a specific contributor. * @memberof ContributorsController * @param {GetContributorToolArgsType} args - Arguments containing project ID and contributor ID * @returns {Promise<ControllerResponse>} A promise that resolves to the formatted contributor details. * @throws {McpError} Throws an McpError if the service call fails. */ async function getContributor( args: GetContributorToolArgsType, ): Promise<ControllerResponse> { const methodLogger = Logger.forContext( "contributors.controller.ts", "getContributor", ); methodLogger.debug("Getting contributor details...", args); try { // Validate inputs if (!args.projectId || typeof args.projectId !== "string") { throw new McpError( "Project ID is required and must be a string.", ErrorType.API_ERROR, ); } if (!args.contributorId) { throw new McpError("Contributor ID is required.", ErrorType.API_ERROR); } // Call service layer const result = await contributorsService.get(args); // Format response const formattedContent = formatContributorDetails(result); methodLogger.debug("Contributor details fetched successfully", { projectId: args.projectId, contributorId: args.contributorId, }); return { content: formattedContent, }; } catch (error: unknown) { throw handleControllerError(error, { source: "ContributorsController.getContributor", entityType: "Contributor", entityId: { project: args.projectId, contributor: String(args.contributorId), }, operation: "retrieving", }); } } /** * @function addContributors * @description Adds one or more contributors to a project. * @memberof ContributorsController * @param {AddContributorsToolArgsType} args - Arguments containing project ID and contributor data * @returns {Promise<ControllerResponse>} A promise that resolves to the formatted result. * @throws {McpError} Throws an McpError if the service call fails. */ async function addContributors( args: AddContributorsToolArgsType, ): Promise<ControllerResponse> { const methodLogger = Logger.forContext( "contributors.controller.ts", "addContributors", ); methodLogger.debug("Adding contributors...", args); try { // Validate inputs if (!args.projectId || typeof args.projectId !== "string") { throw new McpError( "Project ID is required and must be a string.", ErrorType.API_ERROR, ); } if (!args.contributors || args.contributors.length === 0) { throw new McpError( "At least one contributor is required.", ErrorType.API_ERROR, ); } // Call service layer const result = await contributorsService.create(args); // Format response const formattedContent = formatAddContributorsResult(result); methodLogger.debug("Contributors added successfully", { projectId: args.projectId, addedCount: result.length, }); return { content: formattedContent, }; } catch (error: unknown) { throw handleControllerError(error, { source: "ContributorsController.addContributors", entityType: "Contributors", entityId: args.projectId, operation: "adding", }); } } /** * @function getCurrentUser * @description Gets the current user's contributor profile for a project. * @memberof ContributorsController * @param {GetCurrentUserToolArgsType} args - Arguments containing project ID * @returns {Promise<ControllerResponse>} A promise that resolves to the formatted current user details. * @throws {McpError} Throws an McpError if the service call fails. */ async function getCurrentUser( args: GetCurrentUserToolArgsType, ): Promise<ControllerResponse> { const methodLogger = Logger.forContext( "contributors.controller.ts", "getCurrentUser", ); methodLogger.debug("Getting current user contributor profile...", args); try { // Validate inputs if (!args.projectId || typeof args.projectId !== "string") { throw new McpError( "Project ID is required and must be a string.", ErrorType.API_ERROR, ); } // Call service layer const result = await contributorsService.me(args); // Format response const formattedContent = formatContributorDetails(result); methodLogger.debug("Current user profile fetched successfully", { projectId: args.projectId, userId: result.user_id, }); return { content: formattedContent, }; } catch (error: unknown) { throw handleControllerError(error, { source: "ContributorsController.getCurrentUser", entityType: "Current User", entityId: args.projectId, operation: "retrieving", }); } } /** * @function updateContributor * @description Updates a contributor's permissions in a project. * @memberof ContributorsController * @param {UpdateContributorToolArgsType} args - Arguments containing project ID, contributor ID and update data * @returns {Promise<ControllerResponse>} A promise that resolves to the formatted update result. * @throws {McpError} Throws an McpError if the service call fails. */ async function updateContributor( args: UpdateContributorToolArgsType, ): Promise<ControllerResponse> { const methodLogger = Logger.forContext( "contributors.controller.ts", "updateContributor", ); methodLogger.debug("Updating contributor...", args); try { // Validate inputs if (!args.projectId || typeof args.projectId !== "string") { throw new McpError( "Project ID is required and must be a string.", ErrorType.API_ERROR, ); } if (!args.contributorId) { throw new McpError("Contributor ID is required.", ErrorType.API_ERROR); } // Call service layer const result = await contributorsService.update(args); // Format response const formattedContent = formatUpdateContributorResult(result); methodLogger.debug("Contributor updated successfully", { projectId: args.projectId, contributorId: args.contributorId, }); return { content: formattedContent, }; } catch (error: unknown) { throw handleControllerError(error, { source: "ContributorsController.updateContributor", entityType: "Contributor", entityId: { project: args.projectId, contributor: String(args.contributorId), }, operation: "updating", }); } } /** * @function removeContributor * @description Removes a contributor from a project. * @memberof ContributorsController * @param {RemoveContributorToolArgsType} args - Arguments containing project ID and contributor ID * @returns {Promise<ControllerResponse>} A promise that resolves to the formatted deletion result. * @throws {McpError} Throws an McpError if the service call fails. */ async function removeContributor( args: RemoveContributorToolArgsType, ): Promise<ControllerResponse> { const methodLogger = Logger.forContext( "contributors.controller.ts", "removeContributor", ); methodLogger.debug("Removing contributor...", args); try { // Validate inputs if (!args.projectId || typeof args.projectId !== "string") { throw new McpError( "Project ID is required and must be a string.", ErrorType.API_ERROR, ); } if (!args.contributorId) { throw new McpError("Contributor ID is required.", ErrorType.API_ERROR); } // Call service layer const result = await contributorsService.delete(args); // Format response const formattedContent = formatRemoveContributorResult(result); methodLogger.debug("Contributor removed successfully", { projectId: args.projectId, contributorId: args.contributorId, }); return { content: formattedContent, }; } catch (error: unknown) { throw handleControllerError(error, { source: "ContributorsController.removeContributor", entityType: "Contributor", entityId: { project: args.projectId, contributor: String(args.contributorId), }, operation: "removing", }); } } /** * Export the controller functions */ const contributorsController = { listContributors, getContributor, addContributors, getCurrentUser, updateContributor, removeContributor, }; export default contributorsController;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AbdallahAHO/lokalise-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server