salesforce-data-dictionary
Version:
MCP server for Salesforce Data Dictionary Generation
127 lines (126 loc) • 5.09 kB
JavaScript
import { execSync } from "child_process";
import { writeFileSync } from "fs";
export class SalesforceManager {
async listAllObjects() {
try {
const result = execSync('sf sobject list --sobject all', { encoding: 'utf8' });
const lines = result.split('\n').filter(line => line.trim());
// Parse the output to extract object names
// The output format is typically: "ObjectName\tLabel\tDescription"
const objectNames = lines
.slice(1) // Skip header line
.map(line => {
const parts = line.split('\t');
return parts[0]?.trim();
})
.filter(name => name && name.length > 0);
return objectNames;
}
catch (error) {
throw new Error(`Failed to list Salesforce objects: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async describeObject(objectName) {
try {
const result = execSync(`sf sobject describe --sobject ${objectName}`, { encoding: 'utf8' });
const data = JSON.parse(result);
const fields = data.fields.map((field) => ({
name: field.name,
type: field.type,
label: field.label,
description: field.inlineHelpText || field.description,
required: field.nillable === false,
unique: field.unique,
length: field.length,
precision: field.precision,
scale: field.scale,
defaultValue: field.defaultValue,
picklistValues: field.picklistValues?.map((pv) => ({
value: pv.value,
label: pv.label
})),
referenceTo: field.referenceTo,
relationshipName: field.relationshipName
}));
return {
name: data.name,
label: data.label,
description: data.description,
fields,
isCustom: data.custom,
isQueryable: data.queryable,
isCreateable: data.createable,
isUpdateable: data.updateable,
isDeletable: data.deletable
};
}
catch (error) {
throw new Error(`Failed to describe Salesforce object '${objectName}': ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async findSimilarObjects(searchTerm) {
const allObjects = await this.listAllObjects();
const searchLower = searchTerm.toLowerCase();
return allObjects.filter(objName => objName.toLowerCase().includes(searchLower) ||
objName.toLowerCase().replace(/_/g, '').includes(searchLower));
}
generateCSV(object) {
const headers = [
'Field Name',
'Type',
'Label',
'Description',
'Required',
'Unique',
'Length',
'Precision',
'Scale',
'Default Value',
'Picklist Values',
'Reference To',
'Relationship Name'
];
const rows = object.fields.map(field => [
field.name,
field.type,
field.label,
field.description || '',
field.required ? 'Yes' : 'No',
field.unique ? 'Yes' : 'No',
field.length?.toString() || '',
field.precision?.toString() || '',
field.scale?.toString() || '',
field.defaultValue || '',
field.picklistValues ? field.picklistValues.map(pv => `${pv.value} (${pv.label})`).join('; ') : '',
field.referenceTo ? field.referenceTo.join(', ') : '',
field.relationshipName || ''
]);
const csvContent = [
headers.join(','),
...rows.map(row => row.map(cell => `"${cell.replace(/"/g, '""')}"`).join(','))
].join('\n');
return csvContent;
}
saveCSVToFile(csvContent, filename) {
writeFileSync(filename, csvContent, 'utf8');
}
generateObjectSummary(object) {
const fieldCount = object.fields.length;
const requiredFields = object.fields.filter(f => f.required).length;
const customFields = object.fields.filter(f => f.name.includes('__c')).length;
const standardFields = fieldCount - customFields;
return `Salesforce Object: ${object.name} (${object.label})
Description: ${object.description || 'No description available'}
Total Fields: ${fieldCount}
- Required Fields: ${requiredFields}
- Standard Fields: ${standardFields}
- Custom Fields: ${customFields}
Permissions:
- Queryable: ${object.isQueryable ? 'Yes' : 'No'}
- Createable: ${object.isCreateable ? 'Yes' : 'No'}
- Updateable: ${object.isUpdateable ? 'Yes' : 'No'}
- Deletable: ${object.isDeletable ? 'Yes' : 'No'}
- Custom Object: ${object.isCustom ? 'Yes' : 'No'}`;
}
}
//# sourceMappingURL=salesforceManager.js.map