import { Iterator } from "./lazy";
import { Any, AnyObject, Callback, HashFunction, Predicate, WindowOperatorInput } from "./types";
/**
 * Resolves the given string to a Collection.
 * This is useful for operators that require a second collection to use such as $lookup and $out.
 * The collection is not cached and will be resolved each time it is used.
 */
export type CollectionResolver = (name: string) => AnyObject[];
/** Specification for collation options */
export interface CollationSpec {
    readonly locale: string;
    readonly caseLevel?: boolean;
    readonly caseFirst?: "upper" | "lower" | "off";
    readonly strength?: 1 | 2 | 3;
    readonly numericOrdering?: boolean;
    readonly alternate?: string;
    readonly maxVariable?: never;
    readonly backwards?: never;
}
/**
 * JSON schema validator
 */
export type JsonSchemaValidator = (schema: AnyObject) => Predicate<AnyObject>;
/**
 * Specified how input and output documents are processed.
 */
export declare enum ProcessingMode {
    /** Do not clone inputs or outputs. Resulting documents may share references. @default */
    CLONE_OFF = 0,
    /** Clone input documents to maintain immutability of original input. */
    CLONE_INPUT = 1,
    /** Clone output documents to ensure distinct objects without shared references. */
    CLONE_OUTPUT = 2,
    /** Clone input and output documents. */
    CLONE_ALL = 3
}
/**
 * Generic options interface passed down to all operators
 */
export interface Options {
    /** The key that is used to lookup the ID value of a document. @default "_id". */
    readonly idKey: string;
    /** The collation specification for string sorting operations. */
    readonly collation?: CollationSpec;
    /** Determines how to treat inputs and outputs. @default ProcessingMode.CLONE_OFF. */
    readonly processingMode: ProcessingMode;
    /** Enforces strict MongoDB compatibilty. See README. @default true. */
    readonly useStrictMode: boolean;
    /** Enable or disable custom script execution using `$where`, `$accumulator`, and `$function` operators. @default true. */
    readonly scriptEnabled: boolean;
    /** Enable or disable falling back to the global context for operators. @default true. */
    readonly useGlobalContext: boolean;
    /** Hash function to replace the Effective Java default implementation. */
    readonly hashFunction?: HashFunction;
    /** Function to resolve strings to arrays for use with operators that reference other collections such as; `$lookup`, `$out` and `$merge`. */
    readonly collectionResolver?: CollectionResolver;
    /** JSON schema validator to use with the '$jsonSchema' operator. Required in order to use the operator. */
    readonly jsonSchemaValidator?: JsonSchemaValidator;
    /** Global variables. */
    readonly variables?: Readonly<AnyObject>;
    /** Extra references to operators to be used for processing. */
    readonly context: Context;
}
interface LocalData {
    /** The groupId computed for a group of documents. */
    readonly groupId?: Any;
    /** Local user-defind variables. */
    readonly variables?: AnyObject;
}
/** Custom type to facilitate type checking for global options */
export declare class ComputeOptions implements Options {
    #private;
    private constructor();
    /**
     * Initialize new ComputeOptions.
     * @returns {ComputeOptions}
     */
    static init(options: Options, root?: Any, local?: LocalData): ComputeOptions;
    /**
     * Updates the internal state.
     *
     * @param root The new root context for this object.
     * @param local The new local state to merge into current if it exists.
     * @returns
     */
    update(root?: Any, local?: LocalData): ComputeOptions;
    getOptions(): Options;
    get root(): unknown;
    get local(): LocalData;
    get idKey(): string;
    get collation(): CollationSpec;
    get processingMode(): ProcessingMode;
    get useStrictMode(): boolean;
    get scriptEnabled(): boolean;
    get useGlobalContext(): boolean;
    get hashFunction(): HashFunction;
    get collectionResolver(): CollectionResolver;
    get jsonSchemaValidator(): JsonSchemaValidator;
    get variables(): Readonly<AnyObject>;
    get context(): Context;
}
/**
 * Creates an Option from another where required keys are initialized.
 * @param options Options
 */
