UNPKG

ds-sfcoe-ailabs

Version:

AI-powered code review tool with static analysis integration for comprehensive code quality assessment.

224 lines (223 loc) 8.19 kB
import { FileUtils } from './fileUtils.js'; import { CodeAnalysisUtils } from './codeAnalysisUtils.js'; import { RuleUtils } from './ruleUtils.js'; import { DOCUSIGN_SPECIFIC_ISSUES } from './constants.js'; /** * Utility class for Docusign-specific code analysis rules * * Provides specialized rule checking for DocuSign's coding standards * including test framework validation, performance patterns, and * transaction logging requirements. * * @example * ```typescript * const issues = DocuSignRuleUtils.getDocuSignIssuesForFile( * 'MyClass.cls', * 'public class MyClass { ... }', * true * ); * console.log(issues.length); // Number of DocuSign-specific issues found * ``` */ export class DocuSignRuleUtils { /** * Check if file uses old test framework * * @param content - The file content to analyze * @returns True if the file uses old test framework patterns * @example * ```typescript * const hasOldFramework = DocuSignRuleUtils.hasOldTestFramework(apexContent); * if (hasOldFramework) { * console.log('File uses deprecated test framework'); * } * ``` */ static hasOldTestFramework(content) { return CodeAnalysisUtils.hasOldTestFramework(content); } /** * Check if file uses Schema.getGlobalDescribe() * * @param content - The file content to analyze * @returns Array of Docusign issues found related to Schema.getGlobalDescribe() usage * @example * ```typescript * const issues = DocuSignRuleUtils.hasGlobalDescribeUsage(apexContent); * issues.forEach(issue => { * console.log(`Line ${issue.lineNumber}: ${issue.issue}`); * }); * ``` */ static hasGlobalDescribeUsage(content) { const issues = []; if (content?.toLowerCase().includes('getglobaldescribe()')) { const lines = content.split('\n'); for (let i = 0; i < lines.length; i++) { if (lines[i]?.toLocaleLowerCase().includes('getglobaldescribe()')) { issues.push({ lineNumber: i + 1, ruleType: DOCUSIGN_SPECIFIC_ISSUES.GLOBAL_DESCRIBE_USAGE.ruleType, issue: DOCUSIGN_SPECIFIC_ISSUES.GLOBAL_DESCRIBE_USAGE.issue, }); } } } return issues; } /** * Check if an Apex class references TransactionLogger * * @param content - The file content to analyze * @returns True if the content references TransactionLogger * @example * ```typescript * const hasLogger = DocuSignRuleUtils.hasTransactionLoggerReference(apexContent); * if (!hasLogger) { * console.log('TransactionLogger reference missing'); * } * ``` */ static hasTransactionLoggerReference(content) { if (!content) return false; // Check for TransactionLogger references const transactionLoggerPatterns = [ /= new TransactionLogger\(\)/i, /=new TransactionLogger\(\)/i, ]; return transactionLoggerPatterns.some((pattern) => pattern.test(content)); } /** * Check if an Apex class is a new file and missing TransactionLogger reference * * @param filePath - The path of the file being analyzed * @param content - The content of the file to analyze * @param isNewFile - Whether this is a new file (added in commit) * @returns Array of Docusign issues if TransactionLogger is missing from new Apex class * @example * ```typescript * const issues = DocuSignRuleUtils.checkTransactionLoggerInNewApexClass( * 'MyController.cls', * apexContent, * true * ); * if (issues.length > 0) { * console.log('New Apex class missing TransactionLogger'); * } * ``` */ static checkTransactionLoggerInNewApexClass(filePath, content, isNewFile) { const issues = []; // Only check new Apex classes if (!isNewFile || !FileUtils.isApexFile(filePath)) { return issues; } // Skip test files and interfaces if (FileUtils.isTestFile(filePath, content) || content.includes('interface ') || content.includes(' interface ')) { return issues; } // Check if the file contains a class definition const classDefinitionRegex = /\b(public|private|global)?\s*class\s+\w+/i; if (!classDefinitionRegex.test(content)) { return issues; } // Check if TransactionLogger is referenced if (!this.hasTransactionLoggerReference(content)) { issues.push({ lineNumber: 1, ruleType: DOCUSIGN_SPECIFIC_ISSUES.TRANSACTION_LOGGER_MISSING.ruleType, issue: DOCUSIGN_SPECIFIC_ISSUES.TRANSACTION_LOGGER_MISSING.issue, }); } return issues; } /** * Get Docusign issues for a specific file * * @param filePath - The path of the file being analyzed * @param content - The content of the file to analyze * @param isNewFile - Whether this is a new file (optional, defaults to false) * @returns Array of Docusign-specific issues found in the file * @example * ```typescript * const issues = DocuSignRuleUtils.getDocuSignIssuesForFile( * 'MyClass.cls', * apexContent, * true * ); * console.log(`Found ${issues.length} DocuSign-specific issues`); * ``` */ static getDocuSignIssuesForFile(filePath, content, isNewFile = false) { const issues = []; // Test framework check if (FileUtils.isTestFile(filePath, content) && this.hasOldTestFramework(content)) { issues.push({ lineNumber: 1, ruleType: DOCUSIGN_SPECIFIC_ISSUES.TEST_FRAMEWORK.ruleType, issue: DOCUSIGN_SPECIFIC_ISSUES.TEST_FRAMEWORK.issue, }); } // Schema.getGlobalDescribe check issues.push(...this.hasGlobalDescribeUsage(content)); // TransactionLogger check for new Apex classes issues.push(...this.checkTransactionLoggerInNewApexClass(filePath, content, isNewFile)); return issues; } /** * Create JavaScript-specific table entries for common issues * * @param fileName - The name of the JavaScript file being analyzed * @param content - The content of the file to analyze * @param addedEntries - Set of already processed entry keys to avoid duplicates * @returns Array of table entries for JavaScript-specific issues found * @example * ```typescript * const entries = DocuSignRuleUtils.createJavaScriptTableEntries( * 'app.js', * jsContent, * new Set() * ); * console.log(`Created ${entries.length} table entries`); * ``` */ static createJavaScriptTableEntries(fileName, content, addedEntries) { return CodeAnalysisUtils.analyzeJavaScriptContent(fileName, content, addedEntries); } /** * Extract rule type from hint ruleId * * @param ruleId - The rule identifier to extract type from * @returns The rule type category * @example * ```typescript * const ruleType = DocuSignRuleUtils.extractRuleType('SF_SOQL_IN_LOOP'); * console.log(ruleType); // 'SOQL_IN_LOOP' * ``` */ static extractRuleType(ruleId) { return RuleUtils.extractRuleType(ruleId); } /** * Get suggested fix for JavaScript rules * * @param ruleId - The rule identifier to get fix for * @param message - The rule message for context * @returns Suggested fix description for the rule * @example * ```typescript * const fix = DocuSignRuleUtils.getSuggestedFixForJavaScript( * 'no-unused-vars', * 'Variable is declared but never used' * ); * console.log(fix); // Suggested fix for the rule * ``` */ static getSuggestedFixForJavaScript(ruleId, message) { return RuleUtils.getSuggestedFix(ruleId, message); } }