import { archivist } from 'mage';
import * as mage from 'mage';
declare type Key = string | number | symbol;
export declare type Diff<T extends Key, U extends Key> = ({
    [P in T]: P;
} & {
    [P in U]: never;
} & {
    [x: string]: never;
})[T];
export declare type Omit<T, K extends keyof T> = Pick<Partial<T>, Diff<keyof T, K>>;
/**
 * Anonymous object representation of a validated topic
 *
 * Generally passed to Topic.create()
 */
export declare type TopicData<T extends ValidatedTopic> = Omit<T, keyof ValidatedTopic>;
/**
 * Partial index type
 */
export declare type PartialIndex<I> = {
    [K in keyof I]?: string;
};
/**
 * The IStaticThis interface is required
 * for us to be able to create static factory functions
 * that return a properly typed output.
 */
export interface IStaticThis<I, T> {
    indexType: {
        new (): any;
    };
    new (): T;
    getClassName(): string;
    execute<I, T, R>(this: IStaticThis<I, T>, state: any, method: any, args: any[], run: (data: any) => any): Promise<R>;
    create<T extends ValidatedTopic>(this: IStaticThis<I, T>, state: mage.core.IState, index: I, data?: any): Promise<T>;
    get<T extends ValidatedTopic>(this: IStaticThis<I, T>, state: mage.core.IState, index: I, options?: archivist.IArchivistGetOptions): Promise<T>;
    mget<T extends ValidatedTopic>(this: IStaticThis<I, T>, state: mage.core.IState, indexes: I[], options?: archivist.IArchivistGetOptions): Promise<T[]>;
}
/**
 * Validated topic
 *
 * Please note that you should import the default
 * of this module, not this class directly.
 *
 * Good:
 *
 * ```typescript
 * import ValidatedTopic from 'mage-validator'
 * ```
 *
 * Bad:
 *
 * ```typescript
 * import { ValidatedTopic } from 'mage-validator'
 * ```
 *
 * While the second line will work, it will provide you with
 * less type safety than the first import example.
 *
 * @export
 * @abstract
 * @class ValidatedTopic
 */
