Skip to main content
Glama

SFCC Development MCP Server

by taurgis
class-content-parser.ts9.82 kB
/** * Class Content Parser * * Responsible for parsing markdown documentation content and extracting * structured class information including constants, properties, methods, and inheritance. * * Single Responsibility: Converting markdown content to structured data */ import { Logger } from '../../utils/logger.js'; export interface SFCCMethod { name: string; signature: string; description: string; parameters?: string[]; returnType?: string; deprecated?: boolean; deprecationMessage?: string; } export interface SFCCProperty { name: string; type: string; description: string; modifiers?: string[]; deprecated?: boolean; deprecationMessage?: string; } export interface SFCCConstant { name: string; type: string; value?: string; description: string; deprecated?: boolean; deprecationMessage?: string; } export interface SFCCClassDetails { className: string; packageName: string; description: string; constants: SFCCConstant[]; properties: SFCCProperty[]; methods: SFCCMethod[]; inheritance?: string[]; constructorInfo?: string; } export class ClassContentParser { private logger: Logger; constructor() { this.logger = Logger.getChildLogger('ClassContentParser'); } /** * Parse markdown content and extract structured class information */ parseClassContent(content: string): SFCCClassDetails { const lines = content.split('\n'); let currentSection = ''; let className = ''; let packageName = ''; let description = ''; const constants: SFCCConstant[] = []; const properties: SFCCProperty[] = []; const methods: SFCCMethod[] = []; const inheritance: string[] = []; let constructorInfo = ''; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); // Extract package name if (line.startsWith('## Package:')) { packageName = line.replace('## Package:', '').trim(); } // Extract class name if (line.startsWith('# ') && !line.startsWith('## ')) { className = line.replace('# ', '').replace('Class ', '').trim(); } // Track current section if (line.startsWith('## ')) { currentSection = line.replace('## ', '').trim(); } // Extract description if (currentSection === 'Description' && line && !line.startsWith('#')) { description += `${line} `; } // Extract inheritance hierarchy if (currentSection === 'Inheritance Hierarchy' && line.includes('-')) { const hierarchyItem = line.replace(/^[\s-]*/, '').trim(); if (hierarchyItem) { inheritance.push(hierarchyItem); } } // Extract constants if (currentSection === 'Constants' && line.startsWith('### ')) { const constant = this.parseConstant(line, lines, i); if (constant) { constants.push(constant); } } // Extract properties if (currentSection === 'Properties' && line.startsWith('### ')) { const property = this.parseProperty(line, lines, i); if (property) { properties.push(property); } } // Extract methods if ((currentSection === 'Method Summary' || currentSection === 'Method Details') && line.startsWith('### ')) { const method = this.parseMethod(line, lines, i); if (method) { methods.push(method); } } // Extract constructor info if (currentSection === 'Constructor Summary' && line && !line.startsWith('#')) { constructorInfo += `${line} `; } } return { className: className.trim(), packageName: packageName.trim(), description: description.trim(), constants, properties, methods, inheritance: inheritance.length > 0 ? inheritance : undefined, constructorInfo: constructorInfo.trim() || undefined, }; } /** * Parse a constant definition from markdown content */ private parseConstant(headerLine: string, lines: string[], startIndex: number): SFCCConstant | null { const constName = headerLine.replace('### ', '').trim(); let constType = ''; let constValue = ''; let constDesc = ''; let deprecated = false; let deprecationMessage = ''; // Look for type, value and description in following lines for (let j = startIndex + 1; j < lines.length && !lines[j].startsWith('#'); j++) { const nextLine = lines[j].trim(); if (nextLine.startsWith('**Type:**')) { const typeMatch = nextLine.match(/\*\*Type:\*\*\s*(.+)/); if (typeMatch) { const typeInfo = typeMatch[1]; // Extract type and value if present (e.g., "String = 'COMPLETED'" or "Number = 8") const valueMatch = typeInfo.match(/^(\w+)\s*=\s*(.+)$/); if (valueMatch) { constType = valueMatch[1]; constValue = valueMatch[2]; } else { constType = typeInfo.trim(); } } } else if (nextLine.startsWith('**Deprecated:**')) { const deprecationInfo = this.parseDeprecationInfo(nextLine, lines, j); deprecated = true; deprecationMessage = deprecationInfo.message; } else if (nextLine && !nextLine.startsWith('**') && !nextLine.startsWith('#')) { constDesc += `${nextLine} `; } } return { name: constName, type: constType, value: constValue || undefined, description: constDesc.trim(), deprecated: deprecated || undefined, deprecationMessage: deprecationMessage || undefined, }; } /** * Parse a property definition from markdown content */ private parseProperty(headerLine: string, lines: string[], startIndex: number): SFCCProperty | null { const propName = headerLine.replace('### ', '').trim(); let propType = ''; let propDesc = ''; const modifiers: string[] = []; let deprecated = false; let deprecationMessage = ''; // Look for type and description in following lines for (let j = startIndex + 1; j < lines.length && !lines[j].startsWith('#'); j++) { const nextLine = lines[j].trim(); if (nextLine.startsWith('**Type:**')) { const typeMatch = nextLine.match(/\*\*Type:\*\*\s*(.+)/); if (typeMatch) { const typeInfo = typeMatch[1]; propType = typeInfo.split(' ')[0]; if (typeInfo.includes('(Read Only)')) { modifiers.push('Read Only'); } if (typeInfo.includes('(Static)')) { modifiers.push('Static'); } } } else if (nextLine.startsWith('**Deprecated:**')) { const deprecationInfo = this.parseDeprecationInfo(nextLine, lines, j); deprecated = true; deprecationMessage = deprecationInfo.message; } else if (nextLine && !nextLine.startsWith('**') && !nextLine.startsWith('#')) { propDesc += `${nextLine} `; } } return { name: propName, type: propType, description: propDesc.trim(), modifiers: modifiers.length > 0 ? modifiers : undefined, deprecated: deprecated || undefined, deprecationMessage: deprecationMessage || undefined, }; } /** * Parse a method definition from markdown content */ private parseMethod(headerLine: string, lines: string[], startIndex: number): SFCCMethod | null { const methodName = headerLine.replace('### ', '').trim(); let signature = ''; let methodDesc = ''; let deprecated = false; let deprecationMessage = ''; // Look for signature and description in following lines for (let j = startIndex + 1; j < lines.length && !lines[j].startsWith('#'); j++) { const nextLine = lines[j].trim(); if (nextLine.startsWith('**Signature:**')) { const sigMatch = nextLine.match(/\*\*Signature:\*\*\s*`(.+)`/); if (sigMatch) { signature = sigMatch[1]; } } else if (nextLine.startsWith('**Description:**')) { methodDesc = nextLine.replace('**Description:**', '').trim(); } else if (nextLine.startsWith('**Deprecated:**')) { const deprecationInfo = this.parseDeprecationInfo(nextLine, lines, j); deprecated = true; deprecationMessage = deprecationInfo.message; } else if (nextLine && !nextLine.startsWith('**') && !nextLine.startsWith('#') && !nextLine.startsWith('---')) { if (!methodDesc && !nextLine.includes('Signature:')) { methodDesc += `${nextLine} `; } } } return { name: methodName, signature: signature || methodName, description: methodDesc.trim(), deprecated: deprecated || undefined, deprecationMessage: deprecationMessage || undefined, }; } /** * Parse deprecation information from markdown content */ private parseDeprecationInfo(deprecationLine: string, lines: string[], startIndex: number): { message: string } { let deprecationMessage = ''; // Check if there's a message on the same line const sameLineMessage = deprecationLine.replace('**Deprecated:**', '').trim(); if (sameLineMessage) { deprecationMessage = sameLineMessage; } else { // Look for the deprecation message on subsequent lines until next ** marker const depLines: string[] = []; for (let k = startIndex + 1; k < lines.length && !lines[k].startsWith('#'); k++) { const depLine = lines[k].trim(); if (depLine.startsWith('**') && !depLine.startsWith('**Deprecated:**')) { break; // Stop at next ** marker } if (depLine && !depLine.startsWith('---')) { depLines.push(depLine); } } deprecationMessage = depLines.join(' ').trim(); } return { message: deprecationMessage }; } }

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/taurgis/sfcc-dev-mcp'

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