UNPKG

sfcoe-ailabs

Version:

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

262 lines (258 loc) 8.97 kB
import { AIProviderType } from '../aiProvider/index.js'; /** * Supported AI providers */ export const AI_PROVIDERS = { AZURE_OPENAI: AIProviderType.AzureOpenAI, OPENAI: AIProviderType.OpenAI, ANTHROPIC: AIProviderType.Anthropic, }; /** * Default GitHub bot identifier and comment header/footer */ export const GITHUB_BOT_IDENTIFIER_DEFAULTS = { IDENTIFIER: '<!-- AI-PR-Review-Bot: sfcoe-ailabs -->', COMMENT_HEADER: '🤖 **AI Code Quality Review Bot**', USER_AGENT: 'sfcoe-ailabs', COMMENT_FOOTER: '*Generated using the npm package sfcoe-ailabs*', }; /** * Default GitHub REST API configuration values */ 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 */ 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 */ export const EXCLUDED_DIRECTORIES = [ 'node_modules', '.git', 'dist', 'build', 'coverage', '.nyc_output', '.sfdx', ]; /** * Test framework patterns and identifiers */ 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 */ 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 */ 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 */ export const PACKAGE_CONSTANTS = { NAME: 'sfcoe-ailabs', REVIEW_COMMAND: 'ks.review.diff', }; /** * Default values for command flags */ 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 */ 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 to match file extensions */ export const LAST_EXTENSION_REGEX = /\.[^/.]+$/; /** * DocuSign-specific issues and patterns */ 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}. [More details](https://docusign.atlassian.net/wiki/spaces/EA/pages/720143853/DS+Apex+Test+-+Overview)`, }, GLOBAL_DESCRIBE_USAGE: { ruleType: 'Docusign Specific', issue: 'Using Schema.getGlobalDescribe() at line $line_number which has performance issues', suggestedFix: 'Use COE_SchemaUtils framework. [More details](https://docusign.atlassian.net/wiki/spaces/EA/pages/155880835/Better+getGlobalDescribe)', }, }; /** * Supported Salesforce file extensions */ 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 */ 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 */ 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', };