Skip to main content
Glama

JIRA MCP Server

issue.formatter.ts3.96 kB
import type { Formatter } from "@features/jira/shared/formatters/formatter.interface"; /** * Issue formatter */ import type { Issue } from "../models/issue.models"; import { IssueFieldValidator, hasDateInfo, hasLabels, hasValidDescription, hasValidSelfUrl, validateIssue, } from "../validators/issue-field.validator"; import { IssueDatesFormatter } from "./issue-dates.formatter"; import { IssueDescriptionFormatter } from "./issue-description.formatter"; import { IssueHeaderFormatter } from "./issue-header.formatter"; /** * Issue formatter class that converts issues to markdown strings using Zod schema validation */ export class IssueFormatter implements Formatter<Issue, string> { private readonly fieldValidator: IssueFieldValidator; private readonly headerFormatter: IssueHeaderFormatter; private readonly descriptionFormatter: IssueDescriptionFormatter; private readonly datesFormatter: IssueDatesFormatter; constructor() { this.fieldValidator = new IssueFieldValidator(); this.headerFormatter = new IssueHeaderFormatter(); this.descriptionFormatter = new IssueDescriptionFormatter(); this.datesFormatter = new IssueDatesFormatter(); } format(issue: Issue): string { if (!issue) { return ""; } // Validate issue structure using Zod schema const validationResult = validateIssue(issue); if (!validationResult.success) { return this.headerFormatter.formatFallbackHeader(issue.key || ""); } // Use original issue for compatibility with existing interfaces const validatedIssue = issue; // Handle case where issue exists but fields is null or undefined if (this.fieldValidator.hasEmptyFields(validatedIssue)) { return this.headerFormatter.formatFallbackHeader( validatedIssue.key || "", ); } // Get safe field values using schema validation const safeValues = this.fieldValidator.getSafeFieldValues(validatedIssue); // Build the formatted output using extracted formatters let markdown = ""; // Title and basic info markdown += this.headerFormatter.formatTitle( safeValues.key, safeValues.summary, ); markdown += this.headerFormatter.formatBasicInfo( safeValues.status, safeValues.priority, safeValues.assignee, ); // Description - use schema-based validation if (hasValidDescription(validatedIssue)) { markdown += this.descriptionFormatter.formatDescription(validatedIssue); } // Labels - use schema-based validation if (hasLabels(validatedIssue)) { markdown += this.headerFormatter.formatLabels( validatedIssue.fields?.labels || [], ); } // Dates - use schema-based validation if (hasDateInfo(validatedIssue)) { markdown += this.datesFormatter.formatDates(validatedIssue); } // JIRA link - use schema-based validation if (hasValidSelfUrl(validatedIssue)) { markdown += this.headerFormatter.formatJiraLink(validatedIssue); } return markdown; } /** * Format an issue as a simple object (for API compatibility) with schema validation */ formatAsObject(issue: Issue) { if (!issue) { return {}; } // Validate issue structure using Zod schema const validationResult = validateIssue(issue); if (!validationResult.success || !issue.fields) { return {}; } // Use original issue for compatibility with existing interfaces const fields = issue.fields; return { id: issue.id, key: issue.key, self: issue.self, fields: { summary: fields.summary, description: fields.description, issuetype: fields.issuetype, project: fields.project, status: fields.status, creator: fields.creator, reporter: fields.reporter, assignee: fields.assignee, created: fields.created, updated: fields.updated, }, }; } }

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/Dsazz/mcp-jira'

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