"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SalesforceToolingClient = void 0;
const logger_1 = __importDefault(require("../utils/logger"));
const errorHandler_1 = require("../utils/errorHandler");
const rateLimiter_1 = require("../utils/rateLimiter");
class SalesforceToolingClient {
constructor(connection, rateLimitConfig) {
this.conn = null;
this.connection = connection;
const defaultConfig = {
maxRequestsPerSecond: 5,
maxRequestsPerHour: 5000,
retryAttempts: 3,
baseDelay: 1000
};
this.rateLimiter = new rateLimiter_1.RateLimiter(rateLimitConfig || defaultConfig);
}
async authenticate() {
try {
const username = process.env.SF_USERNAME;
const password = process.env.SF_PASSWORD;
const securityToken = process.env.SF_SECURITY_TOKEN;
if (!username || !password || !securityToken) {
throw new errorHandler_1.AppError('Missing Salesforce credentials', 400);
}
this.conn = await this.connection.connectWithOAuth(username, password, securityToken);
logger_1.default.info('Successfully authenticated with Salesforce for Tooling API');
}
catch (error) {
logger_1.default.error('Failed to authenticate with Salesforce', { error });
throw new errorHandler_1.AppError('Salesforce authentication failed', 401);
}
}
async executeQuery(soql) {
if (!this.conn) {
throw new errorHandler_1.AppError('Not authenticated', 401);
}
try {
logger_1.default.debug('Executing Tooling API query', { soql });
const result = await this.rateLimiter.executeWithRateLimit(async () => {
return await this.conn.tooling.query(soql);
});
logger_1.default.debug('Tooling query completed', { recordCount: result.records?.length || 0 });
return result;
}
catch (error) {
logger_1.default.error('Failed to execute Tooling API query', { error, soql });
throw new errorHandler_1.AppError('Tooling API query failed', 500);
}
}
async getApexClasses() {
const query = 'SELECT Id, Name, Body, Status, CreatedDate, LastModifiedDate FROM ApexClass';
const result = await this.executeQuery(query);
return result.records || [];
}
async getApexTriggers() {
const query = 'SELECT Id, Name, Body, TableEnumOrId, CreatedDate, LastModifiedDate FROM ApexTrigger';
const result = await this.executeQuery(query);
return result.records || [];
}
async getValidationRules() {
const query = `SELECT Id, ValidationName, EntityDefinition.QualifiedApiName,
Active, ErrorMessage, ErrorDisplayField, Description, Formula
FROM ValidationRule`;
const result = await this.executeQuery(query);
return result.records || [];
}
async getApexClassByName(className) {
const query = `SELECT Id, Name, Body, Status, CreatedDate, LastModifiedDate
FROM ApexClass WHERE Name = '${className}'`;
const result = await this.executeQuery(query);
return result.records?.[0] || null;
}
getRateLimitStats() {
return this.rateLimiter.getStats();
}
}
exports.SalesforceToolingClient = SalesforceToolingClient;