export default class ValidatedTopic {
    static readonly mediaType: string;
    static readonly index: string[];
    static readonly indexType: any;
    static readonly vaults: {};
    private static _className;
    /**
     * Return the current class name
     *
     * @static
     * @returns
     *
     * @memberof ValidatedTopic
     */
    static getClassName(): string;
    /**
     * Explicitly set the name of this class
     *
     * @static
     * @param {string} name
     *
     * @memberof ValidatedTopic
     */
    static setClassName(name: string): void;
    /**
     * Create an instance from a generic object
     *
     * @static
     * @param {mage.core.IState} state
     * @param {*} data
     * @returns
     *
     * @memberof ValidatedTopic
     */
    static create<I extends archivist.IArchivistIndex, T extends ValidatedTopic>(this: IStaticThis<I, T>, state: mage.core.IState, index: I, data?: TopicData<T>): Promise<T>;
    /**
     * Utility method used to promisify archivist calls
     *
     * @static
     * @param {*} state
     * @param {*} method
     * @param {any[]} args
     * @param {Function} run
     * @returns
     *
     * @memberof ValidatedTopic
     */
    static execute<I, T, R>(this: IStaticThis<I, T>, state: any, method: any, args: any[], run: (data: any) => any): Promise<R>;
    /**
     * Get a topic instance from backend vault(s)
     *
     * Mostly a wrapper around state.archivist.get. Note that
     * instead of using the `optional` option directly with this call,
     * you should consider using `tryGet` instead, which will trigger a
     * compile error if you do not check for an undefined return value.
     *
     * @static
     * @param {mage.core.IState} state
     * @param {archivist.IArchivistIndex} index
     * @param {archivist.IArchivistGetOptions} [options]
     * @returns
     *
     * @memberof ValidatedTopic
     */
    static get<I extends archivist.IArchivistIndex, T extends ValidatedTopic>(this: IStaticThis<I, T>, state: mage.core.IState, index: I, options?: archivist.IArchivistGetOptions): Promise<T>;
    /**
     * Try to get a topic instance from backend vault(s)
     *
     * Same as `get`, but is also states that `undefined' might be returned instead.
     * You should consider using this method instead of calling `get` directly
     * with the `optional: true` option.
     *
     * @static
     * @param {mage.core.IState} state
     * @param {archivist.IArchivistIndex} index
     * @param {archivist.IArchivistGetOptions} [options]
     * @returns
     *
     * @memberof ValidatedTopic
     */
    static tryGet<I extends archivist.IArchivistIndex, T extends ValidatedTopic>(this: IStaticThis<I, T>, state: mage.core.IState, index: I, options?: archivist.IArchivistGetOptions): Promise<T | undefined>;
    /**
     * Get instances from backend vault(s)
     *
     * Mostly a wrapper around state.archivist.mget.
     *
     * @static
     * @param {mage.core.IState} state
     * @param {archivist.IArchivistQuery[]} queries
     * @param {archivist.IArchivistGetOptions} [options]
     * @returns
     *
     * @memberof ValidatedTopic
     */
    static mget<I extends archivist.IArchivistIndex, T extends ValidatedTopic>(this: IStaticThis<I, T>, state: mage.core.IState, indexes: I[], options?: archivist.IArchivistGetOptions): Promise<T[]>;
    /**
     * List all keys
     *
     * @static
     * @param {mage.core.IState} state
     * @param {archivist.IArchivistIndex} partialIndex
     * @param {archivist.IArchivistGetOptions} [options]
     * @returns
     *
     * @memberof ValidatedTopic
     */
    static list<I extends archivist.IArchivistIndex, T extends ValidatedTopic>(this: IStaticThis<I, T>, state: mage.core.IState, partialIndex: PartialIndex<I>, options?: archivist.IArchivistListOptions): Promise<archivist.IArchivistIndex[]>;
    /**
     * Query data by partial index
     *
     * Essentially wraps state.archivist.list, then fetches the data
     * for each keys using state.archivist.mget.
     *
     * @static
     * @param {mage.core.IState} state
     * @param {archivist.IArchivistIndex} partialIndex
     * @param {archivist.IArchivistGetOptions} [options]
     * @returns
     *
     * @memberof ValidatedTopic
     */
    static query<I extends archivist.IArchivistIndex, T extends ValidatedTopic>(this: IStaticThis<I, T>, state: mage.core.IState, partialIndex: PartialIndex<I>, options?: archivist.IArchivistGetOptions | archivist.IArchivistListOptions): Promise<T[]>;
    /**
     * Creates an instance of ValidatedTopic.
     *
     * @param {mage.core.IState} state
     *
     * @memberof ValidatedTopic
     */
    constructor(state?: mage.core.IState);
    /**
     * Get the topic for this instance
     *
     * @memberof ValidatedTopic
     */
    getTopic(): string;
    /**
     * Set the topic name for this instance
     *
     * @param {string} topicName
     *
     * @memberof ValidatedTopic
     */
    setTopic(topicName: string): void;
    /**
     * Get the topic of that instance
     *
     * Should always return the class name of the instance.
     *
     * @returns
     *
     * @memberof ValidatedTopic
     */
    getIndex(): archivist.IArchivistIndex;
    /**
     * Set the index of this topic instance
     *
     * @param {archivist.IArchivistIndex} index
     *
     * @memberof ValidatedTopic
     */
    setIndex(indexData: archivist.IArchivistIndex): Promise<void>;
    /**
     * Retrieve the state object attached to the instance
     */
    getState(): mage.core.IState;
    /**
     * Set the state this topic instance will be using.
     */
    setState(state: mage.core.IState): void;
    /**
     * Retrieve the actual data for this instance
     *
     * This should essentially be the same as simply accessing data on the
     * instance itself.
     */
    getData(): this;
    /**
     * Record an add operation on the instance's state
     *
     * Essentially a wrapper for state.archivist.add
     */
    add(mediaType?: archivist.ArchivistMediaType, encoding?: archivist.ArchivistEncoding, expirationTime?: number): Promise<void>;
    /**
     * Record a set operation on the instance's state
     *
     * Essentially a wrapper for state.archivist.set.
     */
    set(mediaType?: archivist.ArchivistMediaType, encoding?: archivist.ArchivistEncoding, expirationTime?: number): Promise<void>;
    /**
     * Record a touch operation on the instance's state
     *
     * Essentially a wrapper for state.archivist.touch.
     */
    touch(expirationTime?: number): Promise<void>;
    /**
     * Record a delete operation on the instance's state
     */
    del(): void;
    /**
     * Validate the current instance
     */
    validate(errorMessage?: string, code?: string): Promise<void>;
    /**
     * Throw a ValidateError including relevant details
     */
    raiseValidationError(errors: any[], errorMessage?: string, code?: string): void;
}
export {};
