/** * Copyright (c) 2026, Salesforce, Inc., * All rights reserved. * For full license text, see the LICENSE.txt file */ export interface DirectiveNode { name: string; args: Record; } export interface VariableDefinition { name: string; type: string; defaultValue?: string; runtimeValue?: string; } export interface BaseProjectionNode { id: string; kind: "field" | "fragment"; parentId: string | null; schemaPath: string[]; directives: DirectiveNode[]; } export interface FieldProjectionNode extends BaseProjectionNode { kind: "field"; fieldName: string; alias?: string; args: Record; } export interface FragmentProjectionNode extends BaseProjectionNode { kind: "fragment"; onType: string; } export type ProjectionNode = FieldProjectionNode | FragmentProjectionNode; export type OperationType = "query" | "mutation" | "aggregate"; export interface QuerySession { id: string; name?: string; /** GraphQL operation name emitted by `renderQuery`. Distinct from `name`, which is the session's user-facing label. */ operationName?: string; orgAlias: string; /** Resolved Salesforce instance URL stored at session creation to avoid repeated sf-auth calls. */ instanceUrl?: string; operation: OperationType; navigationPath: string[]; nodes: ProjectionNode[]; variables: VariableDefinition[]; focusByPath: Record; createdAt: string; undoStack?: string[]; } /** * Snapshots the current session state (excluding undoStack) and pushes it * onto the undo stack. Call this before any state-mutating operation. */ export declare function pushUndoSnapshot(session: QuerySession): void; /** * Pops the most recent undo snapshot and returns a restored session. * The restored session inherits the current (truncated) undo stack. * Returns null if there is nothing to undo. */ export declare function popUndo(session: QuerySession): QuerySession | null; export declare function isFragmentSegment(segment: string): boolean; /** * Normalizes a fragment segment to the canonical `[Type]` form. * Accepts `on:Type` as a shell-safe alternative that avoids zsh glob/redirect * issues with `[Type]` and ``. * * Examples: `on:User` → `[User]`, `[User]` stays as-is. */ export declare function normalizeFragmentSegment(segment: string): string; /** Returns true for alias-encoded path segments like `openOpps(Opportunity)`. */ export declare function isAliasedSegment(segment: string): boolean; /** * Parses an alias-encoded segment into its alias name and underlying field name. * Returns null for plain or fragment segments. */ export declare function parseAliasedSegment(segment: string): { alias: string; fieldName: string; } | null; /** Strips the alias wrapper from a single path segment, leaving just the schema field name. */ export declare function schemaSegment(segment: string): string; /** * Converts a navigation path (which may contain alias-encoded segments) to a * pure schema path suitable for schema resolution and focus-map lookups. */ export declare function toSchemaPath(navPath: string[]): string[]; export declare function pathKey(pathSegments: string[]): string; export declare function formatPath(pathSegments: string[]): string; export declare function createSession(orgAlias: string, operation?: OperationType, instanceUrl?: string, name?: string): QuerySession; export declare function cloneSession(source: QuerySession, newName?: string): QuerySession; export declare function getNodeById(session: QuerySession, id: string | null | undefined): ProjectionNode | null; export declare function getChildren(session: QuerySession, parentId: string | null): ProjectionNode[]; export declare function listInstancesAtPath(session: QuerySession, schemaPath: string[]): ProjectionNode[]; export declare function getFocusedNodeAtPath(session: QuerySession, schemaPath: string[], createMissing?: boolean): ProjectionNode | null; export declare function ensureFocusedChain(session: QuerySession, schemaPath: string[]): ProjectionNode | null; /** * Walks the query portion of the navigation path and syncs focusByPath entries * for any aliased segments (e.g. `recentAccounts(Account)`). This ensures that * subsequent select/assign operations target the correct aliased instance. */ export declare function syncFocusFromNavigationPath(session: QuerySession): void; export declare function focusNodeAtPath(session: QuerySession, schemaPath: string[], nodeId: string): void; export declare function createSiblingFieldInstance(session: QuerySession, schemaPath: string[], alias?: string): FieldProjectionNode; export declare function setAliasOnPath(session: QuerySession, schemaPath: string[], aliasName: string): FieldProjectionNode; export declare function clearAliasOnPath(session: QuerySession, schemaPath: string[]): void; export declare function focusInstanceByAliasOrId(session: QuerySession, schemaPath: string[], selector: string): ProjectionNode; export declare function setArg(session: QuerySession, schemaPath: string[], argName: string, value: string): void; export declare function getArg(session: QuerySession, schemaPath: string[], argName: string): string | undefined; export declare function removeArg(session: QuerySession, schemaPath: string[], argName: string): boolean; export declare function getEffectiveArgs(_session: QuerySession, node: ProjectionNode): Record; export type NavigationContext = "root" | "query" | "variables"; export declare function getNavigationContext(navPath: string[]): NavigationContext; export declare const ARGS_SEGMENT = "@args"; export declare function isArgsSegment(segment: string): boolean; /** Returns the index of the @args segment in the path, or -1 if not present. */ export declare function argsSegmentIndex(navPath: string[]): number; /** Returns true if the navigation path is inside an @args context. */ export declare function isInArgsContext(navPath: string[]): boolean; /** * Extracts the schema path of the field whose args are being navigated. * E.g. ["query", "uiapi", "query", "Account", "@args", "where", "Name"] * → ["uiapi", "query", "Account"] */ export declare function getArgsFieldPath(navPath: string[]): string[]; /** * Extracts the input sub-path after @args. * E.g. ["query", "uiapi", "query", "Account", "@args", "where", "Name"] * → ["where", "Name"] */ export declare function getInputSubPath(navPath: string[]): string[]; /** * For paths in the /query context, strips the "query" prefix and alias wrappers * to produce a pure schema path. Stops at @args if present. * E.g. ["query", "uiapi", "query", "Account"] → ["uiapi", "query", "Account"] */ export declare function queryNavToSchemaPath(navPath: string[]): string[]; /** * For paths in /variables, extracts the variable name (without $) and the * sub-path into its input type. */ export declare function parseVariablePath(navPath: string[]): { varName: string; inputSubPath: string[]; } | null; /** * Incrementally sets a value deep inside a field argument's JSON structure. * If inputPath is empty, sets the top-level arg directly. * E.g. deepSetArg(session, path, "where", ["Name", "like"], '"Acme%"') * results in node.args["where"] = '{"Name":{"like":"Acme%"}}' */ export declare function deepSetArg(session: QuerySession, schemaPath: string[], argName: string, inputPath: string[], value: string): void; /** * Reads the current value at a nested path inside a field argument. */ export declare function deepGetArg(session: QuerySession, schemaPath: string[], argName: string, inputPath: string[]): unknown; /** * Removes a value at a nested path inside a field argument. */ export declare function deepRemoveArg(session: QuerySession, schemaPath: string[], argName: string, inputPath: string[]): boolean; /** * Incrementally sets a value deep inside a variable's runtime value. * If inputPath is empty, sets the runtime value directly. */ export declare function deepSetVariableValue(session: QuerySession, varName: string, inputPath: string[], value: string): void; /** * Appends a new empty object to a list-type arg array. Returns the new index. */ export declare function appendListElement(session: QuerySession, schemaPath: string[], argName: string, inputPath: string[]): number; /** * Removes an element from a list-type arg by index and compacts remaining indices. */ export declare function removeListElement(session: QuerySession, schemaPath: string[], argName: string, inputPath: string[], index: number): boolean; export declare function selectLeaf(session: QuerySession, schemaPath: string[], alias?: string): FieldProjectionNode; export declare function removeSelectionAtPath(session: QuerySession, schemaPath: string[], selector?: string): boolean; export declare function findDescendantByAlias(session: QuerySession, parentId: string | null, alias: string): FieldProjectionNode | null; export declare function removeNodeByIdWithPrune(session: QuerySession, nodeId: string): boolean; /** * A type-conflicting `$var` redeclaration detected by {@link addVariable}. * The first-declared type is kept (first-wins); the later inference is ignored. */ export interface VariableTypeCollision { name: string; existingType: string; ignoredType: string; } export declare function addVariable(session: QuerySession, name: string, type: string, defaultValue?: string): VariableTypeCollision | undefined; export declare function setVariableRuntimeValue(session: QuerySession, name: string, runtimeValue: string): void; export declare function setVariableDefault(session: QuerySession, name: string, defaultValue: string | undefined): void; /** * Finds all arg paths where a variable is referenced. * Returns entries like `["Account", "where"] → "$filter"` for display. */ export declare function findVariableReferences(session: QuerySession, varName: string): { fieldPath: string[]; argName: string; subPath: string[]; }[]; export declare function removeVariable(session: QuerySession, name: string): boolean; /** * Builds the variables map for query execution. * Priority: ad-hoc overrides > session runtimeValue > defaultValue. */ export declare function buildRuntimeVariables(session: QuerySession, overrides?: Record): Record; export declare function saveSession(session: QuerySession): void; export declare function loadSession(id: string): QuerySession; export declare function listSessions(): { id: string; name?: string; orgAlias: string; operation: string; createdAt: string; }[]; export declare function deleteSession(id: string): boolean;