Skip to main content

API Reference

Functions

evaluateFormula(formula, context, options?)

Parse and evaluate a formula in a single call. This is the simplest way to use the library.

import { evaluateFormula } from '@jetstreamapp/sf-formula-parser';

const result = evaluateFormula('UPPER(LEFT(Name, 3))', { record: { Name: 'Acme Corp' } });
// "ACM"

Parameters:

ParameterTypeDescription
formulastringThe Salesforce formula string
contextFormulaContextThe record to evaluate against
optionsEvaluationOptionsOptional evaluation settings

Returns: FormulaValue — the result of evaluating the formula.


parseFormula(formula)

Parse a formula string into an AST without evaluating it. Useful for caching parsed formulas, building linters, or inspecting formula structure.

import { parseFormula } from '@jetstreamapp/sf-formula-parser';

const ast = parseFormula('1 + 2 * 3');
// Returns an ASTNode tree

Parameters:

ParameterTypeDescription
formulastringThe Salesforce formula string

Returns: ASTNode — the root node of the parsed AST.


createEvaluator(registry?, context?, options?)

Create a reusable Evaluator instance. Useful when evaluating many formulas against the same context, or when using a custom function registry.

import { createEvaluator, createDefaultRegistry } from '@jetstreamapp/sf-formula-parser';

const evaluator = createEvaluator(createDefaultRegistry(), { record: { Status: 'Active', Amount: 100 } });

Parameters:

ParameterTypeDefaultDescription
registryFunctionRegistryDefault registryFunction registry to use
contextFormulaContext{ record: {} }Record context
optionsEvaluationOptionsundefinedEvaluation options

Returns: Evaluator


createDefaultRegistry()

Create a FunctionRegistry pre-loaded with all 90+ built-in Salesforce functions.

import { createDefaultRegistry } from '@jetstreamapp/sf-formula-parser';

const registry = createDefaultRegistry();

Returns: FunctionRegistry


extractFields(formula)

Extract all field references from a formula string without evaluating it. Returns a deduplicated array of field names in the order they appear. Useful for determining which fields to query before evaluation.

import { extractFields } from '@jetstreamapp/sf-formula-parser';

const fields = extractFields('IF(Amount > 100, $User.FirstName, Name)');
// ['Amount', '$User.FirstName', 'Name']

Parameters:

ParameterTypeDescription
formulastringThe Salesforce formula string

Returns: string[] — deduplicated array of dot-joined field reference strings.


extractFieldsByCategory(formula)

Extract and categorize field references from a formula string. Fields are grouped by their $-prefix into object fields, globals, custom metadata, custom labels, custom settings, and custom permissions.

import { extractFieldsByCategory } from '@jetstreamapp/sf-formula-parser';

const result = extractFieldsByCategory('IF($User.IsActive, $Label.Greeting & " " & Name, $Setup.Default__c.Value__c)');
// {
// objectFields: ['Name'],
// globals: { '$User': ['$User.IsActive'] },
// customMetadata: [],
// customLabels: ['$Label.Greeting'],
// customSettings: ['$Setup.Default__c.Value__c'],
// customPermissions: [],
// }

Parameters:

ParameterTypeDescription
formulastringThe Salesforce formula string

Returns: ExtractedFields — categorized field references.


walkAST(node, visitor)

Walk an AST tree in pre-order, calling the visitor function on each node. Useful for building custom analysis tools on top of the parsed AST.

import { parseFormula, walkAST } from '@jetstreamapp/sf-formula-parser';

const ast = parseFormula('IF(Amount > 100, Name, "default")');
const functionNames: string[] = [];

walkAST(ast, node => {
if (node.type === 'FunctionCall') {
functionNames.push(node.name);
}
});
// functionNames: ['IF']

Parameters:

ParameterTypeDescription
nodeASTNodeThe root AST node to start walking
visitor(node: ASTNode) => voidCallback invoked on each node

Classes

