mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-07-30 11:43:26 +08:00
163 lines
4.5 KiB
JavaScript
163 lines
4.5 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Salesforce Metadata API - Section-Specific Loading Examples (JavaScript/Node.js)
|
|
*
|
|
* This file demonstrates how to programmatically load only specific sections
|
|
* from metadata JSON files, avoiding the token waste of loading entire files.
|
|
*
|
|
* ⚠️ CRITICAL: Do NOT use built-in Read tools on these JSON files!
|
|
* Use this programmatic approach instead.
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
|
|
/**
|
|
* Read and parse a metadata JSON file, with a clear error on malformed JSON.
|
|
*/
|
|
function loadMetadataJson(metadataFile) {
|
|
const fileContent = fs.readFileSync(metadataFile, 'utf-8');
|
|
try {
|
|
return JSON.parse(fileContent);
|
|
} catch (e) {
|
|
throw new Error(`Failed to parse ${metadataFile}: ${e.message}`);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Example 1: Load ONLY the 'fields' section from CustomObject.json
|
|
*
|
|
* Token savings: ~70-80% compared to loading entire file
|
|
*/
|
|
function loadSingleSectionExample() {
|
|
const metadataFile = path.join('data', 'metadata_api', 'CustomObject.json');
|
|
|
|
// Read and parse the JSON file
|
|
const data = loadMetadataJson(metadataFile);
|
|
|
|
// Extract only the 'fields' section
|
|
const fieldsOnly = data.fields || {};
|
|
|
|
// Use only 'fields', ignore wsdl_segment and other sections
|
|
console.log(`Loaded ${Object.keys(fieldsOnly).length} fields from CustomObject`);
|
|
return fieldsOnly;
|
|
}
|
|
|
|
|
|
/**
|
|
* Example 2: Load ONLY 'description' and 'fields' sections from Flow.json
|
|
*
|
|
* Token savings: ~60-75% compared to loading entire file
|
|
*/
|
|
function loadMultipleSectionsExample() {
|
|
const metadataFile = path.join('data', 'metadata_api', 'Flow.json');
|
|
|
|
const data = loadMetadataJson(metadataFile);
|
|
|
|
// Extract only needed sections
|
|
const description = data.description || '';
|
|
const fields = data.fields || {};
|
|
|
|
// Skip: wsdl_segment, declarative_metadata_sample_definition, etc.
|
|
console.log(`Loaded description and ${Object.keys(fields).length} fields from Flow`);
|
|
return { description, fields };
|
|
}
|
|
|
|
|
|
/**
|
|
* Example 3: Check available sections first, then load specific ones
|
|
*
|
|
* Best practice: Always check what sections are available
|
|
*/
|
|
function loadWithSectionCheck() {
|
|
const metadataFile = path.join('data', 'metadata_api', 'Profile.json');
|
|
|
|
const data = loadMetadataJson(metadataFile);
|
|
|
|
// Check available sections
|
|
const availableSections = data.sections || [];
|
|
console.log(`Available sections: ${availableSections.join(', ')}`);
|
|
|
|
// Load only specific sections you need
|
|
const result = {};
|
|
if (availableSections.includes('fields')) {
|
|
result.fields = data.fields || {};
|
|
}
|
|
if (availableSections.includes('description')) {
|
|
result.description = data.description || '';
|
|
}
|
|
|
|
// Explicitly ignore verbose sections
|
|
// - wsdl_segment (very large, rarely needed)
|
|
// - file_information (not needed for field definitions)
|
|
// - directory_location (not needed for field definitions)
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* Example 4: Async/Promise version (modern Node.js)
|
|
*/
|
|
async function loadSingleSectionAsync() {
|
|
const metadataFile = path.join('data', 'metadata_api', 'ApexClass.json');
|
|
|
|
// Use async file operations
|
|
const fileContent = await fs.promises.readFile(metadataFile, 'utf-8');
|
|
let data;
|
|
try {
|
|
data = JSON.parse(fileContent);
|
|
} catch (e) {
|
|
throw new Error(`Failed to parse ${metadataFile}: ${e.message}`);
|
|
}
|
|
|
|
// Extract only the sections you need
|
|
const fields = data.fields || {};
|
|
const description = data.description || '';
|
|
|
|
return { fields, description };
|
|
}
|
|
|
|
|
|
/**
|
|
* ❌ WRONG APPROACH - DO NOT USE
|
|
*
|
|
* This is what NOT to do - it loads the entire file into context:
|
|
*
|
|
* // Read tool approach (WRONG):
|
|
* // Read data/metadata_api/CustomObject.json // Loads ALL sections!
|
|
*
|
|
* // This injects the entire file (including massive WSDL segments)
|
|
* // into your context, wasting 60-80% of tokens.
|
|
*/
|
|
function wrongApproachExample() {
|
|
// Don't do this!
|
|
}
|
|
|
|
|
|
// Run examples
|
|
if (require.main === module) {
|
|
console.log('Example 1: Single section');
|
|
loadSingleSectionExample();
|
|
|
|
console.log('\nExample 2: Multiple sections');
|
|
loadMultipleSectionsExample();
|
|
|
|
console.log('\nExample 3: Check sections first');
|
|
loadWithSectionCheck();
|
|
|
|
console.log('\nExample 4: Async version');
|
|
loadSingleSectionAsync().then(() => {
|
|
console.log('Async loading complete');
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
loadSingleSectionExample,
|
|
loadMultipleSectionsExample,
|
|
loadWithSectionCheck,
|
|
loadSingleSectionAsync
|
|
};
|