import { BaseRecord } from './common';

export declare namespace CRUD {
    export type WithIdValue = string | number | {
        _id: number;
    };
    interface BaseCondition<T extends string> {
        op: T;
    }
    export interface AndCondition<M extends Record<string, any>> extends BaseCondition<'and'> {
        subCondition: Condition<M>[];
    }
    export interface OrCondition<M extends Record<string, any>> extends BaseCondition<'or'> {
        subCondition: Condition<M>[];
    }
    export interface EqCondition<M extends Record<string, any>> extends BaseCondition<'eq'> {
        key: keyof M;
        value: WithIdValue;
    }
    export interface NeqCondition<M extends Record<string, any>> extends BaseCondition<'neq'> {
        key: keyof M;
        value: WithIdValue;
    }
    export interface GtCondition<M extends Record<string, any>> extends BaseCondition<'gt'> {
        key: keyof M;
        value: string | number;
    }
    export interface GteCondition<M extends Record<string, any>> extends BaseCondition<'gte'> {
        key: keyof M;
        value: string | number;
    }
    export interface LtCondition<M extends Record<string, any>> extends BaseCondition<'lt'> {
        key: keyof M;
        value: string | number;
    }
    export interface LteCondition<M extends Record<string, any>> extends BaseCondition<'lte'> {
        key: keyof M;
        value: string | number;
    }
    export interface ContainsCondition<M extends Record<string, any>> extends BaseCondition<'contains'> {
        key: keyof M;
        value: WithIdValue;
    }
    export interface NotContainsCondition<M extends Record<string, any>> extends BaseCondition<'notContains'> {
        key: keyof M;
        value: WithIdValue;
    }
    export interface HasAnyOfCondition<M extends Record<string, any>> extends BaseCondition<'hasAnyOf'> {
        key: keyof M;
        value: WithIdValue[];
    }
    export interface NotAnyOfCondition<M extends Record<string, any>> extends BaseCondition<'notAnyOf'> {
        key: keyof M;
        value: WithIdValue[];
    }
    export interface InCondition<M extends Record<string, any>> extends BaseCondition<'in'> {
        key: keyof M;
        value: WithIdValue[];
    }
    export interface NotInCondition<M extends Record<string, any>> extends BaseCondition<'notIn'> {
        key: keyof M;
        value: WithIdValue[];
    }
    export interface LikeCondition<M extends Record<string, any>> extends BaseCondition<'like'> {
        key: keyof M;
        value: string;
    }
    export interface NotLikeCondition<M extends Record<string, any>> extends BaseCondition<'notLike'> {
        key: keyof M;
        value: string;
    }
    export interface IsTrueCondition<M extends Record<string, any>> extends BaseCondition<'isTrue'> {
        key: keyof M;
    }
    export interface IsNotTrueCondition<M extends Record<string, any>> extends BaseCondition<'isNotTrue'> {
        key: keyof M;
    }
    export interface IsNullCondition<M extends Record<string, any>> extends BaseCondition<'isNull'> {
        key: keyof M;
    }
    export interface IsNotNullCondition<M extends Record<string, any>> extends BaseCondition<'isNotNull'> {
        key: keyof M;
    }
    export type Condition<M extends Record<string, any>> = AndCondition<M> | OrCondition<M> | EqCondition<M> | NeqCondition<M> | GtCondition<M> | GteCondition<M> | LtCondition<M> | LteCondition<M> | ContainsCondition<M> | NotContainsCondition<M> | HasAnyOfCondition<M> | NotAnyOfCondition<M> | InCondition<M> | NotInCondition<M> | LikeCondition<M> | NotLikeCondition<M> | IsTrueCondition<M> | IsNotTrueCondition<M> | IsNullCondition<M> | IsNotNullCondition<M>;
    export interface OrderBy<M extends Record<string, any>> {
        key: keyof M;
        desc?: boolean;
    }
    export type SelectField<M extends Record<string, any>> = keyof M | Partial<Record<keyof M, string>>;
    export type CreateInput<M extends Record<string, any>> = Omit<M, keyof BaseRecord>;
    export type UpdateInput<M extends Record<string, any>> = Partial<Omit<M, keyof BaseRecord>>;
    export type UpdateInputWithId<M extends Record<string, any>> = Partial<Omit<M, keyof BaseRecord>> & {
        _id: number;
    };
    export type Method = 'find' | 'findOne' | 'count' | 'del' | 'update' | 'create';
    export interface FindOption<M extends Record<string, any>> {
        fields?: SelectField<M>[];
        condition?: Condition<M>;
        orders?: OrderBy<M>[];
        limit?: number;
        offset?: number;
        useApiId?: boolean;
    }
    export interface FineOneOption<M extends Record<string, any>> {
        fields?: SelectField<M>[];
        condition?: Condition<M>;
        orders?: OrderBy<M>[];
        offset?: number;
        useApiId?: boolean;
    }
    export interface CountOption<M extends Record<string, any>> {
        condition?: Condition<M>;
        useApiId?: boolean;
    }
    export interface DelOption<M extends Record<string, any>> {
        condition?: Condition<M>;
        useApiId?: boolean;
        returnFields?: SelectField<M>[];
    }
    export interface UpdateOption<M extends Record<string, any>> {
        condition?: Condition<M>;
        useApiId?: boolean;
        returnFields?: SelectField<M>[];
        data: UpdateInput<M>;
    }
    export interface UpdateWithIdOption<M extends Record<string, any>> {
        useApiId?: boolean;
        returnFields?: SelectField<M>[];
        data: UpdateInputWithId<M>[];
    }
    export interface CreateOption<M extends Record<string, any>> {
        useApiId?: boolean;
        returnFields?: SelectField<M>[];
        data?: CreateInput<M>;
    }
    export interface BatchCreateOption<M extends Record<string, any>> {
        useApiId?: boolean;
        returnFields?: SelectField<M>[];
        data?: CreateInput<M>[];
    }
    export type Option<M extends Record<string, any>> = FindOption<M> | FineOneOption<M> | CountOption<M> | DelOption<M> | UpdateOption<M> | UpdateWithIdOption<M> | CreateOption<M> | BatchCreateOption<M>;
    export {};
}
