import type { XmlMetadata } from './xml/xml-metadata.js';
import { RateLimitThreshold } from 'rate-limit-threshold';
import * as mb from './musicbrainz.types.js';
import { HttpClient, type MultiQueryFormData } from "./http-client.js";
export { XmlMetadata } from './xml/xml-metadata.js';
export { XmlIsrc } from './xml/xml-isrc.js';
export { XmlIsrcList } from './xml/xml-isrc-list.js';
export { XmlRecording } from './xml/xml-recording.js';
export * from './musicbrainz.types.js';
export type RelationsIncludes = 'area-rels' | 'artist-rels' | 'event-rels' | 'instrument-rels' | 'label-rels' | 'place-rels' | 'recording-rels' | 'release-rels' | 'release-group-rels' | 'series-rels' | 'url-rels' | 'work-rels';
export type SubQueryIncludes = 
/**
 * include discids for all media in the releases
 */
'discids'
/**
 * include media for all releases, this includes the # of tracks on each medium and its format.
 */
 | 'media'
/**
 * include isrcs for all recordings
 */
 | 'isrcs'
/**
 * include artists credits for all releases and recordings
 */
 | 'artist-credits'
/**
 * include only those releases where the artist appears on one of the tracks, only valid on artists in combination with `releases`
 */
 | 'various-artists';
