export declare type Id = string;
export declare type URI = string;
export interface Request {
    /** POST, PUT, etc. */
    method: string;
    /** Full url. */
    url: URI;
    /** Extra headers in addition to what fetch may do. */
    headers?: Record<string, string>;
    /** Payload. */
    data: any;
}
export interface Config {
    APIUrl: URI;
    AccessToken?: () => string;
    callerId?: Id;
    CallerID?: Id;
    Log?: any;
}
export declare type Fetcher = (config: Config, request: Request, callback: (error: boolean, ctx: any) => void) => void;
/** Provide a fetcher strategy. */
export interface FetchProvider {
    fetch?: Fetcher;
}
/** Provide a logger. */
export interface Logger {
    shouldLog?: (category: string) => boolean;
    log?: (category: string, message: string, ctx: any) => void;
}
export interface GetListResponse<T> {
    List: T[];
    Count?: number;
    fetchXmlPagingCookie?: string;
}
export interface UpdateResponse {
    EntityID: Id;
}
export interface Attribute {
    Property: string;
    Type?: string;
}
export interface QueryOptionBase {
    FormattedValues?: boolean;
    Select?: string[];
    Filter?: string;
    /** List of strings "attributename desc/asc" */
    OrderBy?: string[];
    Top?: number;
    Path?: Array<Attribute | string>;
}
export interface ExpandQueryOptions extends QueryOptionBase {
    Property: string;
}
export interface QueryOptions extends QueryOptionBase {
    Expand?: ExpandQueryOptions[];
    FetchXml?: string;
    IncludeCount?: boolean;
    Skip?: number;
    SystemQuery?: string;
    UserQuery?: string;
    RecordAction?: (record: any) => void;
    PageAction?: (list: any[]) => void;
    BatchHeaders?: Record<string, string>;
    /** Debug tag. */
    tag?: string;
}
export interface Option {
    Value: number;
    Label: string;
}
/** General purpose dynamics web api client. */
export interface _Client_IN_PROGRESS_ {
    GetList<T>(uri: URI, QueryOptions?: QueryOptions): Promise<GetListResponse<T>>;
    Get<T>(entityCollection: string, entityID: Id | null, QueryOptions?: QueryOptions): Promise<T>;
    GetCount(uri: URI, QueryOptions?: QueryOptions): any;
    Create(entityCollection: string, data: any): Promise<Id>;
    Update(entityCollection: string, key: string, data: any, Upsert: boolean): Promise<void>;
    Delete(entityCollection: string, entityID: Id): Promise<boolean>;
    Associate(fromEntityCollection: string, fromEntityID: Id, navProperty: String, toEntityCollection: string, toEntityID: Id): Promise<boolean>;
    DeleteAssociation(fromEntityCollection: string, fromEntityID: Id, navProperty: string, toEntityCollection: string, toEntityID: Id): Promise<boolean>;
    ExecuteFunction(functionName: string, parameters: any, entityCollection: string | null, entityID: Id | null): Promise<boolean>;
    ExecuteAction(actionName: string, data: any, entityCollection: string | null, entityID: Id | null): Promise<boolean>;
    batch<T>(entity: string, fetchXml: string, QueryOptions?: QueryOptions): Promise<GetListResponse<T>>;
}
/**
 * Defaults to XMLHTTPRequest.
 *
 * @todo Add the ability to issue pure http query so we can fetch full links provided
 * in some odata responses.
 */
export declare class CRMWebAPI {
    constructor(config: Config & FetchProvider & Logger);
    protected fp: Fetcher;
    private config;
    protected shouldLog?: (category: string) => boolean;
    protected log?: (category: string, message: string, ctx: any) => void;
    /** For now, pass in extra headers in payload.headers and data in payload.data. */
    protected fetch(config: Config, method: string, url: URI, payload: any, callback: (error: boolean, ctx: any) => void): void;
    private _log(category, message, data?);
    private _restParam(func, startIndex?);
    private whilst(test, iterator, callback);
    GetList: <T>(uri: string, QueryOptions?: QueryOptions | undefined) => Promise<GetListResponse<T>>;
    /** Issue a http fetch directly. The response is JSON parsed but not restructured. */
    Fetch: (url: string, QueryOptions?: QueryOptions | undefined, method?: string | undefined) => Promise<any>;
    Get: <T>(entityCollection: string, entityID: string | null, QueryOptions?: QueryOptions | undefined) => Promise<T>;
    GetCount: (uri: string, QueryOptions?: QueryOptions | undefined) => Promise<number>;
    Create: (entityCollection: string, data: any) => Promise<string>;
    Update: (entityCollection: string, key: string, data: any, Upsert?: boolean) => Promise<any>;
    Delete: (entityCollection: string, entityID: string) => Promise<boolean>;
    Associate: (fromEntityCollection: string, fromEntityID: string, navProperty: String, toEntityCollection: string, toEntityID: string) => Promise<boolean>;
    DeleteAssociation: (fromEntityCollection: string, fromEntityID: string, navProperty: string, toEntityCollection: string, toEntityID: string) => Promise<boolean>;
    ExecuteFunction: (functionName: string, parameters: any, entityCollection?: string | null, entityID?: string | null) => Promise<any>;
    ExecuteAction: (actionName: string, data: any, entityCollection?: string | null, entityID?: string | null) => Promise<any>;
    private _BuildQueryURL(uri, queryOptions, config);
    private _BuildQueryHeaders(queryOptions, config);
    private parseResponseHeaders(headerStr);
    _DateReviver(key: string, value: any): any;
    GetOptionSetByName: (optionSetName: string) => Promise<any>;
    GetOptionSetUserLabels: (optionSetName: string) => Promise<Option[]>;
    GetEntityDisplayNameList(LCID: string): Promise<{}>;
    GetAttributeDisplayNameList(entityID: string, LCID: string): Promise<{}>;
    batch<T>(entity: string, fetchXml: string, QueryOptions?: QueryOptions): Promise<GetListResponse<T>>;
    private _hack(config, method, url, payload, callback);
    private _sliceBatchResponse(response);
}
export default CRMWebAPI;
