import { SquidDocIdObj, SquidDocument } from '../public-types/document.public-types';
import { Paths } from '../public-types/typescript.public-types';
/**
 * The mutation type.
 * @category Database
 */
export declare const MUTATION_TYPES: readonly ["insert", "update", "delete"];
/**
 * @category Database
 */
export type MutationType = (typeof MUTATION_TYPES)[number];
interface BaseMutation {
    type: MutationType;
    squidDocIdObj: SquidDocIdObj;
}
/**
 * A mutation on a document.
 * @category Database
 */
export type Mutation<T = any> = UpdateMutation<T> | InsertMutation<T> | DeleteMutation;
/**
 * Represents a delete mutation on a document.
 * @category Database
 */
export interface DeleteMutation extends BaseMutation {
    /** Specifies that the mutation is a deletion. */
    type: 'delete';
}
/**
 * Represents an update mutation on a document.
 * @category Database
 */
export interface UpdateMutation<T = any> extends BaseMutation {
    /** Specifies that the mutation is an update. */
    type: 'update';
    /** The updated properties */
    properties: {
        [key in keyof T & string]?: Array<PropertyMutation<T[key]>>;
    };
}
/**
 * Represents an insert mutation on a document.
 * @category Database
 */
export interface InsertMutation<T = any> extends BaseMutation {
    /** Specifies that the mutation is an insertion. */
    type: 'insert';
    /** The inserted document */
    properties: T;
}
/**
 * A representation of a single property update.
 * @category Database
 */
export type PropertyMutation<Value = any> = ApplyNumericFnPropertyMutation | ApplyStringFnPropertyMutation | ValueUpdatePropertyMutation<Value> | RemovePropertyMutation;
/**
 * A value update property mutation.
 * @category Database
 */
export interface ValueUpdatePropertyMutation<Value = any> {
    /** Specifies that the mutation updates a value. */
    type: 'update';
    /** New value to be set. */
    value: Value;
}
/**
 * Applying a numeric function to a property.
 * @category Database
 */
export interface ApplyNumericFnPropertyMutation {
    /** Specifies that the mutation applies a numeric function. */
    type: 'applyNumericFn';
    /** Numeric function to apply. */
    fn: 'increment';
    /** Value to use in the numeric function. */
    value: number;
}
/**
 * A property update that removes a property from a document.
 * @category Database
 */
export interface RemovePropertyMutation {
    /** Specifies that the mutation removes a property. */
    type: 'removeProperty';
}
interface ApplyExtendString {
    /** Specifies that the mutation applies a string function. */
    type: 'applyStringFn';
    /** String function to extend the existing string. */
    fn: 'extendString';
    /** String value to append. */
    value: string;
}
interface ApplyTrimString {
    /** Specifies that the mutation applies a string function. */
    type: 'applyStringFn';
    /** String function to trim the existing string. */
    fn: 'trim';
}
/**
 * A property mutation that modifies a string.
 * @category Database
 */
export type ApplyStringFnPropertyMutation = ApplyExtendString | ApplyTrimString;
/**
 * The before and after documents of a document change.
 * @category Database
 */
export interface BeforeAndAfterDocs<T = SquidDocument> {
    /** Document state before the mutation. */
    before: T | undefined;
    /** Document state after the mutation. */
    after: T | undefined;
}
/**
 * The mutation context that will be provided to the security function.
 * @category Database
 */
export declare class MutationContext<T = any> {
    readonly mutation: Mutation<T>;
    readonly beforeAndAfterDocs: BeforeAndAfterDocs<T>;
    readonly serverTimeStamp: Date;
    /**
     * Returns the state of the document before the mutation was applied.
     */
    get before(): T | undefined;
    /**
     * Returns the state of the document after the mutation was applied.
     */
    get after(): T | undefined;
    /**
     * Returns the type of the mutation (insert, update, or delete).
     */
    getMutationType(): MutationType;
    /** Returns true if the mutation affects the provided path. */
    affectsPath(path: Paths<T>): boolean;
    /**
     * Find all affected paths starting from a root path.
     *
     * @example
     * doc before - { a: { b: 1, c: 2 }, d: 3 }
     * doc after - { a: { b: 1, c: 3 }, d: 4 }
     * doc.affectedPaths('a') // ['a.c']
     */
    affectedPaths(startingRoot?: Paths<T> | string): Array<Paths<T>>;
    private checkPath;
}
export {};
