afv-library/skills/platform-data-and-tooling-api-context-get/examples/javascript_section_loading.js

98 lines
4.4 KiB
JavaScript

/**
* Salesforce Data + Tooling API - Section-Specific Loading Examples (Node.js)
*
* Demonstrates loading only the sections you need from the enterprise (SOQL/DML
* sObject) and Tooling (developer record) JSON files, and how to traverse this
* skill's surface-specific structure:
* - enterprise `fields` carry query/DML `properties` (Create/Filter/Sort/Group/
* Nillable/Update) plus relationship metadata (relationship_name / refers_to)
* - `field_reference` is a SEPARATE catalog, not a subset of `fields`
* - Tooling records expose supported_rest_api_http_methods / supported_soap_calls
*
* CRITICAL: Do NOT Read/cat these JSON files whole — Account.json etc. carry a
* huge wsdl_segment. Extract only the section you need.
*/
const fs = require('fs');
const path = require('path');
const ENTERPRISE_DIR = ['assets', 'enterprise_api'];
const TOOLING_DIR = ['assets', 'tooling_api'];
function load(dirParts, file) {
return JSON.parse(fs.readFileSync(path.join(...dirParts, file), 'utf-8'));
}
// Example 1: Load ONLY the 'fields' section from an enterprise sObject
function loadFieldsSection() {
console.log('Example 1: enterprise fields section');
const data = load(ENTERPRISE_DIR, 'Account.json');
const fields = data.fields || {};
// Skip wsdl_segment (verbose) and field_reference (load separately if needed)
console.log(`Account has ${Object.keys(fields).length} fields in the 'fields' section`);
}
// Example 2: Find filterable fields (usable in a SOQL WHERE clause)
//
// The `properties` string controls capability: Filter -> WHERE, Sort ->
// ORDER BY, Group -> GROUP BY, Create/Update -> DML. Compare case-insensitively.
function findFilterableFields() {
console.log('\nExample 2: filterable fields (WHERE-safe)');
const data = load(ENTERPRISE_DIR, 'Opportunity.json');
const filterable = Object.entries(data.fields || {})
.filter(([, meta]) => (meta.properties || '').toLowerCase().includes('filter'))
.map(([name]) => name);
console.log(`Opportunity has ${filterable.length} filterable fields; first 5: ${filterable.slice(0, 5).join(', ')}`);
}
// Example 3: Traverse a relationship (reference field -> parent object)
//
// relationship_name is the SOQL traversal path; refers_to names the target.
function traverseRelationship() {
console.log('\nExample 3: relationship traversal');
const data = load(ENTERPRISE_DIR, 'Contact.json');
const account = (data.fields || {}).AccountId || {};
console.log(`AccountId -> relationship_name=${account.relationship_name} refers_to=${account.refers_to}`);
console.log('SOQL: SELECT Id, Account.Name FROM Contact');
}
// Example 4: Check BOTH catalogs — field_reference is NOT a subset of fields
//
// System/audit fields (Id, CreatedDate, ...) frequently live ONLY in
// field_reference. If a field isn't in `fields`, check `field_reference`.
function checkBothCatalogs() {
console.log('\nExample 4: fields vs field_reference (dual catalog)');
const data = load(ENTERPRISE_DIR, 'Account.json');
const fields = new Set(Object.keys(data.fields || {}));
const ref = Object.keys(data.field_reference || {});
const onlyInRef = ref.filter((k) => !fields.has(k));
console.log(`Account: fields=${fields.size} field_reference=${ref.length}`);
console.log(`Only in field_reference (first 5): ${onlyInRef.slice(0, 5).join(', ')}`);
}
// Example 5: Tooling record — check supported HTTP methods before querying
//
// Tooling objects query against /services/data/vXX.0/tooling/query, not the
// regular Data API. Many are read-only; check the methods first.
function toolingSupportedMethods() {
console.log('\nExample 5: Tooling API supported methods');
const data = load(TOOLING_DIR, 'ApexClass.json');
console.log(`ApexClass REST methods: ${data.supported_rest_api_http_methods || ''}`);
console.log(`First 5 ApexClass fields: ${Object.keys(data.fields || {}).slice(0, 5).join(', ')}`);
}
// WRONG APPROACH - DO NOT USE
// fs.readFileSync('assets/enterprise_api/Account.json') // then use whole object
// loads the huge wsdl_segment into memory. Extract only the section you need.
if (require.main === module) {
console.log('Salesforce Data + Tooling API - Section-Specific Loading (Node.js)');
console.log('==================================================================');
console.log('');
loadFieldsSection();
findFilterableFields();
traverseRelationship();
checkBothCatalogs();
toolingSupportedMethods();
}