export type MiscIncludes = 'aliases' | 'annotation' | 'tags' | 'genres' | 'ratings' | 'media';
export type AreaIncludes = MiscIncludes | RelationsIncludes;
export type ArtistIncludes = MiscIncludes | RelationsIncludes | 'recordings' | 'releases' | 'release-groups' | 'works';
export type CollectionIncludes = MiscIncludes | RelationsIncludes | 'user-collections';
export type EventIncludes = MiscIncludes | RelationsIncludes;
export type GenreIncludes = MiscIncludes;
export type InstrumentIncludes = MiscIncludes | RelationsIncludes;
export type LabelIncludes = MiscIncludes | RelationsIncludes | 'releases';
export type PlaceIncludes = MiscIncludes | RelationsIncludes;
export type RecordingIncludes = MiscIncludes | RelationsIncludes | SubQueryIncludes | 'artists' | 'releases' | 'isrcs';
export type ReleaseIncludes = MiscIncludes | SubQueryIncludes | RelationsIncludes | 'artists' | 'collections' | 'labels' | 'recordings' | 'release-groups';
export type ReleaseGroupIncludes = MiscIncludes | SubQueryIncludes | RelationsIncludes | 'artists' | 'releases';
export type SeriesIncludes = MiscIncludes | RelationsIncludes;
export type WorkIncludes = MiscIncludes | RelationsIncludes;
export type UrlIncludes = RelationsIncludes;
export type IFormData = {
    [key: string]: string | number;
};
export interface IMusicBrainzConfig {
    botAccount?: {
        username?: string;
        password?: string;
    };
    baseUrl?: string;
    appName?: string;
    appVersion?: string;
    /**
     * HTTP Proxy
     */
    proxy?: string;
    /**
     * User e-mail address or application URL
     */
    appContactInfo?: string;
    disableRateLimiting?: boolean;
}
interface IInternalConfig extends IMusicBrainzConfig {
    baseUrl: string;
}
export interface ICsrfSession {
    sessionKey: string;
    token: string;
}
export interface ISessionInformation {
    csrf: ICsrfSession;
    loggedIn?: boolean;
}
export declare class MusicBrainzApi {
    readonly config: IInternalConfig;
    protected rateLimiter: RateLimitThreshold;
    protected httpClient: HttpClient;
    protected session?: ISessionInformation;
    static fetchCsrf(html: string): ICsrfSession;
    private static fetchValue;
    constructor(_config?: IMusicBrainzConfig);
    protected initHttpClient(): HttpClient;
    restGet<T>(relUrl: string, query?: MultiQueryFormData): Promise<T>;
    /**
     * Lookup entity
     * @param entity 'area', 'artist', collection', 'instrument', 'label', 'place', 'release', 'release-group', 'recording', 'series', 'work', 'url' or 'event'
     * @param mbid Entity MBID
     * @param inc Includes, which allows you to request more information to be included about the entity
     */
    lookup(entity: 'area', mbid: string, inc?: AreaIncludes[]): Promise<mb.IArea>;
    lookup(entity: 'artist', mbid: string, inc?: ArtistIncludes[]): Promise<mb.IArtist>;
    lookup(entity: 'collection', mbid: string, inc?: CollectionIncludes[]): Promise<mb.ICollection>;
    lookup(entity: 'instrument', mbid: string, inc?: InstrumentIncludes[]): Promise<mb.IInstrument>;
    lookup(entity: 'label', mbid: string, inc?: LabelIncludes[]): Promise<mb.ILabel>;
    lookup(entity: 'place', mbid: string, inc?: PlaceIncludes[]): Promise<mb.IPlace>;
    lookup(entity: 'release', mbid: string, inc?: ReleaseIncludes[]): Promise<mb.IRelease>;
    lookup(entity: 'release-group', mbid: string, inc?: ReleaseGroupIncludes[]): Promise<mb.IReleaseGroup>;
    lookup(entity: 'recording', mbid: string, inc?: RecordingIncludes[]): Promise<mb.IRecording>;
    lookup(entity: 'series', mbid: string, inc?: SeriesIncludes[]): Promise<mb.ISeries>;
    lookup(entity: 'work', mbid: string, inc?: WorkIncludes[]): Promise<mb.IWork>;
    lookup(entity: 'url', mbid: string, inc?: UrlIncludes[]): Promise<mb.IUrl>;
    lookup(entity: 'event', mbid: string, inc?: EventIncludes[]): Promise<mb.IEvent>;
    lookupUrl(url: string, inc?: UrlIncludes[]): Promise<mb.IUrl>;
    lookupUrl(url: string[], inc?: UrlIncludes[]): Promise<mb.IUrlLookupResult>;
    /**
     * Browse entity
     * https://wiki.musicbrainz.org/MusicBrainz_API#Browse
     * https://wiki.musicbrainz.org/MusicBrainz_API#Linked_entities
     * https://wiki.musicbrainz.org/Development/JSON_Web_Service#Browse_Requests
     * For example: http://musicbrainz.org/ws/2/release?label=47e718e1-7ee4-460c-b1cc-1192a841c6e5&offset=12&limit=2
     * @param entity MusicBrainz entity
     * @param query Query, like: {<entity>: <MBID:}
     * @param inc Includes, which allows you to request more information to be included about the entity
     */
    browse(entity: 'area', query?: mb.IBrowseAreasQuery, inc?: AreaIncludes[]): Promise<mb.IBrowseAreasResult>;
    browse(entity: 'artist', query?: mb.IBrowseArtistsQuery, inc?: ArtistIncludes[]): Promise<mb.IBrowseArtistsResult>;
    browse(entity: 'collection', query?: mb.IBrowseCollectionsQuery, inc?: CollectionIncludes[]): Promise<mb.IBrowseCollectionsResult>;
    browse(entity: 'event', query?: mb.IBrowseEventsQuery, inc?: EventIncludes[]): Promise<mb.IBrowseEventsResult>;
    browse(entity: 'label', query?: mb.IBrowseLabelsQuery, inc?: LabelIncludes[]): Promise<mb.IBrowseLabelsResult>;
    browse(entity: 'instrument', query?: mb.IBrowseInstrumentsQuery, inc?: InstrumentIncludes[]): Promise<mb.IBrowseInstrumentsResult>;
    browse(entity: 'place', query?: mb.IBrowsePlacesQuery, inc?: PlaceIncludes[]): Promise<mb.IBrowsePlacesResult>;
    browse(entity: 'recording', query?: mb.IBrowseRecordingsQuery, inc?: RecordingIncludes[]): Promise<mb.IBrowseRecordingsResult>;
    browse(entity: 'release', query?: mb.IBrowseReleasesQuery, inc?: ReleaseIncludes[]): Promise<mb.IBrowseReleasesResult>;
    browse(entity: 'release-group', query?: mb.IBrowseReleaseGroupsQuery, inc?: ReleaseGroupIncludes[]): Promise<mb.IBrowseReleaseGroupsResult>;
    browse(entity: 'series', query?: mb.IBrowseSeriesQuery, inc?: SeriesIncludes[]): Promise<mb.IBrowseSeriesResult>;
    browse(entity: 'url', query?: mb.IBrowseUrlsQuery, inc?: UrlIncludes[]): Promise<mb.IUrl>;
    browse(entity: 'work', query?: mb.IBrowseWorksQuery, inc?: WorkIncludes[]): Promise<mb.IBrowseWorksResult>;
    /**
     * Search an entity using a search query
     * @param entity e.g. 'recording'
     * @param query e.g.: '" artist: Madonna, track: Like a virgin"' or object with search terms: {artist: Madonna}
     */
    search(entity: 'annotation', query: mb.ISearchQuery<(MiscIncludes | RelationsIncludes)>): Promise<mb.IAnnotationList>;
    search(entity: 'area', query: mb.ISearchQuery<AreaIncludes> & mb.ILinkedEntitiesArea): Promise<mb.IAreaList>;
    search(entity: 'artist', query: mb.ISearchQuery<ArtistIncludes> & mb.ILinkedEntitiesArea): Promise<mb.IArtistList>;
    search(entity: 'cdstub', query: mb.ISearchQuery<(MiscIncludes | RelationsIncludes)>): Promise<mb.ICdStubList>;
    search(entity: 'event', query: mb.ISearchQuery<EventIncludes> & mb.ILinkedEntitiesEvent): Promise<mb.IEventList>;
    search(entity: 'instrument', query: mb.ISearchQuery<InstrumentIncludes> & mb.ILinkedEntitiesInstrument): Promise<mb.IInstrumentList>;
    search(entity: 'label', query: mb.ISearchQuery<LabelIncludes> & mb.ILinkedEntitiesLabel): Promise<mb.ILabelList>;
    search(entity: 'place', query: mb.ISearchQuery<PlaceIncludes> & mb.ILinkedEntitiesPlace): Promise<mb.IPlaceList>;
    search(entity: 'recording', query: mb.ISearchQuery<RecordingIncludes> & mb.ILinkedEntitiesArea): Promise<mb.IRecordingList>;
    search(entity: 'release', query: mb.ISearchQuery<ReleaseIncludes> & mb.ILinkedEntitiesArea): Promise<mb.IReleaseList>;
    search(entity: 'release-group', query: mb.ISearchQuery<ReleaseGroupIncludes> & mb.ILinkedEntitiesArea): Promise<mb.IReleaseGroupList>;
    search(entity: 'series', query: mb.ISearchQuery<SeriesIncludes> & mb.ILinkedEntitiesSeries): Promise<mb.ISeriesList>;
    search(entity: 'tag', query: mb.ISearchQuery<MiscIncludes | RelationsIncludes>): Promise<mb.ITagList>;
    search(entity: 'url', query: mb.ISearchQuery<UrlIncludes> & mb.ILinkedEntitiesUrl): Promise<mb.IUrlList>;
    search(entity: 'work', query: mb.ISearchQuery<WorkIncludes> & mb.ILinkedEntitiesWork): Promise<mb.IWorkList>;
    postRecording(xmlMetadata: XmlMetadata): Promise<void>;
    post(entity: mb.EntityType, xmlMetadata: XmlMetadata): Promise<void>;
    /**
     * Submit entity
     * @param entity Entity type e.g. 'recording'
     * @param mbid
     * @param formData
     */
    editEntity(entity: mb.EntityType, mbid: string, formData: Record<string, any>): Promise<void>;
    /**
     * Set URL to recording
     * @param recording Recording to update
     * @param url2add URL to add to the recording
     * @param editNote Edit note
     */
    addUrlToRecording(recording: mb.IRecording, url2add: {
        linkTypeId: mb.LinkType;
        text: string;
    }, editNote?: string): Promise<void>;
    /**
     * Add ISRC to recording
     * @param recording Recording to update
     * @param isrc ISRC code to add
     */
    addIsrc(recording: mb.IRecording, isrc: string): Promise<void>;
    /**
     * Add Spotify-ID to MusicBrainz recording.
     * This function will automatically lookup the recording title, which is required to submit the recording URL
     * @param recording MBID of the recording
     * @param spotifyId Spotify ID
     * @param editNote Comment to add.
     */
    addSpotifyIdToRecording(recording: mb.IRecording, spotifyId: string, editNote: string): Promise<void>;
    protected getSession(): Promise<ISessionInformation>;
    protected applyRateLimiter(): Promise<void>;
}
export declare function makeAndQueryString(keyValuePairs: IFormData): string;
