export type ExpressionReturnType = 'string' | 'number' | 'boolean' | 'any' | 'null'; export interface LiteralNode { type: 'Literal'; value: string | number | boolean | null; returnType: ExpressionReturnType; } export interface DatasourceRefNode { type: 'DatasourceRef'; datasource: string; field: string; returnType: 'any'; } export interface ParameterRefNode { type: 'ParameterRef'; parameter: string; path?: string[]; returnType: 'any'; } export interface FieldRefNode { type: 'FieldRef'; field: string; returnType: 'any'; } export type RowOrColGroupProperty = { kind: 'key'; } | { kind: 'keys'; } | { kind: 'values'; } | { kind: 'field'; field: string; } | { kind: 'variable'; name: string; }; export interface RowGroupRefNode { type: 'RowGroupRef'; groupName: string; property: RowOrColGroupProperty; returnType: 'any'; } export interface ColGroupRefNode { type: 'ColGroupRef'; groupName: string; property: RowOrColGroupProperty; returnType: 'any'; } export interface VariableRefNode { type: 'VariableRef'; name: string; path?: string[]; returnType: 'any'; } export interface BuiltInFieldRefNode { type: 'BuiltInFieldRef'; name: string; path?: string[]; returnType: 'any'; } export interface FunctionCallNode { type: 'FunctionCall'; name: string; args: ExpressionNode[]; returnType: ExpressionReturnType; } export interface BinaryOpNode { type: 'BinaryOp'; op: string; left: ExpressionNode; right: ExpressionNode; returnType: ExpressionReturnType; } export interface UnaryOpNode { type: 'UnaryOp'; op: '!' | '-'; operand: ExpressionNode; returnType: ExpressionReturnType; } export type ExpressionNode = LiteralNode | DatasourceRefNode | ParameterRefNode | FieldRefNode | RowGroupRefNode | ColGroupRefNode | VariableRefNode | BuiltInFieldRefNode | FunctionCallNode | BinaryOpNode | UnaryOpNode; export type TokenType = 'Identifier' | 'Number' | 'String' | 'Dot' | 'Comma' | 'LParen' | 'RParen' | 'Operator' | 'EOF'; export interface Token { type: TokenType; value: string; start: number; end: number; } export interface FunctionParam { name: string; type: ExpressionReturnType | 'any'; variadic?: boolean; } export interface BuiltinFunction { name: string; description: string; params: FunctionParam[]; returnType: ExpressionReturnType; isAsync?: boolean; } export interface CustomFunction extends BuiltinFunction { fn: (...args: unknown[]) => unknown | Promise; } export interface GroupFrame { name: string; key?: unknown; keys?: unknown[]; values?: Record[]; fields?: Record; variables?: Record; } export interface ExpressionContext { datasources?: Record[]>; currentRow?: Record; parameters?: Record; customFunctions?: CustomFunction[]; rowGroups?: Record; colGroups?: Record; variables?: Record; /** * Built-in fields are read-only values made available under the `BuiltInFields.*` namespace * in expressions. They combine: * 1. Values registered via `initReportBuilder({ builtInFields })` (library-wide defaults / host-provided). * 2. Values passed to `ReportBuilder` / `ReportViewer` via the `builtInFields` prop (override per-instance). * Each entry is either a constant or a zero-arg getter; the engine resolves getters lazily per evaluation. */ builtInFields?: Record; } export interface ExpressionTypeContext { expectedReturnType?: ExpressionReturnType; availableDatasources?: Record; availableParameters?: string[]; availableFields?: string[]; availableRowGroups?: string[]; availableColGroups?: string[]; availableVariables?: string[]; availableBuiltInFields?: string[]; customFunctions?: CustomFunction[]; } export interface ExpressionError { message: string; position?: number; length?: number; } export type SuggestionKind = 'datasource' | 'field' | 'parameter' | 'function' | 'keyword' | 'builtin'; export interface AutocompleteSuggestion { label: string; kind: SuggestionKind; detail?: string; insertText?: string; }