sfcoe-ailabs
Version:
AI-powered code review tool with static analysis integration for comprehensive code quality assessment.
262 lines (258 loc) • 8.97 kB
JavaScript
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',
};