FunctionRegistry

A registry that maps function names to implementations. Case-insensitive.

import { FunctionRegistry } from '@jetstreamapp/sf-formula-parser';

const registry = new FunctionRegistry();

// Register a custom function
registry.register('DOUBLE', ctx => {
const val = ctx.evaluate(ctx.args[0]);
return (val as number) * 2;
});

Methods:

MethodDescription
register(name, fn)Register a function by name
get(name)Get a function by name (returns undefined if not found)
has(name)Check if a function is registered

Evaluator

The tree-walking evaluator. Evaluates an AST node against a record context.

import { Evaluator, createDefaultRegistry } from '@jetstreamapp/sf-formula-parser';

const evaluator = new Evaluator(createDefaultRegistry(), { record: { x: 10 } });

Parser

The Pratt parser. Converts a formula string into an AST.

import { Parser } from '@jetstreamapp/sf-formula-parser';

const ast = Parser.parse('1 + 2');

Types

FormulaValue

type FormulaValue = number | string | boolean | Date | SfTime | GeoLocation | null;

The result type of any formula evaluation.

FormulaRecord

type FormulaRecord = { [key: string]: FormulaValue | FormulaRecord };

A flat record where field values and related records coexist as keys — the same shape as a SOQL query result.

FormulaContext

interface FormulaContext {
record: FormulaRecord;
globals?: Record<string, FormulaRecord>;
priorRecord?: FormulaRecord;
isNew?: boolean;
isClone?: boolean;
}

See Record Context for full documentation.

EvaluationOptions

interface EvaluationOptions {
treatBlanksAsZeroes?: boolean; // default: true
now?: Date; // override current time
}
OptionDefaultDescription
treatBlanksAsZeroestrueWhen true, null/blank numeric fields are treated as 0 and blank text fields as "". Matches the Salesforce default.
nownew Date()Override the current timestamp. Useful for deterministic tests with NOW() and TODAY().

ExtractedFields

interface ExtractedFields {
objectFields: string[]; // Regular fields (no $ prefix)
globals: Record<string, string[]>; // e.g. { '$User': ['$User.FirstName'] }
customMetadata: string[]; // $CustomMetadata.* fields
customLabels: string[]; // $Label.* fields
customSettings: string[]; // $Setup.* fields
customPermissions: string[]; // $Permission.* fields
}

Returned by extractFieldsByCategory(). The globals map uses the original $-prefix as the key (e.g., $User, $Organization, $Profile, $UserRole, $System, $Api).

ASTNode

The discriminated union type representing parsed formula nodes. Includes types for literals, field references, function calls, binary/unary operations, and more.

SfTime

interface SfTime {
timeInMillis: number; // 0–86400000 (ms since midnight, GMT)
}

GeoLocation

interface GeoLocation {
latitude: number;
longitude: number;
}

Error Classes

FormulaError

Base error class for all formula errors.

LexerError extends FormulaError

Thrown when the formula string contains invalid tokens. Includes line and column properties.

ParseError extends FormulaError

Thrown when the formula has a syntax error. Includes line and column properties.

import { FormulaError, LexerError, ParseError } from '@jetstreamapp/sf-formula-parser';

try {
evaluateFormula('IF(', { record: {} });
} catch (e) {
if (e instanceof ParseError) {
console.log(e.line, e.column); // position of the error
}
}

See Error Handling for more details.

Utility Functions

The library also exports helper functions for type checking and coercion:

FunctionDescription
isBlank(value)Check if a value is null, undefined, or empty string
isSfTime(value)Type guard for SfTime values
isGeoLocation(value)Type guard for GeoLocation values
isDate(value)Type guard for Date values
isFormulaValue(value)Type guard — true for field values, false for nested records
isFormulaRecord(value)Type guard — true for nested records
toNumber(value)Coerce a formula value to a number
toText(value)Coerce a formula value to a string
toBoolean(value)Coerce a formula value to a boolean