/// <reference types="node" />
import * as log from "loglevel";
import * as loglevel from "loglevel";
/**
 * Cancellable promise. Extends the functionality of the native Promise to include the cancel method.
 *
 * Example:
 *
 * ```ts
 *
 * const cancellableFetchPromise = new CancellablePromise(async (resolve, reject, onCancel) => {
 *     const request = fetch("https://example.com/");
 *
 *     onCancel(() => request.cancel());
 *
 *     try {
 *         const response = await request;
 *         resolve(response);
 *     } catch (err) {
 *         reject(err);
 *     }
 * });
 *
 * cancellableFetchPromise.cancel();
 * ```
 */
declare class CancellablePromise<T> extends Promise<T> {
    private readonly id;
    private rejectPromise?;
    private static readonly cancellationMap;
    /**
     * Creates a new CancellablePromise.
     * @param executor A callback used to initialize the promise. This callback is passed three arguments:
     * a resolve callback used to resolve the promise with a value or the result of another promise,
     * a reject callback used to reject the promise with a provided reason or error,
     * and an onCancel callback used to define behavior of cancellation.
     */
    constructor(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: string | Error) => void, onCancel: (cancellationFunction: () => void) => void) => void);
    /**
     * Cancels the promise and invokes the cancellation callback if it was defined during instantiation. Cancellation will result in the promise being rejected.
     */
    cancel(): this;
}
type Headers = {
    [id: string]: string;
};
interface Response {
    status: any;
    headers: Headers;
    body: any;
}
/**
 * Provides generic network interface
 */
declare class Transport {
    private static request;
    /**
     * Make a GET request by given URL
     */
    get(url: string, headers: Headers): CancellablePromise<Response>;
    /**
     * Make a POST request by given URL
     */
    post(url: string, headers: Headers, body?: any): CancellablePromise<Response>;
}
interface BackoffOverride {
    max: number;
    min: number;
    maxAttemptsCount?: number;
}
interface McsOptions {
    region?: string;
    retryWhenThrottledOverride?: boolean;
    backoffConfigOverride?: BackoffOverride;
}
interface Options {
    region?: string;
    logLevel?: log.LogLevelDesc;
    transport?: Transport;
    retryWhenThrottledOverride?: boolean;
    backoffConfigOverride?: BackoffOverride;
    MCS?: McsOptions;
}
declare class Configuration {
    token: string;
    readonly retryWhenThrottledOverride: boolean;
    readonly backoffConfigOverride: BackoffOverride;
    readonly mediaUrl: string;
    readonly mediaSetUrl: string;
    private readonly region;
    constructor(token: string, baseUrl: string, baseSetUrl: string | null, options: Options);
    static get backoffConfigDefault(): BackoffOverride;
    static get retryWhenThrottledDefault(): boolean;
    updateToken(token: string): void;
}
declare class Network {
    private readonly config;
    private readonly transport;
    constructor(config: Configuration, transport: Transport);
    private backoffConfig;
    private retryWhenThrottled;
    private executeWithRetry;
    get(url: string): CancellablePromise<any>;
    post(url: string, category: MediaCategory | null, media: string | Buffer | Blob | FormData | Record<string, unknown>, contentType?: string, filename?: string): CancellablePromise<any>;
}
type MediaCategory = "media" | "body" | "history";
/**
 * @internal
 * A subset of MediaRecord for Conversation-specific purposes.
 */
interface MediaState {
    sid: string;
    category: MediaCategory;
    filename: string | null;
    contentType: string;
    size: number;
}
interface Links {
    content: string;
    content_direct_temporary?: string;
}
interface MediaResponse {
    sid: string;
    service_sid: string;
    channel_sid: string | null;
    message_sid: string | null;
    date_created?: string;
    date_upload_updated?: string;
    date_updated?: string;
    size: number;
    content_type: string;
    filename?: string;
    category?: MediaCategory;
    author: string;
    is_multipart_upstream?: boolean;
    url: string;
    links: Links;
}
/**
 * @classdesc A Media represents a metadata information for the media upload
 * @property {String} sid - The server-assigned unique identifier for Media
 * @property {String} serviceSid - Service instance id which Media belongs/uploaded to
 * @property {Date} dateCreated - When the Media was created
 * @property {Date} dateUpdated - When the Media was updated
 * @property {Number} size - Size of media, bytes
 * @property {String} contentType - content type of media
 * @property {String} fileName - file name, if present, null otherwise
 * @property {MediaCategory} category - attachment category
 */
