@atomic-ehr/fhirpath
Version:
A TypeScript implementation of FHIRPath
902 lines (886 loc) • 30.1 kB
TypeScript
import { FHIRSchema } from '@atomic-ehr/fhirschema';
/**
* Symbol to mark boxed values
*/
declare const BOXED_SYMBOL: unique symbol;
/**
* Extension structure for FHIR primitive elements
*/
interface Extension {
url: string;
[key: string]: any;
}
/**
* Metadata for FHIR primitive elements (e.g., _gender for gender property)
*/
interface PrimitiveElement {
id?: string;
extension?: Extension[];
}
/**
* Boxed FHIRPath value with metadata
*/
interface FHIRPathValue<T = any> {
/** The actual value */
value: T;
/** Type information from ModelProvider */
typeInfo?: TypeInfo;
/** Primitive element extension (for primitives only) */
primitiveElement?: PrimitiveElement;
/** Internal marker to identify boxed values */
[BOXED_SYMBOL]: true;
}
/**
* Simplified FHIRPath Lexer
*
* This lexer only recognizes:
* - Symbol operators: +, -, *, /, <, >, =, etc. (all as OPERATOR tokens)
* - Structural tokens: (, ), [, ], {, }, ., ,
* - Literals: numbers, strings, datetime, time
* - Identifiers: any alphabetic sequence (including all keywords)
* - Special identifiers: $... (context variables like $this, $index)
* - Environment variables: %identifier, %`delimited`, %'string'
*
* The parser is responsible for determining which identifiers are keyword operators.
*/
declare enum TokenType {
EOF = 0,
IDENTIFIER = 1,
NUMBER = 2,
STRING = 3,
DATETIME = 4,
TIME = 5,
QUANTITY = 6,// Quantity literals like 5 'mg'
OPERATOR = 10,// +, -, *, /, <, >, <=, >=, =, !=, ~, !~, |, &
DOT = 50,// .
COMMA = 51,// ,
LPAREN = 52,// (
RPAREN = 53,// )
LBRACKET = 54,// [
RBRACKET = 55,// ]
LBRACE = 56,// {
RBRACE = 57,// }
SPECIAL_IDENTIFIER = 60,// $...
ENVIRONMENT_VARIABLE = 70,// %identifier, %`delimited`, %'string'
CURSOR = 71,// Virtual cursor token for LSP support
WHITESPACE = 80,
LINE_COMMENT = 81,
BLOCK_COMMENT = 82
}
declare enum Channel {
DEFAULT = 0,
HIDDEN = 1
}
interface Token {
type: TokenType;
value: string;
start: number;
end: number;
line: number;
column: number;
range?: Range;
channel?: Channel;
}
interface LexerOptions {
trackPosition?: boolean;
preserveTrivia?: boolean;
}
declare class Lexer {
private input;
private position;
private line;
private column;
private lspLine;
private lspCharacter;
private options;
private lineOffsets;
constructor(input: string, options?: LexerOptions);
/**
* Build line offset map for efficient position conversions
*/
private buildLineOffsets;
tokenize(): Token[];
private nextToken;
private readIdentifier;
private readDelimitedIdentifier;
private readSpecialIdentifier;
private readEnvironmentVariable;
private readString;
private readNumber;
private readDateTimeOrTime;
private readDateTime;
private readTime;
private readTimeFormat;
private readTimezone;
private skipWhitespace;
private skipLineComment;
private skipBlockComment;
private advance;
private current;
private peek;
private isDigit;
private isWhitespace;
/**
* Convert absolute offset to LSP Position
*/
private offsetToPosition;
private createToken;
private error;
/**
* Get the text value for a token
*/
getTokenText(token: Token): string;
/**
* Check if a token is an identifier (including keyword operators)
*/
static isIdentifier(token: Token): boolean;
/**
* Check if a token could be a keyword operator (parser decides)
*/
static couldBeKeywordOperator(token: Token): boolean;
}
declare enum PRECEDENCE {
IMPLIES = 10,
OR = 20,
XOR = 30,
AND = 40,
IN_CONTAINS = 50,
EQUALITY = 60,// =, !=, ~, !~
COMPARISON = 70,// <, >, <=, >=
PIPE = 80,// |
ADDITIVE = 90,// +, -
MULTIPLICATIVE = 100,// *, /, div, mod
UNARY = 110,// unary +, -, not
AS_IS = 120,// as, is
POSTFIX = 130,// []
DOT = 140
}
type TypeName = 'Any' | 'Boolean' | 'String' | 'Integer' | 'Long' | 'Decimal' | 'Date' | 'DateTime' | 'Time' | 'Quantity';
interface TypeInfo<TypeContext = unknown> {
type: TypeName;
singleton?: boolean;
namespace?: string;
name?: string;
modelContext?: TypeContext;
}
interface ModelProvider<TypeContext = unknown> {
getType(typeName: string): Promise<TypeInfo<TypeContext> | undefined>;
getElementType(parentType: TypeInfo<TypeContext>, propertyName: string): Promise<TypeInfo<TypeContext> | undefined>;
ofType(type: TypeInfo<TypeContext>, typeName: TypeName): TypeInfo<TypeContext> | undefined;
getElementNames(parentType: TypeInfo<TypeContext>): string[];
getChildrenType(parentType: TypeInfo<TypeContext>): Promise<TypeInfo<TypeContext> | undefined>;
getElements(typeName: string): Promise<Array<{
name: string;
type: string;
documentation?: string;
}>>;
getResourceTypes(): Promise<string[]>;
getComplexTypes(): Promise<string[]>;
getPrimitiveTypes(): Promise<string[]>;
}
interface OperatorSignature {
name: string;
left: TypeInfo;
right: TypeInfo;
result: TypeInfo | 'inputType' | 'leftType' | 'rightType';
}
interface OperatorDefinition {
symbol: string;
name: string;
category: string[];
precedence: PRECEDENCE;
associativity: 'left' | 'right';
description: string;
examples: string[];
signatures: OperatorSignature[];
evaluate: OperationEvaluator;
}
interface FunctionSignature {
name: string;
input: TypeInfo;
parameters: Array<{
name: string;
optional?: boolean;
type: TypeInfo;
expression?: boolean;
}>;
result: TypeInfo | 'inputType' | 'inputTypeSingleton' | 'parameterType';
}
interface FunctionDefinition {
name: string;
category: string[];
description: string;
examples: string[];
signatures: FunctionSignature[];
evaluate: FunctionEvaluator;
}
declare enum NodeType {
EOF = "EOF",
Binary = "Binary",
Unary = "Unary",
TypeOrIdentifier = "TypeOrIdentifier",
Identifier = "Identifier",
Literal = "Literal",
Function = "Function",
Variable = "Variable",
Index = "Index",
MembershipTest = "MembershipTest",
TypeCast = "TypeCast",
Collection = "Collection",
TypeReference = "TypeReference",
Quantity = "Quantity"
}
interface Position {
line: number;
character: number;
offset?: number;
}
interface Range {
start: Position;
end: Position;
}
declare enum SymbolKind {
Function = 12,
Variable = 13,
Property = 7,
Field = 8,
Method = 6
}
interface TriviaInfo {
type: 'whitespace' | 'comment' | 'lineComment';
value: string;
range: Range;
}
interface BaseASTNode {
type: NodeType | 'Error';
range: Range;
parent?: ASTNode;
children?: ASTNode[];
leadingTrivia?: TriviaInfo[];
trailingTrivia?: TriviaInfo[];
raw?: string;
id?: string;
symbolKind?: SymbolKind;
typeInfo?: TypeInfo;
}
interface ErrorNode extends BaseASTNode {
type: 'Error';
message: string;
expected?: string[];
severity?: DiagnosticSeverity;
code?: string | number;
source?: string;
}
interface IdentifierNode extends BaseASTNode {
type: NodeType.Identifier;
name: string;
symbolKind?: SymbolKind.Variable | SymbolKind.Function | SymbolKind.Property;
}
interface TypeOrIdentifierNode extends BaseASTNode {
type: NodeType.TypeOrIdentifier;
name: string;
}
interface LiteralNode extends BaseASTNode {
type: NodeType.Literal;
value: any;
valueType: 'string' | 'number' | 'boolean' | 'date' | 'time' | 'datetime' | 'null';
}
interface BinaryNode extends BaseASTNode {
type: NodeType.Binary;
operator: string;
left: ASTNode;
right: ASTNode;
}
interface UnaryNode extends BaseASTNode {
type: NodeType.Unary;
operator: string;
operand: ASTNode;
}
interface FunctionNode extends BaseASTNode {
type: NodeType.Function;
name: ASTNode;
arguments: ASTNode[];
symbolKind?: SymbolKind.Function;
detail?: string;
}
interface VariableNode extends BaseASTNode {
type: NodeType.Variable;
name: string;
}
interface IndexNode extends BaseASTNode {
type: NodeType.Index;
expression: ASTNode;
index: ASTNode;
}
interface MembershipTestNode extends BaseASTNode {
type: NodeType.MembershipTest;
expression: ASTNode;
targetType: string;
}
interface TypeCastNode extends BaseASTNode {
type: NodeType.TypeCast;
expression: ASTNode;
targetType: string;
}
interface CollectionNode extends BaseASTNode {
type: NodeType.Collection;
elements: ASTNode[];
}
interface TypeReferenceNode extends BaseASTNode {
type: NodeType.TypeReference;
typeName: string;
}
interface QuantityNode extends BaseASTNode {
type: NodeType.Quantity;
value: number;
unit: string;
isCalendarUnit?: boolean;
}
type ASTNode = IdentifierNode | TypeOrIdentifierNode | LiteralNode | BinaryNode | UnaryNode | FunctionNode | VariableNode | IndexNode | MembershipTestNode | TypeCastNode | CollectionNode | TypeReferenceNode | QuantityNode | ErrorNode;
interface RuntimeContext {
input: any[];
focus: any[];
variables: Record<string, any>;
currentNode?: ASTNode;
modelProvider?: ModelProvider;
}
interface EvaluationResult {
value: FHIRPathValue[];
context: RuntimeContext;
}
declare enum DiagnosticSeverity {
Error = 1,
Warning = 2,
Information = 3,
Hint = 4
}
interface Diagnostic {
range: Range;
severity?: DiagnosticSeverity;
code?: string;
source?: string;
message: string;
tags?: number[];
relatedInformation?: any[];
data?: any;
}
interface AnalysisResult {
diagnostics: Diagnostic[];
ast: ASTNode;
}
interface ParseError {
message: string;
position: Position;
range?: Range;
token?: Token;
}
interface ParseResult {
ast: ASTNode;
errors: ParseError[];
indexes?: {
nodeById: Map<string, ASTNode>;
nodesByType: Map<NodeType | 'Error', ASTNode[]>;
identifiers: Map<string, ASTNode[]>;
};
cursorContext?: {
node: ASTNode | null;
expectedTokens: TokenType[];
availableCompletions: string[];
};
}
type OperationEvaluator = (input: FHIRPathValue[], context: RuntimeContext, ...args: any[]) => Promise<EvaluationResult>;
type FunctionEvaluator = (input: FHIRPathValue[], context: RuntimeContext, args: ASTNode[], evaluator: (node: ASTNode, input: FHIRPathValue[], context: RuntimeContext) => Promise<EvaluationResult>) => Promise<EvaluationResult>;
interface ParserOptions {
mode?: 'simple' | 'lsp';
preserveTrivia?: boolean;
buildIndexes?: boolean;
errorRecovery?: boolean;
partialParse?: {
cursorPosition: number;
};
cursorPosition?: number;
}
declare class Parser {
protected lexer: Lexer;
protected tokens: Token[];
protected current: number;
private mode;
private options;
private errors?;
private nodeIdCounter?;
private nodeIndex?;
private nodesByType?;
private identifierIndex?;
private currentParent?;
private input;
private readonly synchronizationTokens;
constructor(input: string, options?: ParserOptions);
private checkCursor;
private injectCursorToken;
private getRangeFromToken;
private getRangeFromTokens;
private getRangeFromNodes;
parse(): ParseResult;
private parseSimple;
private parseLSP;
protected expression(): ASTNode;
protected parseExpressionWithPrecedence(minPrecedence: number): ASTNode;
protected parsePrimary(): ASTNode;
protected parseInvocation(): ASTNode;
protected parseArgumentList(): ASTNode[];
protected parseCollectionElements(): ASTNode[];
protected parseTypeName(): string;
protected parseStringValue(raw: string): string;
protected parseIdentifierValue(raw: string): string;
protected isFunctionCall(node: ASTNode): boolean;
protected isBinaryOperatorToken(token: Token): boolean;
protected isKeywordAllowedAsMember(token: Token): boolean;
protected isKeywordAllowedAsIdentifier(token: Token): boolean;
protected peek(): Token;
protected previous(): Token;
protected isAtEnd(): boolean;
protected advance(): Token;
protected check(type: TokenType): boolean;
protected match(...types: TokenType[]): boolean;
protected consume(type: TokenType, message: string): Token;
protected createIdentifierNode(name: string, token: Token): ASTNode;
protected createLiteralNode(value: any, valueType: LiteralNode['valueType'], token: Token): LiteralNode;
protected createBinaryNode(token: Token, left: ASTNode, right: ASTNode): BinaryNode;
protected createUnaryNode(token: Token, operand: ASTNode): UnaryNode;
protected createFunctionNode(name: ASTNode, args: ASTNode[], startToken: Token): FunctionNode;
protected createVariableNode(name: string, token: Token): VariableNode;
protected createIndexNode(expression: ASTNode, index: ASTNode, startToken: Token): IndexNode;
protected createMembershipTestNode(expression: ASTNode, targetType: string, startToken: Token): MembershipTestNode;
protected createTypeCastNode(expression: ASTNode, targetType: string, startToken: Token): TypeCastNode;
protected createCollectionNode(elements: ASTNode[], startToken: Token): CollectionNode;
protected createQuantityNode(value: number, unit: string, isCalendarUnit: boolean, startToken: Token, endToken: Token): QuantityNode;
protected handleError(message: string, token?: Token): never;
private enrichNodeForLSP;
private createErrorNode;
private addError;
private synchronize;
private findNodeAtPosition;
private getExpectedTokens;
private getExpectedTokensForError;
private getCompletions;
}
declare function parse(input: string, options?: ParserOptions): ParseResult;
declare class Registry {
private symbolOperators;
private keywordOperators;
private unaryOperators;
private functions;
constructor();
private registerDefaultOperators;
private registerOperator;
isSymbolOperator(symbol: string): boolean;
isKeywordOperator(keyword: string): boolean;
isUnaryOperator(op: string): boolean;
isBinaryOperator(op: string): boolean;
getOperatorDefinition(op: string): OperatorDefinition | undefined;
getPrecedence(op: string): number;
getAssociativity(op: string): 'left' | 'right';
getKeywordOperators(): string[];
registerFunction(def: FunctionDefinition): void;
getFunction(name: string): FunctionDefinition | undefined;
isFunction(name: string): boolean;
listFunctions(): string[];
listOperators(): string[];
listAllOperations(): string[];
getOperationInfo(name: string): OperatorDefinition | FunctionDefinition | undefined;
/**
* Get functions applicable to a specific type
*/
getFunctionsForType(typeName: TypeName | string): FunctionDefinition[];
/**
* Get operators applicable to a specific type
*/
getOperatorsForType(typeName: TypeName | string): OperatorDefinition[];
/**
* Check if a function is applicable to a type
*/
isFunctionApplicableToType(functionName: string, typeName: TypeName | string): boolean;
/**
* Check if an operator is applicable to a type
*/
isOperatorApplicableToType(operatorSymbol: string, typeName: TypeName | string): boolean;
}
declare const registry: Registry;
declare class Interpreter {
private registry;
private nodeEvaluators;
private operationEvaluators;
private functionEvaluators;
private modelProvider?;
constructor(registry?: Registry, modelProvider?: ModelProvider<any>);
private registerOperationEvaluators;
evaluate(node: ASTNode, input?: any[], context?: RuntimeContext): Promise<EvaluationResult>;
private createInitialContext;
private evaluateLiteral;
private evaluateIdentifier;
private evaluateTypeOrIdentifier;
private evaluateBinary;
private evaluateUnary;
private evaluateVariable;
private evaluateCollection;
private evaluateFunction;
private evaluateIndex;
private evaluateMembershipTest;
private evaluateTypeCast;
private evaluateQuantity;
}
declare enum CursorContext {
Operator = "operator",
Identifier = "identifier",
Argument = "argument",
Index = "index",
Type = "type"
}
interface CursorNode {
type: 'CursorNode';
context: CursorContext;
position: number;
range: {
start: {
line: number;
character: number;
offset: number;
};
end: {
line: number;
character: number;
offset: number;
};
};
}
interface CursorOperatorNode extends CursorNode {
context: CursorContext.Operator;
}
interface CursorIdentifierNode extends CursorNode {
context: CursorContext.Identifier;
}
interface CursorArgumentNode extends CursorNode {
context: CursorContext.Argument;
functionName: string;
argumentIndex: number;
}
interface CursorIndexNode extends CursorNode {
context: CursorContext.Index;
}
interface CursorTypeNode extends CursorNode {
context: CursorContext.Type;
typeOperator: 'is' | 'as' | 'ofType';
}
type AnyCursorNode = CursorOperatorNode | CursorIdentifierNode | CursorArgumentNode | CursorIndexNode | CursorTypeNode;
declare function isCursorNode(node: any): node is CursorNode;
interface AnalyzerOptions {
cursorMode?: boolean;
}
interface AnalysisResultWithCursor extends AnalysisResult {
stoppedAtCursor?: boolean;
cursorContext?: {
typeBeforeCursor?: TypeInfo;
expectedType?: TypeInfo;
cursorNode?: AnyCursorNode;
};
}
declare class Analyzer {
private diagnostics;
private variables;
private modelProvider?;
private userVariableTypes;
private systemVariableTypes;
private cursorMode;
private stoppedAtCursor;
private cursorContext?;
constructor(modelProvider?: ModelProvider);
analyze(ast: ASTNode, userVariables?: Record<string, any>, inputType?: TypeInfo, options?: AnalyzerOptions): Promise<AnalysisResultWithCursor>;
private visitNode;
private visitBinaryOperator;
private visitIdentifier;
private visitFunctionCall;
private visitMembershipTest;
private visitTypeCast;
private validateVariable;
private collectDefinedVariables;
private collectDefinedVariablesWithTypes;
private inferType;
private inferErrorNodeType;
private inferLiteralType;
private inferBinaryType;
private inferNavigationType;
private inferUnaryType;
private inferFunctionType;
private inferIdentifierType;
private inferTypeOrIdentifierType;
private inferVariableType;
private inferCollectionType;
private inferTypeCastType;
private isTypeCompatible;
private isSubtypeOf;
private isNumericType;
private inferValueType;
private resolveResultType;
private checkBinaryOperatorTypes;
private checkFunctionArgumentTypes;
private typeToString;
/**
* Infer the expected type at a cursor position based on context
*/
private inferExpectedTypeForCursor;
/**
* Annotate AST with type information
*/
private annotateAST;
}
interface FHIRModelContext {
path: string;
schemaHierarchy: FHIRSchema[];
isUnion?: boolean;
choices?: Array<{
type: TypeName;
code: string;
choiceName?: string;
schema?: FHIRSchema;
}>;
canonicalUrl?: string;
version?: string;
}
interface FHIRModelProviderConfig {
packages: Array<{
name: string;
version: string;
}>;
cacheDir?: string;
registryUrl?: string;
}
/**
* FHIR ModelProvider implementation
*
* Note: This provider requires async initialization before use.
* Call initialize() before using the synchronous methods.
*
* For best performance, pre-load common types during initialization.
*/
declare class FHIRModelProvider implements ModelProvider<FHIRModelContext> {
private config;
private canonicalManager;
private schemaCache;
private hierarchyCache;
private initialized;
private complexTypesCache?;
private primitiveTypesCache?;
private resourceTypesCache?;
private readonly typeMapping;
private readonly primitiveTypeMapping;
constructor(config?: FHIRModelProviderConfig);
initialize(): Promise<void>;
private buildCanonicalUrl;
getSchema(typeName: string): Promise<FHIRSchema | undefined>;
private getSchemaHierarchyAsync;
private extractTypeName;
private getSchemaHierarchyCached;
private mapToFHIRPathType;
private isChoiceType;
private createUnionContext;
getType(typeName: string): Promise<TypeInfo<FHIRModelContext> | undefined>;
getElementType(parentType: TypeInfo<FHIRModelContext>, propertyName: string): Promise<TypeInfo<FHIRModelContext> | undefined>;
ofType(type: TypeInfo<FHIRModelContext>, typeName: TypeName): TypeInfo<FHIRModelContext> | undefined;
getElementNames(parentType: TypeInfo<FHIRModelContext>): string[];
getChildrenType(parentType: TypeInfo<FHIRModelContext>): Promise<TypeInfo<FHIRModelContext> | undefined>;
loadType(typeName: string): Promise<TypeInfo<FHIRModelContext> | undefined>;
getElements(typeName: string): Promise<Array<{
name: string;
type: string;
documentation?: string;
}>>;
getResourceTypes(): Promise<string[]>;
getComplexTypes(): Promise<string[]>;
getPrimitiveTypes(): Promise<string[]>;
getTypeFromCache(typeName: string): TypeInfo<FHIRModelContext> | undefined;
}
interface ASTMetadata {
complexity: number;
depth: number;
operationCount: Map<string, number>;
}
interface InspectResult {
result: FHIRPathValue[];
ast: {
node: ASTNode;
metadata: ASTMetadata;
};
diagnostics: {
warnings: Diagnostic[];
hints: Array<{
message: string;
suggestion?: string;
}>;
};
performance: {
parseTime: number;
analyzeTime: number;
evalTime: number;
totalTime: number;
operationTimings: Map<string, number>;
};
traces?: Array<{
label: string;
value: FHIRPathValue[];
timestamp: number;
}>;
}
interface InspectOptions {
input?: any;
variables?: Record<string, any>;
includeTraces?: boolean;
maxDepth?: number;
}
declare function inspect(expression: string, options?: InspectOptions): Promise<InspectResult>;
/**
* Base error class for all FHIRPath errors
*/
declare class FHIRPathError extends Error {
code: string;
location?: Range | undefined;
constructor(code: string, message: string, location?: Range | undefined);
}
/**
* Error factory with specialized constructors
*/
declare const Errors: {
unknownOperator(operator: string, location?: Range): FHIRPathError;
unknownFunction(name: string, location?: Range): FHIRPathError;
unknownVariable(name: string, location?: Range): FHIRPathError;
unknownUserVariable(name: string, location?: Range): FHIRPathError;
unknownProperty(property: string, type: string, location?: Range): FHIRPathError;
unknownNodeType(nodeType: string, location?: Range): FHIRPathError;
noEvaluatorFound(evaluatorType: string, name: string, location?: Range): FHIRPathError;
variableNotDefined(name: string, location?: Range): FHIRPathError;
wrongArgumentCount(funcName: string, expected: number, actual: number, location?: Range): FHIRPathError;
wrongArgumentCountRange(funcName: string, min: number, max: number, actual: number, location?: Range): FHIRPathError;
singletonRequired(funcName: string, actualCount: number, location?: Range): FHIRPathError;
stringSingletonRequired(funcName: string, actualCount: number, location?: Range): FHIRPathError;
emptyNotAllowed(funcName: string, location?: Range): FHIRPathError;
argumentRequired(funcName: string, argumentName: string, location?: Range): FHIRPathError;
singletonTypeRequired(funcName: string, actualType: string, location?: Range): FHIRPathError;
operatorTypeMismatch(operator: string, leftType: string, rightType: string, location?: Range): FHIRPathError;
argumentTypeMismatch(argIndex: number, funcName: string, expected: string, actual: string, location?: Range): FHIRPathError;
conversionFailed(value: string, targetType: string, location?: Range): FHIRPathError;
invalidValueType(expected: string, actual: string, location?: Range): FHIRPathError;
invalidOperandType(operation: string, type: string, location?: Range): FHIRPathError;
stringOperationOnNonString(operation: string, location?: Range): FHIRPathError;
numericOperationOnNonNumeric(operation: string, location?: Range): FHIRPathError;
booleanOperationOnNonBoolean(operation: string, index: number, actualType: string, location?: Range): FHIRPathError;
modelProviderRequired(operation: string, location?: Range): FHIRPathError;
unexpectedToken(token: string, location?: Range): FHIRPathError;
expectedToken(expected: string, actual: string, location?: Range): FHIRPathError;
invalidSyntax(details: string, location?: Range): FHIRPathError;
expectedIdentifier(after: string, actual: string, location?: Range): FHIRPathError;
expectedTypeName(actual: string, location?: Range): FHIRPathError;
divisionByZero(location?: Range): FHIRPathError;
invalidDateTimeFormat(format: string, location?: Range): FHIRPathError;
incompatibleUnits(unit1: string, unit2: string, location?: Range): FHIRPathError;
indexOutOfBounds(index: number, size: number, location?: Range): FHIRPathError;
invalidOperation(details: string, location?: Range): FHIRPathError;
invalidPrecision(operation: string, location?: Range): FHIRPathError;
invalidStringOperation(operation: string, paramName: string, location?: Range): FHIRPathError;
invalidNumericOperation(operation: string, paramName: string, expectedType: string, location?: Range): FHIRPathError;
};
declare enum ErrorCodes {
UNKNOWN_OPERATOR = "FP1001",
UNKNOWN_FUNCTION = "FP1002",
UNKNOWN_VARIABLE = "FP1003",
UNKNOWN_USER_VARIABLE = "FP1004",
UNKNOWN_PROPERTY = "FP1005",
UNKNOWN_NODE_TYPE = "FP1006",
NO_EVALUATOR_FOUND = "FP1007",
VARIABLE_NOT_DEFINED = "FP1008",
WRONG_ARGUMENT_COUNT = "FP2001",
WRONG_ARGUMENT_COUNT_RANGE = "FP2002",
SINGLETON_REQUIRED = "FP2003",
EMPTY_NOT_ALLOWED = "FP2004",
ARGUMENT_REQUIRED = "FP2005",
OPERATOR_TYPE_MISMATCH = "FP3002",
ARGUMENT_TYPE_MISMATCH = "FP3003",
CONVERSION_FAILED = "FP3004",
INVALID_VALUE_TYPE = "FP3005",
INVALID_OPERAND_TYPE = "FP3006",
STRING_OPERATION_ON_NON_STRING = "FP3007",
NUMERIC_OPERATION_ON_NON_NUMERIC = "FP3008",
BOOLEAN_OPERATION_ON_NON_BOOLEAN = "FP3009",
MODEL_PROVIDER_REQUIRED = "FP4001",
UNEXPECTED_TOKEN = "FP5001",
EXPECTED_TOKEN = "FP5002",
INVALID_SYNTAX = "FP5003",
EXPECTED_IDENTIFIER = "FP5004",
EXPECTED_TYPE_NAME = "FP5005",
DIVISION_BY_ZERO = "FP6001",
INVALID_DATE_TIME_FORMAT = "FP6002",
INCOMPATIBLE_UNITS = "FP6003",
INDEX_OUT_OF_BOUNDS = "FP6004",
INVALID_OPERATION = "FP6005",
INVALID_PRECISION = "FP6006",
INVALID_STRING_OPERATION = "FP6007",
INVALID_NUMERIC_OPERATION = "FP6008"
}
/**
* Kind of completion item
*/
declare enum CompletionKind {
Property = "property",
Function = "function",
Variable = "variable",
Operator = "operator",
Type = "type",
Keyword = "keyword",
Constant = "constant"
}
/**
* Represents a completion item
*/
interface CompletionItem {
/** Display text */
label: string;
/** Kind of completion */
kind: CompletionKind;
/** Short description */
detail?: string;
/** Full documentation */
documentation?: string;
/** Text to insert (if different from label) */
insertText?: string;
/** Sort order */
sortText?: string;
}
/**
* Options for completion provider
*/
interface CompletionOptions {
/** Model provider for FHIR types */
modelProvider?: ModelProvider;
/** Variables in scope */
variables?: Record<string, any>;
/** Input type for the expression */
inputType?: TypeInfo;
/** Maximum number of completions to return */
maxCompletions?: number;
}
/**
* Provides context-aware completions for FHIRPath expressions
*/
declare function provideCompletions(expression: string, cursorPosition: number, options?: CompletionOptions): Promise<CompletionItem[]>;
interface EvaluateOptions {
input?: unknown;
variables?: Record<string, unknown>;
modelProvider?: ModelProvider;
inputType?: TypeInfo;
}
declare function evaluate(expression: string, options?: EvaluateOptions): Promise<any[]>;
declare function analyze(expression: string, options?: {
variables?: Record<string, unknown>;
modelProvider?: ModelProvider;
inputType?: TypeInfo;
errorRecovery?: boolean;
}): Promise<AnalysisResult>;
export { type ASTMetadata, type ASTNode, type AnalysisResult, Analyzer, type AnyCursorNode, type CompletionItem, CompletionKind, type CompletionOptions, type CursorArgumentNode, CursorContext, type CursorIdentifierNode, type CursorIndexNode, type CursorNode, type CursorOperatorNode, type CursorTypeNode, type Diagnostic, DiagnosticSeverity, ErrorCodes, Errors, type EvaluateOptions, type FHIRModelContext, FHIRModelProvider, type FHIRModelProviderConfig, FHIRPathError, type FunctionDefinition, type InspectOptions, type InspectResult, Interpreter, type ModelProvider as ModelTypeProvider, type OperatorDefinition, type ParseResult, Parser, Registry, type TypeInfo, type TypeName, analyze, evaluate, inspect, isCursorNode, parse, provideCompletions, registry };