UNPKG

ds-sfcoe-ailabs

Version:

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

375 lines (371 loc) 13 kB
import { AIProviderType } from '../aiProvider/index.js'; /** * Supported AI providers mapping * Maps string identifiers to AIProviderType enum values * * @example * ```typescript * const provider = AI_PROVIDERS.OPENAI; // AIProviderType.OpenAI * ``` */ export const AI_PROVIDERS = { AZURE_OPENAI: AIProviderType.AzureOpenAI, OPENAI: AIProviderType.OpenAI, ANTHROPIC: AIProviderType.Anthropic, }; /** * Default GitHub bot identifier and comment header/footer configuration * Contains standard identifiers and templates for GitHub PR comments * * @example * ```typescript * const comment = `${GITHUB_BOT_IDENTIFIER_DEFAULTS.COMMENT_HEADER}\n\nReview content\n\n${GITHUB_BOT_IDENTIFIER_DEFAULTS.COMMENT_FOOTER}`; * ``` */ export const GITHUB_BOT_IDENTIFIER_DEFAULTS = { IDENTIFIER: '<!-- AI-PR-Review-Bot: ds-sfcoe-ailabs -->', COMMENT_HEADER: '🤖 **AI Code Quality Review Bot**', USER_AGENT: 'ds-sfcoe-ailabs', COMMENT_FOOTER: '*Generated using the npm package ds-sfcoe-ailabs*', }; /** * Default GitHub REST API configuration values * Contains standard API endpoints, headers, and error messages for GitHub integration * * @example * ```typescript * const apiUrl = `${GITHUB_API_DEFAULTS.PR_BASE_URL}/${owner}/${repo}/pulls`; * ``` */ export const GITHUB_API_DEFAULTS = { PR_BASE_URL: 'https://api.github.com/repos', USER_AGENT: GITHUB_BOT_IDENTIFIER_DEFAULTS.USER_AGENT, API_VERSION: '2022-11-28', ACCEPT_HEADER: 'application/vnd.github+json', START_SIDE: 'RIGHT', RESPONSE_TYPE: 'json', SAML_ERROR_MESSAGE: `🔒 GitHub SAML SSO Required! Your organization requires SAML Single Sign-On authentication for Personal Access Tokens. SOLUTION STEPS: 1. Go to your Personal Access Tokens page: https://github.com/settings/tokens 2. Find your token and click "Configure SSO" next to it 3. Authorize the token for your organization 4. Click "Authorize" to grant SAML SSO access Alternative: Create a new token and immediately authorize it for SSO: 1. Create new token: https://github.com/settings/tokens/new 2. Select required scopes (repo for private repos, public_repo for public) 3. Click "Configure SSO" and authorize for organization Documentation: https://docs.github.com/articles/authenticating-to-a-github-organization-with-saml-single-sign-on/`, }; /** * Supported file extensions for code analysis by language/platform * Organizes file extensions by technology stack for targeted analysis * * @example * ```typescript * const isApexFile = SUPPORTED_FILE_EXTENSIONS.APEX.includes('.cls'); * const jsExtensions = SUPPORTED_FILE_EXTENSIONS.JAVASCRIPT; * ``` */ export const SUPPORTED_FILE_EXTENSIONS = { APEX: ['.cls', '.trigger'], JAVASCRIPT: ['.js', '.mjs', '.cjs'], TYPESCRIPT: ['.ts'], HTML: ['.html'], CSS: ['.css'], XML: ['.xml'], AURA: ['.cmp'], METADATA: ['.xml', '.json', '.yaml', '.yml'], PLSQL: [ '.sql', '.pks', '.pkb', '.prc', '.fnc', '.trg', '.typ', '.tps', '.tpb', ], VISUALFORCE: ['.page', '.component'], JAVA: ['.java'], }; /** * Directories to exclude from analysis * List of common directories that should be skipped during code analysis * * @example * ```typescript * const shouldExclude = EXCLUDED_DIRECTORIES.includes('node_modules'); * ``` */ export const EXCLUDED_DIRECTORIES = [ 'node_modules', '.git', 'dist', 'build', 'coverage', '.nyc_output', '.sfdx', ]; /** * Test framework patterns and identifiers for Apex testing * Contains patterns used to identify test files and deprecated testing frameworks * * @example * ```typescript * const isTestFile = content.includes(TEST_PATTERNS.APEX_TEST_ANNOTATION); * const usesOldFramework = content.includes(TEST_PATTERNS.SOBJECT_MOCKER); * ``` */ export const TEST_PATTERNS = { APEX_TEST_ANNOTATION: '@isTest', SOBJECT_MOCKER: 'SObjectMocker', CLASS_MOCKER: 'ClassMocker', GENERATE_MOCK_SOBJECT: 'generateMockSObject', TEST_FILE_PATTERN: 'test', }; /** * Default Datadog configuration values for observability * Contains standard settings for logging and metrics integration with Datadog * * @example * ```typescript * const logConfig = { * service: DATADOG_DEFAULT_CONSTANTS.service, * environment: DATADOG_DEFAULT_CONSTANTS.environment * }; * ``` */ export const DATADOG_DEFAULT_CONSTANTS = { ddsource: 'AIPRReview', hostname: 'sfcoe-aipr-review', service: 'sfcoe-aipr-review', prefix: 'sfcoe_aipr_review.', environment: 'development', logLevel: 'debug', timestampFormat: 'MMM-DD-YYYY HH:mm:ss', observabilityFlags: [ 'pull-request-id', 'ai-provider', 'git-provider', 'git-owner', 'git-repo', ], }; /** * Default patterns for JavaScript code analysis * Predefined patterns to detect common JavaScript issues and violations * * @example * ```typescript * const consolePattern = JS_PATTERNS.find(p => p.pattern === 'console.log'); * console.log(consolePattern.suggestedFix); * ``` */ export const JS_PATTERNS = [ { pattern: 'console.log', ruleType: 'JavaScript Best Practices', issue: 'Console.log statements found - should be removed for production', suggestedFix: 'Use proper logging framework or remove console statements', ruleId: 'console-custom', }, { pattern: 'var ', ruleType: 'JavaScript Best Practices', issue: 'Using var instead of let/const', suggestedFix: 'Replace var with let or const for block scoping', ruleId: 'var-custom', }, { pattern: 'with (', ruleType: 'JavaScript Security', issue: 'Using with statement which is deprecated and insecure', suggestedFix: 'Refactor to avoid with statements', ruleId: 'with-custom', }, ]; /** * Package and message bundle identifiers * Contains package metadata and command identifiers * * @example * ```typescript * console.log(`Running ${PACKAGE_CONSTANTS.NAME} package`); * const command = PACKAGE_CONSTANTS.REVIEW_COMMAND; * ``` */ export const PACKAGE_CONSTANTS = { NAME: 'ds-sfcoe-ailabs', REVIEW_COMMAND: 'ks.review.diff', }; /** * Default values for command flags and configuration * Provides fallback values for CLI command options and API settings * * @example * ```typescript * const fromRef = flags.from || COMMAND_DEFAULTS.GIT_FROM_REF; * const aiProvider = flags.aiProvider || COMMAND_DEFAULTS.AI_PROVIDER; * ``` */ export const COMMAND_DEFAULTS = { GIT_FROM_REF: 'HEAD~1', GIT_TO_REF: 'HEAD', AI_PROVIDER: AIProviderType.AzureOpenAI, GIT_PROVIDER: 'GitHub', AI_MODEL: 'gpt-4o-mini-eastus2', AI_API_ENDPOINT: 'https://dts-apigw-sandbox.docusignhq.com/', AI_API_VERSION: '2024-08-01-preview', SCA_RULESET: '../../common/contextProviders/scat/sf-code-analyzer-ruleset.yml', PMD_RULESET: '../../common/contextProviders/scat/pmd-ruleset.xml', DEFAULT_MAX_TOKENS: 4096, DEFAULT_PROMPT_TEMPLATE: '$prompt\n\n# Code Snippet:\n$codeSnippet\n\n# Hints:\n$hintsText', DEFAULT_SARIF_FILE_NAME: 'results.sarif', SF_CODE_ANALYZER_LOGS_FOLDER: 'code-analyzer-logs', }; /** * Default values for review command hints and messages * Contains fallback values and templates for review output formatting * * @example * ```typescript * const ruleId = hint.ruleId || REVIEW_COMMAND_HINTS_DEFAULTS.RULE_ID; * const tableHeader = REVIEW_COMMAND_HINTS_DEFAULTS.AI_ANALYSIS_TABLE_HEADERS; * ``` */ export const REVIEW_COMMAND_HINTS_DEFAULTS = { RULE_ID: 'unknown-rule', MESSAGE: 'No message available', SUGGESTION: 'AI Suggestion', SUGGESTION_RULE_TYPE: 'Review and refactor as needed', RULE_TYPE: 'General', FILE_NAME: 'unknown-file', LINE_NUMBER: 0, AI_ANALYSIS_TABLE_HEADERS: '| Class | Line | Rule Type | Issue | Suggested Fix |\n' + '|-------|------|-----------|-------|---------------|\n', }; /** * Regex pattern to match file extensions * Used to extract the last file extension from file paths * * @example * ```typescript * const extension = 'file.cls'.match(LAST_EXTENSION_REGEX)?.[0]; // '.cls' * ``` */ export const LAST_EXTENSION_REGEX = /\.[^/.]+$/; /** * DocuSign-specific issues and patterns for code analysis * Defines organization-specific rules and their corresponding messages and fixes * * @example * ```typescript * const testIssue = DOCUSIGN_SPECIFIC_ISSUES.TEST_FRAMEWORK; * console.log(testIssue.suggestedFix); * ``` */ export const DOCUSIGN_SPECIFIC_ISSUES = { TEST_FRAMEWORK: { ruleType: 'Docusign Specific', issue: 'Using old test framework which takes huge time to run', suggestedFix: `[Use ${TEST_PATTERNS.SOBJECT_MOCKER}, ${TEST_PATTERNS.CLASS_MOCKER}, or ${TEST_PATTERNS.GENERATE_MOCK_SOBJECT}.](https://docusign.atlassian.net/wiki/spaces/EA/pages/720143853/DS+Apex+Test+-+Overview)`, }, GLOBAL_DESCRIBE_USAGE: { ruleType: 'Docusign Specific', issue: 'Using Schema.getGlobalDescribe() which has performance issues', suggestedFix: '[Use COE_SchemaUtils framework.](https://docusign.atlassian.net/wiki/spaces/EA/pages/155880835/Better+getGlobalDescribe)', }, TRANSACTION_LOGGER_MISSING: { ruleType: 'Docusign Specific', issue: 'New Apex class does not have any reference to TransactionLogger methods', suggestedFix: '[Add TransactionLogger methods for better tracking and observability.](https://docusign.atlassian.net/wiki/x/HwPaGQ)', }, }; /** * Supported Salesforce file extensions for platform-specific analysis * List of file extensions commonly used in Salesforce development * * @example * ```typescript * const isSalesforceFile = SUPPORTED_SALESFORCE_EXTENSIONS.includes('.cls'); * ``` */ export const SUPPORTED_SALESFORCE_EXTENSIONS = [ '.cls', '.trigger', '.page', '.component', '.mjs', '.cjs', '.js', '.ts', '.html', '.css', '.xml', '.cmp', ]; /** * Mapping of rule types to human-readable categories * Maps linter rule IDs to descriptive category names for better user understanding * * @example * ```typescript * const category = RULE_TYPE_MAP['no-var']; // 'JavaScript Best Practices' * const unknownRule = RULE_TYPE_MAP['unknown-rule'] || 'General'; * ``` */ export const RULE_TYPE_MAP = { // JavaScript/ESLint rules 'no-var': 'JavaScript Best Practices', 'no-with': 'JavaScript Security', 'no-debugger': 'JavaScript Performance', 'no-console': 'JavaScript Best Practices', 'no-unused-vars': 'JavaScript General', eqeqeq: 'JavaScript Best Practices', 'no-eval': 'JavaScript Security', curly: 'JavaScript Best Practices', 'no-undef': 'JavaScript General', 'prefer-const': 'JavaScript Best Practices', 'no-empty': 'JavaScript Best Practices', // TypeScript rules '@typescript-eslint/no-unused-vars': 'TypeScript General', '@typescript-eslint/no-explicit-any': 'TypeScript Best Practices', '@typescript-eslint/ban-ts-comment': 'TypeScript Best Practices', // LWC rules '@lwc/lwc/no-inner-html': 'LWC Security', '@lwc/lwc/no-document-query': 'LWC Best Practices', '@lwc/lwc/no-api-reassignments': 'LWC Best Practices', // Apex rules ApexCSRF: 'Apex Security', ApexCRUDViolation: 'Apex Security', MethodNamingConventions: 'Apex Best Practices', AvoidDebugStatements: 'Apex Performance', }; /** * Suggested fixes for common code issues * Maps rule IDs to actionable fix descriptions for developers * * @example * ```typescript * const fix = SUGGESTED_FIXES['no-var']; // 'Replace var with let or const for block scoping' * const defaultFix = SUGGESTED_FIXES[ruleId] || 'Review and refactor as needed'; * ``` */ export const SUGGESTED_FIXES = { 'no-var': 'Replace var with let or const for block scoping', 'no-with': 'Refactor code to avoid with statements', 'no-debugger': 'Remove debugger statements before production', 'no-console': 'Use proper logging framework instead of console.log', 'no-unused-vars': 'Remove unused variables or prefix with underscore if intentional', eqeqeq: 'Use === or !== instead of == or !=', 'no-eval': 'Avoid eval() and use safer alternatives', curly: 'Add curly braces around control flow statements', 'no-undef': 'Define the variable or import it properly', 'prefer-const': 'Use const for variables that are never reassigned', 'no-empty': 'Add code to empty blocks or remove them', '@lwc/lwc/no-inner-html': 'Use secure alternatives to innerHTML', '@lwc/lwc/no-document-query': 'Use LWC template queries instead of document queries', '@typescript-eslint/no-unused-vars': 'Remove unused variables or use underscore prefix', '@typescript-eslint/no-explicit-any': 'Use specific types instead of any', };