UNPKG

sf-agent-framework

Version:

AI Agent Orchestration Framework for Salesforce Development - Two-phase architecture with 70% context reduction

303 lines (243 loc) 8.05 kB
# Salesforce Project Configuration Reader ## Purpose Utility to read and parse Salesforce DX project configuration from `sfdx-project.json` ## Usage ### Reading API Version ```bash # Get API version from sfdx-project.json get_api_version() { if [ -f "sfdx-project.json" ]; then cat sfdx-project.json | grep sourceApiVersion | sed 's/.*"sourceApiVersion": "\(.*\)".*/\1/' else echo "63.0" # Fallback to latest stable fi } API_VERSION=$(get_api_version) echo "Using API Version: $API_VERSION" ``` ### Reading Package Directories ```bash # Get default package directory get_package_dir() { if [ -f "sfdx-project.json" ]; then cat sfdx-project.json | jq -r '.packageDirectories[] | select(.default==true) | .path' 2>/dev/null || echo "force-app" else echo "force-app" fi } PACKAGE_DIR=$(get_package_dir) echo "Package Directory: $PACKAGE_DIR" ``` ### Validating Project Structure ```bash # Check if valid SFDX project validate_sfdx_project() { if [ ! -f "sfdx-project.json" ]; then echo "❌ Error: Not a Salesforce DX project directory" echo "Please run this command from a directory containing sfdx-project.json" return 1 fi # Check for package directories if [ ! -d "$(get_package_dir)" ]; then echo "⚠️ Warning: Package directory not found" echo "Expected directory: $(get_package_dir)" return 1 fi echo "✅ Valid Salesforce DX project detected" return 0 } ``` ### JavaScript/Node.js Implementation ```javascript const fs = require('fs'); const path = require('path'); class SfdxProjectConfig { constructor(projectPath = process.cwd()) { this.projectPath = projectPath; this.configPath = path.join(projectPath, 'sfdx-project.json'); this.config = null; this.loadConfig(); } loadConfig() { try { if (fs.existsSync(this.configPath)) { const configContent = fs.readFileSync(this.configPath, 'utf8'); this.config = JSON.parse(configContent); } else { console.warn('sfdx-project.json not found. Using defaults.'); this.config = this.getDefaultConfig(); } } catch (error) { console.error('Error reading sfdx-project.json:', error); this.config = this.getDefaultConfig(); } } getDefaultConfig() { return { packageDirectories: [{ path: 'force-app', default: true }], sourceApiVersion: '63.0', namespace: '', sfdcLoginUrl: 'https://login.salesforce.com', }; } getApiVersion() { return this.config?.sourceApiVersion || '63.0'; } getPackageDirectories() { return this.config?.packageDirectories || [{ path: 'force-app', default: true }]; } getDefaultPackageDirectory() { const dirs = this.getPackageDirectories(); const defaultDir = dirs.find((d) => d.default === true); return defaultDir?.path || dirs[0]?.path || 'force-app'; } getNamespace() { return this.config?.namespace || ''; } getLoginUrl() { return this.config?.sfdcLoginUrl || 'https://login.salesforce.com'; } getAllPackagePaths() { return this.getPackageDirectories().map((d) => d.path); } isValidProject() { return fs.existsSync(this.configPath); } getFullPath(relativePath) { const packageDir = this.getDefaultPackageDirectory(); return path.join(this.projectPath, packageDir, relativePath); } } // Export for use in other modules module.exports = SfdxProjectConfig; // Usage example: // const config = new SfdxProjectConfig(); // console.log('API Version:', config.getApiVersion()); // console.log('Package Directory:', config.getDefaultPackageDirectory()); ``` ### Python Implementation ```python import json import os from pathlib import Path from typing import Dict, List, Optional class SfdxProjectConfig: def __init__(self, project_path: str = None): self.project_path = project_path or os.getcwd() self.config_path = Path(self.project_path) / 'sfdx-project.json' self.config = self._load_config() def _load_config(self) -> Dict: """Load sfdx-project.json configuration""" if self.config_path.exists(): try: with open(self.config_path, 'r') as f: return json.load(f) except Exception as e: print(f"Error reading sfdx-project.json: {e}") return self._get_default_config() else: print("sfdx-project.json not found. Using defaults.") return self._get_default_config() def _get_default_config(self) -> Dict: """Return default configuration""" return { 'packageDirectories': [{'path': 'force-app', 'default': True}], 'sourceApiVersion': '63.0', 'namespace': '', 'sfdcLoginUrl': 'https://login.salesforce.com' } def get_api_version(self) -> str: """Get the source API version""" return self.config.get('sourceApiVersion', '63.0') def get_package_directories(self) -> List[Dict]: """Get all package directories""" return self.config.get('packageDirectories', [{'path': 'force-app', 'default': True}]) def get_default_package_directory(self) -> str: """Get the default package directory path""" dirs = self.get_package_directories() for d in dirs: if d.get('default', False): return d['path'] return dirs[0]['path'] if dirs else 'force-app' def get_namespace(self) -> str: """Get the namespace""" return self.config.get('namespace', '') def is_valid_project(self) -> bool: """Check if this is a valid SFDX project""" return self.config_path.exists() # Usage example: # config = SfdxProjectConfig() # print(f"API Version: {config.get_api_version()}") # print(f"Package Directory: {config.get_default_package_directory()}") ``` ## Integration with Agents When agents need to execute Salesforce commands, they should: 1. **Check for valid project** ```bash if [ ! -f "sfdx-project.json" ]; then echo "Please navigate to a Salesforce DX project directory" exit 1 fi ``` 2. **Read configuration dynamically** ```bash API_VERSION=$(cat sfdx-project.json | grep sourceApiVersion | sed 's/.*"sourceApiVersion": "\(.*\)".*/\1/') PACKAGE_DIR=$(cat sfdx-project.json | jq -r '.packageDirectories[0].path') ``` 3. **Use configuration in commands** ```bash sf project deploy start \ --source-dir "$PACKAGE_DIR" \ --api-version "$API_VERSION" \ --target-org myorg ``` ## Error Handling Always include proper error handling: ```bash # Function to safely get project config get_project_config() { local config_file="sfdx-project.json" if [ ! -f "$config_file" ]; then echo "Error: $config_file not found" >&2 echo "Are you in a Salesforce DX project directory?" >&2 return 1 fi # Validate JSON format if ! jq empty "$config_file" 2>/dev/null; then echo "Error: Invalid JSON in $config_file" >&2 return 1 fi return 0 } # Use before any SF command if get_project_config; then # Safe to proceed with SF commands API_VERSION=$(jq -r '.sourceApiVersion' sfdx-project.json) echo "Project configured with API version: $API_VERSION" else exit 1 fi ``` ## Best Practices 1. **Never hardcode paths** - Always read from sfdx-project.json 2. **Never hardcode API versions** - Always read from sfdx-project.json 3. **Check for project validity** before executing commands 4. **Provide helpful error messages** when project config is missing 5. **Use fallback values** only when explicitly needed 6. **Log configuration values** for debugging purposes ## Sample sfdx-project.json Structure ```json { "packageDirectories": [ { "path": "force-app", "default": true } ], "name": "MyProject", "namespace": "", "sfdcLoginUrl": "https://login.salesforce.com", "sourceApiVersion": "63.0" } ``` This utility ensures that all Salesforce operations use the correct project-specific configuration rather than hardcoded values.