import type { Asset, Resource } from '@hcengineering/platform';
import type { Association, AttachedDoc, Class, Doc, Domain, Ref, Space } from './classes';
import type { Tx } from './tx';
import type { KeysByType } from './utils';
export type ArraySizeSelector = {
    $gt: number;
} | {
    $lt: number;
} | {
    $gte: number;
} | {
    $lte: number;
};
/**
 * @public
 */
export type QuerySelector<T> = {
    $in?: T[];
    $all?: T extends Array<any> ? T : never;
    $nin?: T[];
    $ne?: T;
    $gt?: T extends number ? number : never;
    $gte?: T extends number ? number : never;
    $lt?: T extends number ? number : never;
    $lte?: T extends number ? number : never;
    $exists?: boolean;
    $like?: string;
    $regex?: string;
    $options?: string;
    $size?: T extends Array<any> ? number | ArraySizeSelector : never;
};
/**
 * @public
 */
export type ObjQueryType<T> = (T extends Array<infer U> ? U | U[] | QuerySelector<U> : T) | QuerySelector<T>;
/**
 * @public
 */
export type DocumentQuery<T extends Doc> = {
    [P in keyof T]?: ObjQueryType<T[P]>;
} & {
    $search?: string;
    [key: string]: any;
};
/**
 * @public
 */
export type ToClassRefT<T extends object, P extends keyof T> = T[P] extends Ref<infer X> | null | undefined ? Ref<Class<X>> | [Ref<Class<X>>, Lookup<X>] : never;
/**
 * @public
 */
export type ToClassRefTA<T extends object, P extends keyof T> = T[P] extends Array<Ref<infer X>> | null | undefined ? Ref<Class<X>> | [Ref<Class<X>>, Lookup<X>] : never;
/**
 * @public
 */
export type ToClassRef<T extends object> = {
    [P in keyof T]?: ToClassRefT<T, P> | ToClassRefTA<T, P>;
};
/**
 * @public
 */
export type NullableRef = Ref<Doc> | Array<Ref<Doc>> | null | undefined;
/**
 * @public
 */
export type RefKeys<T extends Doc> = Pick<T, KeysByType<T, NullableRef>>;
/**
 * @public
 */
export type Refs<T extends Doc> = ToClassRef<RefKeys<T>>;
/**
 * @public
 */
export interface ReverseLookups {
    _id?: ReverseLookup;
}
/**
 * @public
 */
export type ReverseLookup = Record<string, Ref<Class<AttachedDoc>> | [Ref<Class<Doc>>, string]>;
/**
 * @public
 */
export type Lookup<T extends Doc> = Refs<T> | ReverseLookups | (Refs<T> & ReverseLookups);
/**
 * @public
 */
export type Projection<T extends Doc> = {
    [P in keyof T]?: 0 | 1;
};
export type AssociationQuery = [Ref<Association>, 1 | -1];
/**
 * @public
 */
export type FindOptions<T extends Doc> = {
    limit?: number;
    sort?: SortingQuery<T>;
    lookup?: Lookup<T>;
    projection?: Projection<T>;
    associations?: AssociationQuery[];
    total?: boolean;
    showArchived?: boolean;
};
/**
 * @public
 */
export type SortQuerySelector<T> = {
    $in?: T[];
    $nin?: T[];
    $ne?: T;
};
/**
 * @public
 */
export type SortRuleQueryType<T> = (T extends Array<infer U> ? U | U[] : T) | SortQuerySelector<T>;
/**
 * @public
 */
export interface SortingRules<T> {
    order: SortingOrder;
    default?: string | number;
    cases: {
        query: SortRuleQueryType<T>;
        index: string | number;
    }[];
}
/**
 * @public
 */
export type SortingQuery<T extends Doc> = {
    [P in keyof T]?: SortingOrder | SortingRules<T[P]>;
} & Record<string, SortingOrder | SortingRules<any>>;
/**
 * @public
 */
export declare enum SortingOrder {
    Ascending = 1,
    Descending = -1
}
/**
 * @public
 */
export type RefsAsDocs<T> = {
    [P in keyof T]: T[P] extends Ref<infer X> | null | undefined ? (T extends X ? X : X | WithLookup<X>) : AttachedDoc[];
};
/**
 * @public
 */
export type LookupData<T extends Doc> = Partial<RefsAsDocs<T>>;
/**
 * @public
 */
export type WithLookup<T extends Doc> = T & {
    $lookup?: LookupData<T>;
    $associations?: Record<string, Doc[]>;
    $source?: {
        $score: number;
        [key: string]: any;
    };
};
/**
 * @public
 */
export type FindResult<T extends Doc> = WithLookup<T>[] & {
    total: number;
    lookupMap?: Record<string, Doc>;
};
export type DomainParams = Record<string, any>;
export interface DomainResult<T = any> {
    domain: Domain;
    value: T;
}
/**
 * @public
 */
export interface TxResult {
}
/**
 * @public
 */
export interface SearchQuery {
    query: string;
    classes?: Ref<Class<Doc>>[];
    spaces?: Ref<Space>[];
}
/**
 * @public
 */
export interface SearchOptions {
    limit?: number;
}
export interface SearchComponentWithProps {
    component?: Resource<any>;
    props?: Record<string, string>;
}
/**
 * @public
 */
export interface SearchResultDoc {
    id: Ref<Doc>;
    icon?: Asset;
    iconComponent?: SearchComponentWithProps;
    shortTitle?: string;
    shortTitleComponent?: SearchComponentWithProps;
    title?: string;
    titleComponent?: SearchComponentWithProps;
    description?: string;
    emojiIcon?: string;
    score?: number;
    doc: Pick<Doc, '_id' | '_class' | 'createdOn'> & Partial<Pick<AttachedDoc, 'attachedTo' | 'attachedToClass'>>;
}
/**
 * @public
 */
export interface SearchResult {
    docs: SearchResultDoc[];
    total?: number;
}
/**
 * @public
 */
export interface Storage {
    findAll: <T extends Doc>(_class: Ref<Class<T>>, query: DocumentQuery<T>, options?: FindOptions<T>) => Promise<FindResult<T>>;
    tx: (tx: Tx) => Promise<TxResult>;
}
/**
 * @public
 */
export interface FulltextStorage {
    searchFulltext: (query: SearchQuery, options: SearchOptions) => Promise<SearchResult>;
}
export declare function shouldShowArchived<T extends Doc>(query: DocumentQuery<T>, options: FindOptions<T> | undefined): boolean;
//# sourceMappingURL=storage.d.ts.map