declare class Media {
    private state;
    private network;
    private config;
    constructor(config: Configuration, network: Network, data: MediaResponse);
    get sid(): string;
    get serviceSid(): string;
    get dateCreated(): Date | null;
    get dateUpdated(): Date | null;
    get contentType(): string;
    get size(): number;
    /** @deprecated Use filename instead */
    get fileName(): string | null;
    get filename(): string | null;
    get category(): MediaCategory;
    /**
     * Returns direct content URL to uploaded binary. This URL will expire after some time.
     * This function gets a new URL every time, preventing it from expiring but putting additional load on backend.
     * See getCachedContentUrl() for a function that reduces the amount of network requests.
     *
     * It is reasonable to build your own refresh logic upon these two functions: as soon as URL returned
     * by getCachedContentUrl() returns 40x status you should call getContentUrl() to refresh it.
     */
    getContentUrl(): CancellablePromise<string | null>;
    private _update;
    /**
     * @internal
     * This payload is compatible with Conversations' media object _state().
     */
    _state(): MediaState;
}
interface Options$0 {
    region?: string;
    logLevel?: loglevel.LogLevelDesc;
    transport?: Transport;
}
/**
 * @classdesc A Client provides an interface for Media Content Service
 */
declare class Client {
    // eslint-disable-next-line
    private readonly transport;
    private options;
    private network;
    private config;
    static readonly version: string;
    /**
     * Base URLs must be full URLs with host. If host is not provided it will be generated from a default configuration
     * template using options.region.
     *
     * @param {String} token - Access token
     * @param {String} baseUrl - Base URL for Media Content Service Media resource, i.e. /v1/Services/{serviceSid}/Media
     * @param {String} baseSetUrl - Base URL for Media Content Service MediaSet resource, i.e. /v1/Services/{serviceSid}/MediaSet
     * @param {Client#ClientOptions} [options] - Options to customize the Client
     */
    constructor(token: string, baseUrl: string, baseSetUrl: string | null, options?: Options$0);
    /**
     * These options can be passed to Client constructor
     * @typedef {Object} Client#ClientOptions
     * @property {String} [logLevel='silent'] - The level of logging to enable. Valid options
     *   (from strictest to broadest): ['silent', 'error', 'warn', 'info', 'debug', 'trace']
     */
    /**
     * Update the token used for Client operations
     * @param {String} token - The JWT string of the new token
     * @returns {void}
     */
    updateToken(token: string): void;
    /**
     * Gets media from media service
     * @param {String} sid - Media's SID
     */
    get(sid: string): CancellablePromise<Media>;
    /**
     * Posts raw content to media service
     * @param {String} contentType - content type of media
     * @param {String|Buffer|Blob} media - content to post
     * @param {MediaCategory|null} category - category for the media
     */
    post(contentType: string, media: string | Buffer | Blob, category: MediaCategory | null, filename?: string): CancellablePromise<Media>;
    /**
     * Posts FormData to media service. Can be used only with browser engine's FormData.
     * In non-browser FormData case the method will do promise reject with
     * new TypeError("Posting FormData supported only with browser engine's FormData")
     * @param {FormData} formData - form data to post
     * @param {MediaCategory|null} category - category for the media
     */
    postFormData(formData: FormData, category?: MediaCategory | null): CancellablePromise<Media>;
    /**
     * Retrieve information about multiple media SIDs at the same time.
     * @param mediaSids Array of Media SIDs to get information from.
     */
    mediaSetGet(mediaSids: string[]): CancellablePromise<Media[]>;
    /**
     * Retrieve temporary URLs for a set of media SIDs.
     * @param mediaSids array of the media SIDs to get URLs from.
     */
    mediaSetGetContentUrls(mediaSids: string[]): CancellablePromise<Map<string, string>>;
}
export { CancellablePromise, Client, Client as McsClient, Client as default, Media, Media as McsMedia, MediaCategory, MediaCategory as McsMediaCategory, MediaState, MediaState as McsMediaState };