export declare function initOptions(options?: Partial<Options>): Options;
/**
 * Supported cloning modes.
 * - "deep": Performs a recursive deep clone of the object.
 * - "copy": Performs a shallow copy of the object.
 * - "none": No cloning. Uses the value as given.
 */
export type CloneMode = "deep" | "copy" | "none";
export interface UpdateOptions {
    /** Specifies whether to deep clone values to persist in the internal store. @default "copy". */
    readonly cloneMode?: CloneMode;
    /** Options to use for processing queries. Unless overriden 'useStrictMode' is false.  */
    readonly queryOptions?: Partial<Options>;
}
/**
 * The different groups of operators
 */
export declare enum OperatorType {
    ACCUMULATOR = "accumulator",
    EXPRESSION = "expression",
    PIPELINE = "pipeline",
    PROJECTION = "projection",
    QUERY = "query",
    WINDOW = "window"
}
export type AccumulatorOperator<R = Any> = (collection: Any[], expr: Any, options: Options) => R;
export type ExpressionOperator<R = Any> = (obj: AnyObject, expr: Any, options: Options) => R;
export type PipelineOperator = (collection: Iterator, expr: Any, options: Options) => Iterator;
export type ProjectionOperator = (obj: AnyObject, expr: Any, selector: string, options: Options) => Any;
export type QueryOperator = (selector: string, value: Any, options: Options) => (obj: AnyObject) => boolean;
export type WindowOperator = (obj: AnyObject, array: AnyObject[], expr: WindowOperatorInput, options: Options) => Any;
/** Interface for update operators */
export type UpdateOperator = (obj: AnyObject, expr: AnyObject, arrayFilters: AnyObject[], options: UpdateOptions) => string[];
type Operator = AccumulatorOperator | ExpressionOperator | PipelineOperator | ProjectionOperator | QueryOperator | WindowOperator;
type AccumulatorOps = Record<string, AccumulatorOperator>;
type ExpressionOps = Record<string, ExpressionOperator>;
type ProjectionOps = Record<string, ProjectionOperator>;
type QueryOps = Record<string, QueryOperator>;
type PipelineOps = Record<string, PipelineOperator>;
type WindowOps = Record<string, WindowOperator>;
/** Kinds of operators that can be registered. */
export type OpType = "accumulator" | "expression" | "pipeline" | "projection" | "query" | "window";
export declare class Context {
    #private;
    private constructor();
    static init(): Context;
    static from(ctx?: Context): Context;
    private addOperators;
    getOperator(type: OpType, name: string): Callback | null;
    addAccumulatorOps(ops: AccumulatorOps): Context;
    addExpressionOps(ops: ExpressionOps): Context;
    addQueryOps(ops: QueryOps): Context;
    addPipelineOps(ops: PipelineOps): Context;
    addProjectionOps(ops: ProjectionOps): Context;
    addWindowOps(ops: WindowOps): Context;
}
/**
 * Register global operators that are available when {@link Options.useGlobalContext} is enabled.
 *
 * @param type Operator type
 * @param operators Map of operator name to functions
 */
export declare function useOperators(type: OpType, operators: Record<string, Operator>): void;
/**
 * Returns the operator function or undefined if it is not found
 * @param type Type of operator
 * @param name Name of the operator
 * @param options
 */
export declare function getOperator(type: OpType, name: string, options: Pick<Options, "useGlobalContext" | "context">): Operator;
/**
 * Computes the value of the expression on the object for the given operator
 *
 * @param obj the current object from the collection
 * @param expr the expression for the given field
 * @param operator the operator to resolve the field with
 * @param options {Object} extra options
 * @returns {*}
 */
export declare function computeValue(obj: Any, expr: Any, operator: string | null, options?: Options): Any;
/**
 * Redact an object
 * @param  {Object} obj The object to redact
 * @param  {*} expr The redact expression
 * @param  {*} options  Options for value
 * @return {*} returns the result of the redacted object
 */
export declare function redact(obj: AnyObject, expr: Any, options: ComputeOptions): Any;
export {};
