import polyfillFetch, { Response as Response$1 } from 'node-fetch';

declare class Base$1 {
    protected clientId: number;
    protected clientSecret: string;
    protected redirectUri: string;
    protected oauthUrl: string;
    protected fetch: typeof fetch | typeof polyfillFetch;
    constructor(clientId: number, clientSecret: string, redirectUri: string, options?: {
        polyfillFetch?: typeof polyfillFetch;
    });
}

declare const isOsuJSErrorSymbol: unique symbol;
/**
 * Documentation: {@link https://osujs.mario564.com/extras/error-handling}
 */
declare class OsuJSGeneralError extends Error {
    readonly _: {
        [isOsuJSErrorSymbol]: boolean;
    };
    type: 'invalid_json_syntax' | 'network_error' | 'undefined_fetch';
    constructor(type: 'invalid_json_syntax' | 'network_error' | 'undefined_fetch');
}
/**
 * Documentation: {@link https://osujs.mario564.com/extras/error-handling}
 */
declare class OsuJSUnexpectedResponseError extends Error {
    readonly _: {
        [isOsuJSErrorSymbol]: boolean;
    };
    type: "unexpected_response";
    private response1;
    constructor(response: Response | Response$1);
    response<T extends boolean | undefined = undefined>(polyfill?: T): T extends true ? Response$1 : Response;
}

/**
 * Documentation: {@link https://osujs.mario564.com/references/modes-enum}
 */
declare enum ModesEnum {
    osu = 0,
    taiko = 1,
    fruits = 2,
    mania = 3
}
/**
 * Documentation: {@link https://osujs.mario564.com/references/status-enum}
 */
declare enum StatusEnum {
    graveyard = -2,
    wip = -1,
    pending = 0,
    ranked = 1,
    approved = 2,
    qualified = 3,
    loved = 4
}
/**
 * Documentation: {@link https://osujs.mario564.com/references/genres-enum}
 */
declare enum GenresEnum {
    Any = 0,
    Unspecified = 1,
    'Video Game' = 2,
    Anime = 3,
    Rock = 4,
    Pop = 5,
    Other = 6,
    Novelty = 7,
    'Hip Hop' = 9,
    Electronic = 10,
    Metal = 11,
    Classical = 12,
    Folk = 13,
    Jazz = 14
}
/**
 * Documentation: {@link https://osujs.mario564.com/references/languages-enum}
 */
declare enum LanguagesEnum {
    Any = 0,
    Unspecified = 1,
    English = 2,
    Japanese = 3,
    Chinese = 4,
    Instrumental = 5,
    Korean = 6,
    French = 7,
    German = 8,
    Swedish = 9,
    Spanish = 10,
    Italian = 11,
    Russian = 12,
    Polish = 13,
    Other = 14
}
/**
 * Documentation: {@link https://osujs.mario564.com/references/mods-enum}
 */
declare enum ModsEnum {
    NF = 1,
    EZ = 2,
    TD = 4,
    HD = 8,
    HR = 16,
    SD = 32,
    DT = 64,
    RX = 128,
    HT = 256,
    NC = 512,
    FL = 1024,
    AT = 2048,
    SO = 4096,
    AP = 8192,
    PF = 16384,
    '4K' = 32768,
    '5K' = 65536,
    '6K' = 131072,
    '7K' = 262144,
    '8K' = 524288,
    FI = 1048576,
    RD = 2097152,
    CN = 4194304,
    TP = 8388608,
    K9 = 16777216,
    KC = 33554432,
    '1K' = 67108864,
    '3K' = 134217728,
    '2K' = 268435456,
    SV2 = 536870912,
    MR = 1073741824
}
/**
 * Documentation: {@link https://osujs.mario564.com/references/scoring-type-enum}
 */
declare enum ScoringTypeEnum {
    Score = 0,
    Accuracy = 1,
    Combo = 2,
    'Score V2' = 3
}
/**
 * Documentation: {@link https://osujs.mario564.com/references/team-type-enum}
 */
declare enum TeamTypeEnum {
    'Head To Head' = 0,
    'Tag Co-Op' = 1,
    'Team VS' = 2,
    'Tag Team VS' = 3
}
/**
 * Documentation: {@link https://osujs.mario564.com/references/team-color-enum}
 */
declare enum TeamColorEnum {
    Blue = 1,
    Red = 2
}

type BaseMod<TAcronym extends string, TSettings extends Record<string, any> | undefined = undefined> = TSettings extends undefined ? {
    acronym: TAcronym;
} : {
    acronym: TAcronym;
    settings?: TSettings;
};
type EasyMod = BaseMod<'EZ', {
    retries: number;
}>;
type NoFailMod = BaseMod<'NF'>;
type HalfTimeMod = BaseMod<'HT', {
    speed_change: number;
    adjust_pitch: boolean;
}>;
type DaycoreMod = BaseMod<'DC', {
    speed_change: number;
}>;
type HardRockMod = BaseMod<'HR'>;
type SuddenDeathMod = BaseMod<'SD', {
    restart: boolean;
}>;
type PerfectMod = BaseMod<'PF', {
    restart: boolean;
}>;
type DoubleTimeMod = BaseMod<'DT', {
    speed_change: number;
    adjust_pitch: boolean;
}>;
type NightcoreMod = BaseMod<'NC', {
    speed_change: number;
}>;
type HiddenMod = BaseMod<'HD', {
    only_fade_approach_circles: boolean;
}>;
type FlaslightMod = BaseMod<'FL', {
    follow_delay: number;
    size_multiplier: number;
    combo_based_size: boolean;
}>;
type BlindsMod = BaseMod<'BL'>;
type StrictTrackingMod = BaseMod<'ST'>;
type AccuracyChallengeMod = BaseMod<'AC', {
    minimum_accuracy: number;
    accuracy_judge_mode: string;
    restart: boolean;
}>;
type TargetPracticeMod = BaseMod<'TP', {
    seed: number;
    metronome: boolean;
}>;
type DifficultyAdjustMod = BaseMod<'DA', {
    circle_size: number;
    approach_rate: number;
    drain_rate: number;
    overall_difficulty: number;
    extended_limits: boolean;
}>;
type ClassicMod = BaseMod<'CL', {
    no_slider_head_accuracy: boolean;
    classic_note_lock: boolean;
    always_play_tail_sample: boolean;
    fade_hit_circle_early: boolean;
    classic_health: boolean;
}>;
type RandomMod = BaseMod<'RD', {
    angle_sharpness: number;
    seed: number;
}>;
type MirrorMod = BaseMod<'MR', {
    reflection: string;
}>;
type AlternateMod = BaseMod<'AL'>;
type SingleTapMod = BaseMod<'SG'>;
type AutoplayMod = BaseMod<'AT'>;
type CinemaMod = BaseMod<'CN'>;
type RelaxMod = BaseMod<'RX'>;
type AutopilotMod = BaseMod<'AP'>;
type SpunOutMod = BaseMod<'SO'>;
type TransformMod = BaseMod<'TR'>;
type WiggleMod = BaseMod<'WG', {
    strength: number;
}>;
type SpinInMod = BaseMod<'SI'>;
type GrowMod = BaseMod<'GR', {
    start_scale: number;
}>;
type DeflateMod = BaseMod<'DF', {
    start_scale: number;
}>;
type WindUpMod = BaseMod<'WU', {
    initial_rate: number;
    final_rate: number;
    adjust_pitch: boolean;
}>;
type WindDownMod = BaseMod<'WD', {
    initial_rate: number;
    final_rate: number;
    adjust_pitch: boolean;
}>;
type TraceableMod = BaseMod<'TC'>;
type BarrelRollMod = BaseMod<'BR', {
    spin_speed: number;
    direction: string;
}>;
type ApproachDifferentMod = BaseMod<'AD', {
    scale: number;
    style: string;
}>;
type MutedMod = BaseMod<'MU', {
    inverse_muting: boolean;
    enable_metronome: boolean;
    mute_combo_count: number;
    affects_hit_sounds: boolean;
}>;
type NoScopeMod = BaseMod<'NS', {
    hidden_combo_count: number;
}>;
type MagnetisedMod = BaseMod<'MG', {
    attraction_strength: number;
}>;
type RepelMod = BaseMod<'RP', {
    repulsion_strength: number;
}>;
type AdaptiveSpeedMod = BaseMod<'AS', {
    initial_rate: number;
    adjust_pitch: boolean;
}>;
type FreezeFrameMod = BaseMod<'FR'>;
type BubblesMod = BaseMod<'BU'>;
type SynesthesiaMod = BaseMod<'SY'>;
type DepthMod = BaseMod<'DP', {
    max_depth: number;
    show_approach_circles: boolean;
}>;
type TouchDeviceMod = BaseMod<'TD'>;
type ScoreV2Mod = BaseMod<'SV2'>;
type SwapMod = BaseMod<'SW'>;
type FloatingFruitsMod = BaseMod<'FF'>;
type FadeInMod = BaseMod<'FI', {
    coverage: number;
}>;
type DualStagesMod = BaseMod<'DS'>;
type InvertMod = BaseMod<'IN'>;
type ConstantSpeedMod = BaseMod<'CS'>;
type HoldOffMod = BaseMod<'HO'>;
type Key1Mod = BaseMod<'1K'>;
type Key2Mod = BaseMod<'2K'>;
type Key3Mod = BaseMod<'3K'>;
type Key4Mod = BaseMod<'4K'>;
type Key5Mod = BaseMod<'5K'>;
type Key6Mod = BaseMod<'6K'>;
type Key7Mod = BaseMod<'7K'>;
type Key8Mod = BaseMod<'8K'>;
type Key9Mod = BaseMod<'9K'>;
type Key10Mod = BaseMod<'10K'>;
type ModSettings = EasyMod | NoFailMod | HalfTimeMod | DaycoreMod | HardRockMod | SuddenDeathMod | PerfectMod | DoubleTimeMod | NightcoreMod | HiddenMod | FlaslightMod | BlindsMod | StrictTrackingMod | AccuracyChallengeMod | TargetPracticeMod | DifficultyAdjustMod | ClassicMod | RandomMod | MirrorMod | AlternateMod | SingleTapMod | AutoplayMod | CinemaMod | RelaxMod | AutopilotMod | SpunOutMod | TransformMod | WiggleMod | SpinInMod | GrowMod | DeflateMod | WindUpMod | WindDownMod | TraceableMod | BarrelRollMod | ApproachDifferentMod | MutedMod | NoScopeMod | MagnetisedMod | RepelMod | AdaptiveSpeedMod | FreezeFrameMod | BubblesMod | SynesthesiaMod | DepthMod | TouchDeviceMod | ScoreV2Mod | SwapMod | FloatingFruitsMod | FadeInMod | DualStagesMod | InvertMod | ConstantSpeedMod | HoldOffMod | Key1Mod | Key2Mod | Key3Mod | Key4Mod | Key5Mod | Key6Mod | Key7Mod | Key8Mod | Key9Mod | Key10Mod;

/**
 * Timestamp string in ISO 8601 format
 */
type ISOTimestamp = string;
/**
 * Documentation: {@link https://osujs.mario564.com/extras/error-handling}
 */
type OsuJSError = OsuJSGeneralError | OsuJSUnexpectedResponseError;
type Cursor = string | null;
type SafeParse<TData, TUsePolyfillResponse extends boolean = false> = {
    success: true;
    data: TData;
} | {
    success: false;
    response: TUsePolyfillResponse extends true ? Response$1 : Response;
};
type Mod = keyof typeof ModsEnum | 'DC' | 'BL' | 'ST' | 'AC' | 'DA' | 'CL' | 'AL' | 'SG' | 'TR' | 'WG' | 'SI' | 'GR' | 'DF' | 'WU' | 'WD' | 'TC' | 'BR' | 'AD' | 'MU' | 'NS' | 'MG' | 'RP' | 'AS' | 'FR' | 'BU' | 'SY' | 'DP' | 'SW' | 'FF' | 'DS' | 'IN' | 'CS' | 'HO' | '9K' | '10K';
type RankStatus = keyof typeof StatusEnum;
type GameMode = 'fruits' | 'mania' | 'osu' | 'taiko';
type UserBeatmapsType = 'favourite' | 'graveyard' | 'guest' | 'loved' | 'most_played' | 'nominated' | 'pending' | 'ranked';
type CommentableType = 'beatmapset' | 'news_post' | 'build';
type CommentSort = 'new' | 'old' | 'top';
type MultiplayerScoresSort = 'score_asc' | 'score_desc';
type RankingType = 'charts' | 'country' | 'performance' | 'score';
type UserScoreType = 'best' | 'firsts' | 'recent';
type ChangelogStream = 'stable40' | 'beta40' | 'cuttingedge' | 'lazer' | 'web';
type DiscussionMessageType = 'suggestion' | 'problem' | 'mapper_note' | 'praise' | 'hype' | 'review';
type Playstyle = 'mouse' | 'keyboard' | 'tablet' | 'touch';
type Scope = 'chat.read' | 'chat.write' | 'chat.write_manage' | 'delegate' | 'forum.write' | 'friends.read' | 'identify' | 'public';
type ProfilePageSection = 'me' | 'recent_activity' | 'beatmaps' | 'historical' | 'kudosu' | 'top_ranks' | 'medals';
type UserAccountHistoryType = 'note' | 'restriction' | 'silence';
type KudosuAction = 'give' | 'vote.give' | 'reset' | 'vote.reset' | 'revoke' | 'vote.revoke';
type Rank = 'SS' | 'SSH' | 'S' | 'SH' | 'A' | 'B' | 'C' | 'D' | 'F';
type UserEventType = 'achievement' | 'beatmapPlaycount' | 'beatmapsetApprove' | 'beatmapsetDelete' | 'beatmapsetRevive' | 'beatmapsetUpdate' | 'beatmapsetUpload' | 'rank' | 'rankLost' | 'userSupportAgain' | 'userSupportFirst' | 'userSupportGift' | 'usernameChange';
type AchievementGrouping = 'Skill' | 'Hush-Hush' | 'Dedication' | 'Mod Introduction';
type EventBeatmapsetApprovedType = 'ranked' | 'approved' | 'qualified' | 'loved';
type SpotlightType = 'monthly' | 'spotlight' | 'theme' | 'special' | 'bestof';
type ChannelType = 'PUBLIC' | 'PRIVATE' | 'MULTIPLAYER' | 'SPECTATOR' | 'TEMPORARY' | 'PM' | 'GROUP' | 'ANNOUNCE';
type ChatMessageType = 'action' | 'markdown' | 'plain';
type ForumTopicType = 'normal' | 'sticky' | 'announcement';
interface Token {
    token_type: string;
    expires_in: number;
    access_token: string;
    refresh_token: string;
}
type GuestToken = Omit<Token, 'refresh_token'>;
interface UserCompact {
    avatar_url: string;
    country_code: string;
    default_group: string;
    id: number;
    is_active: boolean;
    is_bot: boolean;
    is_deleted: boolean;
    is_online: boolean;
    is_supporter: boolean;
    last_visit: string;
    pm_friends_only: boolean;
    profile_colour: string | null;
    username: string;
}
interface Country {
    code: string;
    name: string;
}
interface Cover {
    custom_url: string | null;
    url: string;
    id: string | null;
}
interface UserKudosu {
    available: number;
    total: number;
}
interface User extends UserCompact {
    country: Country;
    cover: Cover;
    discord: string | null;
    has_supported: boolean;
    interests: string | null;
    join_date: ISOTimestamp;
    kudosu: UserKudosu;
    location: string | null;
    max_blocks: number;
    max_friends: number;
    occupation: string | null;
    playmode: GameMode;
    playstyle: Playstyle[];
    post_count: number;
    profile_order: ProfilePageSection[];
    title: string | null;
    title_url: string | null;
    twitter: string | null;
    website: string | null;
}
interface UserAccountHistory {
    description: string | null;
    id: number;
    length: number;
    permanent: boolean;
    timestamp: string;
    type: UserAccountHistoryType;
}
interface UserActiveTournamentBanner {
    id: number;
    tournament_id: number;
    image: string | null;
    'image@2x': string | null;
}
interface UserBadge {
    awarded_at: ISOTimestamp;
    description: string;
    image_url: string;
    'image@2x_url': string;
    url: string;
}
interface Page {
    html: string;
    raw: string;
}
interface Group {
    colour: string | null;
    has_listing: boolean;
    has_playmodes: boolean;
    id: number;
    identifier: string;
    is_probationary: boolean;
    name: string;
    short_name: string;
}
interface UserGroup extends Group {
    playmodes: GameMode[] | null;
}
interface MonthlyPlaycount {
    start_date: ISOTimestamp;
    count: number;
}
interface RankHighest {
    rank: number;
    updated_at: ISOTimestamp;
}
interface RankHistory {
    mode: GameMode;
    data: number[];
}
interface GradeCounts {
    a: number;
    s: number;
    sh: number;
    ss: number;
    ssh: number;
}
interface UserLevel {
    current: number;
    progress: number;
}
interface UserStatisticsVariant {
    mode: GameMode;
    variant: string;
    country_rank: number;
    global_rank: number;
    pp: number;
}
interface UserStatistics {
    count_100: number;
    count_300: number;
    count_50: number;
    count_miss: number;
    grade_counts: GradeCounts;
    hit_accuracy: number;
    is_ranked: boolean;
    level: UserLevel;
    maximum_combo: number;
    play_count: number;
    play_time: number;
    pp: number;
    pp_exp: number;
    global_rank: number | null;
    global_rank_exp: number | null;
    ranked_score: number;
    replays_watched_by_others: number;
    total_hits: number;
    total_score: number;
    country_rank: number | null;
    variants?: UserStatisticsVariant[];
}
interface UserAchievement {
    achieved_at: ISOTimestamp;
    achievement_id: number;
}
interface UserExtended extends User {
    account_history: UserAccountHistory[];
    active_tournament_banners: UserActiveTournamentBanner[];
    active_tournament_banner: UserActiveTournamentBanner | null;
    badges: UserBadge[];
    beatmap_playcounts_count: number;
    favourite_beatmapset_count: number;
    follower_count: number;
    graveyard_beatmapset_count: number;
    groups: UserGroup[];
    loved_beatmapset_count: number;
    mapping_follower_count: number;
    monthly_playcounts: MonthlyPlaycount[];
    page: Page;
    pending_beatmapset_count: number;
    previous_usernames: string[];
    rank_highest: RankHighest | null;
    rank_history: RankHistory;
    ranked_beatmapset_count: number;
    replays_watched_counts: MonthlyPlaycount[];
    scores_best_count: number;
    scores_first_count: number;
    scores_recent_count: number;
    statistics: UserStatistics;
    support_level: number;
    user_achievements: UserAchievement[];
}
interface Giver {
    url: string;
    username: string;
}
interface Post {
    url: string | null;
    title: string;
}
interface UserKudosuHistory {
    id: number;
    action: KudosuAction;
    amount: number;
    model: string;
    created_at: ISOTimestamp;
    giver: Giver | null;
    post: Post;
}
type StatisticsRulesets = Record<GameMode, UserStatistics | undefined>;
interface BeatmapCompact {
    beatmapset_id: number;
    difficulty_rating: number;
    id: number;
    mode: GameMode;
    status: RankStatus;
    total_length: number;
    user_id: number;
    version: string;
}
interface ScoreStatistics {
    count_50: number;
    count_100: number;
    count_300: number;
    count_geki: number | null;
    count_katu: number | null;
    count_miss: number;
}
interface Score {
    id: number;
    best_id: number;
    user_id: number;
    accuracy: number;
    mods: Mod[];
    score: number;
    max_combo: number;
    perfect: boolean;
    statistics: ScoreStatistics;
    passed: boolean;
    pp: number;
    rank: Rank;
    created_at: ISOTimestamp;
    mode: GameMode;
    mode_int: number;
    replay: boolean;
}
interface ScoreV2 {
    accuracy: number;
    beatmap_id: number;
    best_id: number | null;
    build_id: number | null;
    classic_total_score: number | null;
    ended_at: ISOTimestamp;
    has_replay: boolean;
    id: number;
    is_perfect_combo: boolean;
    legacy_perfect: boolean;
    legacy_score_id: number | null;
    legacy_total_score: number;
    max_combo: number;
    maximum_statistics: ScoreStatistics;
    mods: ModSettings[];
    passed: boolean;
    playlist_item_id: number | null;
    pp: number | null;
    preserve: boolean | null;
    processed: boolean | null;
    rank: Rank;
    room_id: number | null;
    ruleset_id: number;
    started_at: ISOTimestamp | null;
    statistics: ScoreStatistics;
    total_score: number;
    type: string;
    user_id: number;
}
interface Covers {
    cover: string;
    'cover@2x': string;
    card: string;
    'card@2x': string;
    list: string;
    'list@2x': string;
    slimcover: string;
    'slimcover@2x': string;
}
interface BeatmapsetCompact {
    artist: string;
    artist_unicode: string;
    covers: Covers;
    creator: string;
    favourite_count: number;
    id: number;
    nsfw: boolean;
    play_count: number;
    preview_url: string;
    source: string;
    status: RankStatus;
    title: string;
    title_unicode: string;
    user_id: string;
    video: boolean;
}
interface UserScore extends Score {
    beatmap: BeatmapCompact & {
        checksum: string | null;
    };
    beatmapset: BeatmapsetCompact;
    user: UserCompact;
}
interface UserScoreV2 extends Pick<UserScore, 'beatmap' | 'beatmapset' | 'user'>, ScoreV2 {
}
interface Weight {
    percentage: number;
    pp: number;
}
interface UserBestScore extends UserScore, Score {
    weight: Weight;
}
interface UserBestScoreV2 extends UserScoreV2, ScoreV2 {
    weight: Weight;
}
interface BeatmapsetAvailability {
    download_disabled: boolean;
    more_information: string | null;
}
interface BeatmapsetHype {
    current: number;
    required: number;
}
interface Beatmapset extends BeatmapsetCompact {
    availability: BeatmapsetAvailability;
    bpm: number;
    can_be_hyped: boolean;
    creator: string;
    discussion_locked: boolean;
    hype: BeatmapsetHype | null;
    is_scoreable: boolean;
    last_updated: ISOTimestamp;
    legacy_thread_url: string | null;
    nominations_summary: BeatmapsetHype;
    ranked: number;
    ranked_date: ISOTimestamp | null;
    source: string;
    storyboard: boolean;
    submitted_date: ISOTimestamp | null;
    tags: string;
}
interface Beatmap extends BeatmapCompact {
    accuracy: number;
    ar: number;
    beatmapset_id: number;
    bpm: number | null;
    convert: boolean;
    count_circles: number;
    count_sliders: number;
    count_spinners: number;
    cs: number;
    deleted_at: ISOTimestamp | null;
    drain: number;
    hit_length: number;
    is_scoreable: boolean;
    last_updated: ISOTimestamp;
    mode_int: number;
    passcount: number;
    playcount: number;
    ranked: number;
    url: string;
}
interface BeatmapPlaycount {
    beatmap_id: number;
    beatmap: BeatmapCompact | null;
    beatmapset: BeatmapsetCompact | null;
    count: number;
}
interface EventAchievement {
    icon_url: string;
    id: number;
    name: string;
    grouping: AchievementGrouping;
    ordering: number;
    slug: string;
    description: string;
    mode: GameMode | null;
    instructions: string;
}
interface EventUser {
    username: string;
    url: string;
}
interface EventBeatmap {
    title: string;
    url: string;
}
interface BaseUserEvent {
    created_at: ISOTimestamp;
    id: number;
    type: UserEventType;
}
interface UserEventAchievement extends BaseUserEvent {
    type: 'achievement';
    achievement: EventAchievement;
    user: EventUser;
}
interface UserEventBeatmapPlaycount extends BaseUserEvent {
    type: 'beatmapPlaycount';
    beatmap: EventBeatmap;
    count: number;
}
interface UserEventBeatmapsetApprove extends BaseUserEvent {
    type: 'beatmapsetApprove';
    approval: EventBeatmapsetApprovedType;
    beatmapset: EventBeatmap;
}
interface UserEventBeatmapsetDelete extends BaseUserEvent {
    type: 'beatmapsetDelete';
    beatmapset: EventBeatmap;
}
interface UserEventBeatmapsetUpdate extends BaseUserEvent {
    type: 'beatmapsetRevive' | 'beatmapsetUpdate' | 'beatmapsetUpload';
    beatmapset: EventBeatmap;
    user: EventUser;
}
interface UserEventRank extends BaseUserEvent {
    mode: GameMode;
    beatmap: EventBeatmap;
    user: EventUser;
}
interface UserEventRankAchieved extends BaseUserEvent, UserEventRank {
    type: 'rank';
    scoreRank: Rank;
}
interface UserEventRankLost extends BaseUserEvent, UserEventRank {
    type: 'rankLost';
}
interface UserEventUserUpdate extends BaseUserEvent {
    type: 'userSupportAgain' | 'userSupportFirst' | 'userSupportGift';
    user: EventUser;
}
interface UserEventUsernameUpdate extends BaseUserEvent {
    type: 'usernameChange';
    user: EventUser & {
        previousUsername: string | null;
    };
}
type UserEvent = UserEventAchievement | UserEventBeatmapPlaycount | UserEventBeatmapsetApprove | UserEventBeatmapsetDelete | UserEventBeatmapsetUpdate | UserEventRankAchieved | UserEventRankLost | UserEventUserUpdate | UserEventUsernameUpdate;
interface WikiPage {
    available_locales: string[];
    layout: string;
    locale: string;
    markdown: string;
    path: string;
    subtitle: string | null;
    tags: string[];
    title: string;
}
type SearchResult<T> = {
    data: T[];
    total: number;
};
interface SearchResults {
    user: SearchResult<UserCompact> | null;
    wiki_page: SearchResult<WikiPage> | null;
}
interface CommentableMetadata {
    id: number;
    title: string;
    type: string;
    url: string;
}
interface Comment {
    commentable_id: number;
    commentable_type: CommentableType;
    created_at: ISOTimestamp;
    deleted_at: ISOTimestamp | null;
    edited_at: ISOTimestamp | null;
    edited_by_id: number | null;
    id: number;
    legacy_name: string | null;
    message: string | null;
    message_html: string | null;
    parent_id: number | null;
    pinned: boolean;
    replies_count: number;
    updated_at: ISOTimestamp;
    user_id: number;
    votes_count: number;
}
interface CommentBundle {
    commentable_meta: CommentableMetadata[];
    comments: Comment[];
    has_more: boolean;
    has_more_id: number | null;
    included_comments: Comment[];
    pinned_commnets: Comment[] | null;
    sort: CommentSort;
    top_level_count: number | null;
    total: number | null;
    user_follow: boolean;
    user_votes: number[];
    users: UserCompact[];
}
interface MultiplayerScoresParams {
    limit: number;
    sort: MultiplayerScoresSort;
}
interface MultiplayerScoreMod {
    acronym: Mod;
}
interface MultiplayerScoreStatistics {
    Ok: number;
    Meh: number;
    Good: number;
    Miss: number;
    None: number;
    Great: number;
    Perfect: number;
    IgnoreHit: number;
    IgnoreMiss: number;
    LargeBonus: number;
    SmallBonus: number;
    LargeTickHit: number;
    SmallTickHit: number;
    LargeTickMiss: number;
    SmallTickMiss: number;
}
interface MultiplayerScore {
    id: number;
    user_id: number;
    room_id: number;
    playlist_item_id: number;
    beatmap_id: number;
    rank: Rank;
    total_score: number;
    accuracy: number;
    max_combo: number;
    mods: MultiplayerScoreMod[];
    statistics: MultiplayerScoreStatistics;
    passed: boolean;
    position: number | null;
    user: UserCompact & {
        country: Country;
        cover: Cover;
    };
}
interface MultiplayerScores {
    cursor_string: Cursor;
    params: MultiplayerScoresParams;
    scores: MultiplayerScore[];
    total: number | null;
    user_score: MultiplayerScore | null;
}
interface Spotlight {
    end_date: ISOTimestamp;
    id: number;
    mode_specific: boolean;
    participant_count: number | null;
    name: string;
    start_date: ISOTimestamp;
    type: SpotlightType;
}
interface Rankings {
    beatmapsets: Beatmapset[] | null;
    ranking: (UserStatistics & {
        user: UserCompact & {
            country: Country;
            cover: Cover;
        };
    })[];
    spotlight: Spotlight | null;
    total: number;
}
interface NewsPost {
    author: string;
    edit_url: string;
    first_image: string | null;
    id: number;
    published_at: ISOTimestamp;
    slug: string;
    title: string;
    updated_at: ISOTimestamp;
}
interface NewsSidebar {
    current_year: number;
    news_posts: NewsPost;
    years: number[];
}
interface NewsSearch {
    limit: number;
    sort: 'published_desc';
}
interface NewsListing {
    cursor_string: Cursor;
    news_posts: NewsPost & {
        preview: string;
    };
    news_sidebar: NewsSidebar;
    search: NewsSearch;
}
interface NewsNavigation {
    newer: NewsPost | null;
    older: NewsPost | null;
}
interface Fails {
    exit: number[] | null;
    fail: number[] | null;
}
interface BeatmapUserScore {
    position: number;
    score: Score & {
        beatmap: Beatmap & {
            checksum: string | null;
        };
        user: UserCompact & {
            country: Country;
            cover: Cover;
        };
    };
}
interface BeatmapUserScoreV2 {
    position: number;
    score: ScoreV2 & {
        beatmap: Beatmap & {
            checksum: string | null;
        };
        user: UserCompact & {
            country: Country;
            cover: Cover;
        };
    };
}
interface BeatmapDifficultyAttributes {
    max_combo: number;
    star_rating: number;
    gamemode: GameMode;
}
interface OsuBeatmapDifficultyAttributes extends BeatmapDifficultyAttributes {
    gamemode: 'osu';
    aim_difficulty: number;
    approach_rate: number;
    flashlight_difficulty: number;
    overall_difficulty: number;
    slider_factor: number;
    speed_difficulty: number;
}
interface TaikoBeatmapDifficultyAttributes extends BeatmapDifficultyAttributes {
    gamemode: 'taiko';
    stamina_difficulty: number;
    rhythm_difficulty: number;
    colour_difficulty: number;
    approach_rate: number;
    great_hit_window: number;
}
interface FruitsBeatmapDifficultyAttributes extends BeatmapDifficultyAttributes {
    gamemode: 'fruits';
    approach_rate: number;
}
interface ManiaBeatmapDifficultyAttributes extends BeatmapDifficultyAttributes {
    gamemode: 'mania';
    great_hit_window: number;
    score_multiplier: number;
}
interface UpdateStream {
    display_name: string | null;
    id: number;
    is_featured: boolean;
    name: string;
}
interface Build {
    created_at: ISOTimestamp;
    display_version: string;
    id: number;
    update_stream: UpdateStream | null;
    users: number;
    version: string | null;
}
interface BuildVersions {
    next: Build | null;
    previous: Build | null;
}
interface ChangelogEntry {
    category: string;
    created_at: ISOTimestamp | null;
    github_pull_request_id: number | null;
    github_url: string | null;
    id: number | null;
    major: boolean;
    repository: string | null;
    title: string | null;
    type: string;
    url: string | null;
}
interface GithubUser {
    display_name: string;
    github_url: string | null;
    id: number | null;
    osu_username: string | null;
    user_id: number | null;
    user_url: string | null;
}
interface Channel {
    channel_id: number;
    name: string;
    description: string | null;
    icon: string | null;
    type: ChannelType;
    moderated: boolean;
    uuid: string | null;
}
interface ChatMessage {
    channel_id: number;
    content: string;
    is_action: boolean;
    message_id: number;
    sender_id: number;
    timestamp: ISOTimestamp;
    type: ChatMessageType;
    uuid: string | null;
}
interface ForumPost {
    created_at: ISOTimestamp;
    deleted_at: ISOTimestamp | null;
    edited_at: ISOTimestamp | null;
    edited_by_id: number | null;
    forum_id: number;
    id: number;
    topic_id: number;
    user_id: number;
}
interface ForumPostBody {
    html: string;
    raw: string;
}
interface ForumTopic {
    created_at: ISOTimestamp;
    deleted_at: ISOTimestamp | null;
    first_post_id: number;
    forum_id: number;
    id: number;
    is_locked: boolean;
    last_post_id: number;
    poll: ForumPoll | null;
    post_count: number;
    title: string;
    type: ForumTopicType;
    updated_at: ISOTimestamp;
    user_id: number;
}
interface ForumPoll {
    allow_vote_change: boolean;
    ended_at: ISOTimestamp | null;
    hide_incomplete_results: boolean;
    last_vote_at: ISOTimestamp | null;
    max_votes: number;
    options: ForumPollOptions[];
    started_at: ISOTimestamp;
    title: {
        bbcode: string;
        html: string;
    };
    total_vote_count: number;
}
interface ForumPollOptions {
    id: number;
    text: {
        bbcode: string;
        html: string;
    };
    vote_count: number | null;
}
interface BeatmapsetDiscussion {
    beatmap_id: number | null;
    beatmapset_id: number | null;
    can_be_resolved: boolean;
    can_grant_kudosu: boolean;
    created_at: ISOTimestamp;
    deleted_at: ISOTimestamp | null;
    deleted_by_id: number | null;
    id: number;
    kudosu_denied: boolean;
    last_post_at: ISOTimestamp;
    message_type: DiscussionMessageType;
    parent_id: number | null;
    resolved: boolean;
    timestamp: number | null;
    updated_at: ISOTimestamp;
    user_id: number;
}
interface DiscussionPost {
    beatmapset_discussion_id: number;
    created_at: ISOTimestamp;
    deleted_at: ISOTimestamp | null;
    deleted_by_id: number | null;
    id: number;
    last_editor_id: number | null;
    message: string;
    system: boolean;
    updated_at: ISOTimestamp;
    user_id: number;
}
interface DiscussionVote {
    beatmapset_discussion_id: number;
    created_at: ISOTimestamp;
    id: number;
    score: number;
    updated_at: ISOTimestamp;
    user_id: number;
}

/**
 * Class that handles auth code grant flow related actions
 *
 * Documentation: {@link https://osujs.mario564.com/oauth/authorization-code-grant}
 */
declare class AuthCodeGrant extends Base$1 {
    private scopes;
    /**
     * @param clientId OAuth client ID
     * @param clientSecret OAuth client secret
     * @param redirectUri OAuth redirect URI
     * @param scopes An array of OAuth scopes
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(clientId: number, clientSecret: string, redirectUri: string, scopes: Scope[], options?: {
        polyfillFetch?: typeof polyfillFetch;
    });
    /**
     * Gets a token
     *
     * Documentation: {@link https://osujs.mario564.com/oauth/authorization-code-grant}
     * @param code The string received after a user authorizes the app
     * @returns An API token
     */
    requestToken(code: string): Promise<Token>;
    /**
     * Refreshes a token
     *
     * Documentation: {@link https://osujs.mario564.com/oauth/authorization-code-grant}
     * @param refreshToken The token used to refresh
     * @returns An API token
     */
    refreshToken(refreshToken: string): Promise<Token>;
}

/**
 * Class that wraps all OAuth related endpoints
 *
 * Documentation: {@link https://osujs.mario564.com/oauth}
 */
declare class Auth extends Base$1 {
    /**
     * @param clientId OAuth client ID
     * @param clientSecret OAuth client secret
     * @param redirectUri OAuth redirect URI
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(clientId: number, clientSecret: string, redirectUri: string, options?: {
        polyfillFetch?: typeof polyfillFetch;
    });
    /**
     * @param scopes An array of scopes
     *
     * Documentation: {@link https://osujs.mario564.com/oauth/authorization-code-grant}
     */
    authorizationCodeGrant(scopes?: Scope[]): AuthCodeGrant;
    /**
     * Gets a token
     *
     * Documentation: {@link https://osujs.mario564.com/oauth/client-credentials-grant}
     * @param scopes An array of scopes
     * @returns An API token
     */
    clientCredentialsGrant(scopes?: Scope[]): Promise<GuestToken>;
    /**
     * Revokes a token
     *
     * Documentation: {@link https://osujs.mario564.com/oauth/revoke-token}
     * @param accessToken Access token to revoke
     */
    revokeToken(accessToken: string): Promise<void>;
}

interface Options {
    query?: Record<string, any>;
    body?: Record<string, any> | string;
}
interface LookupBeatmapOptions {
    query?: {
        /** A beatmap checksum */
        checksum?: string;
        /** A beatmap file name */
        filename?: string;
        /** ID of a beatmap */
        id?: number;
    };
}
interface GetBeatmapScoresOptions {
    query?: {
        /** Gamemode of the scores to return */
        mode?: GameMode;
    };
}
interface GetBeatmapTopNonLegacyScoresOptions {
    query?: {
        /** Set to true to only return legacy scores */
        legacy_only?: boolean;
        /** Gamemode of the scores to return */
        mode?: GameMode;
    };
}
interface GetBeatmapsOptions {
    query?: {
        /** An array of beatmap IDs (can only take up to 50 IDs) */
        ids?: number[];
    };
}
interface GetBeatmapAttributesOptions {
    body?: {
        /** Mods to apply (can be either the bitwise representation or an array of acronyms) */
        mods?: number | Mod[];
        /** Ruleset of the difficulty attributes. Only valid if it's the beatmap ruleset or the beatmap can be converted to the specified ruleset. Defaults to ruleset of the specified beatmap */
        ruleset?: GameMode;
        /** The same as `ruleset` but in integer form */
        ruleset_id?: number;
    };
}
interface GetDiscussionBaseQuery {
    /** Max. number of results */
    limit?: number;
    /** Search result page number */
    page?: number;
    /** Sort posts by newest (`id_desc`) or oldest (`id_desc`) */
    sort?: 'id_desc' | 'id_asc';
}
interface GetDiscussionPostsOptions {
    query?: GetDiscussionBaseQuery & {
        /** ID of the beatmapset discussion */
        beatmapset_discussion_id?: number;
        /** Post types */
        types?: ('first' | 'reply' | 'system')[];
        /** ID of the user to get posts from */
        user?: number;
    };
}
interface GetDiscussionVotesOptions {
    query?: GetDiscussionBaseQuery & {
        /** ID of the beatmapset discussion */
        beatmapset_discussion_id?: number;
        /** ID of the user receiving the votes */
        receiver?: number;
        /** `1` for up vote, `-1` for down vote */
        score?: 1 | -1;
        /** ID of the user giving votes */
        user?: number;
    };
}
interface GetDiscussionsOptions {
    query?: GetDiscussionBaseQuery & {
        /** ID of the beatmap to get discussions from */
        beatmap_id?: number;
        /** ID of the beatmapset to get discussions from */
        beatmapset_id?: number;
        /** Specify beatmapset status */
        beatmapset_status?: 'all' | 'ranked' | 'qualified' | 'disqualified' | 'never_qualified';
        /** Specify message types, (unset for all) */
        message_types?: DiscussionMessageType[];
        /** Show only resolved issues? */
        only_unresolved?: boolean;
        /** ID of the user (documentation doesn't specify about what) */
        user?: number;
    };
}
interface GetChangelogListingOptions {
    query?: {
        /** Minimum build version */
        from?: string;
        /** Maximum build ID */
        max_id?: number;
        /** Stream name to return builds from */
        stream?: ChangelogStream;
        /** Maximum build version */
        to?: string;
        /** Changelog entry format (returns both by default) */
        message_formats?: ('html' | 'markdown')[];
    };
}
interface LookupChangelogBuildOptions {
    query?: {
        /** Unset to query by build version or stream name, or id to query by build ID */
        key?: 'id';
        /** Changelog entry format (returns both by default) */
        message_formats?: ('html' | 'markdown')[];
    };
}
interface CreatePMOptions {
    body: {
        /** ID of the user to send a PM */
        target_id: number;
        /** Message to send */
        message: string;
        /** Is the message an action? */
        is_action: boolean;
        /** Client side message identifier which will be sent back in response and websocket JSON */
        uuid?: string;
    };
}
interface CreatePMChannelOptions {
    body: {
        /** Message to send */
        message?: string;
        /** Channel details */
        channel?: {
            /** Channel name */
            name?: string;
            /** Channel description */
            description?: string;
        };
        /** Target user ID */
        target_id: number;
    };
}
interface CreateAnnounceChannelOptions {
    body: {
        /** Message to send with the announcement */
        message: string;
        /** Channel details */
        channel: {
            /** Channel name */
            name: string;
            /** Channel description */
            description: string;
        };
        /** Target user IDs */
        target_ids: number[];
    };
}
interface GetCommentsOptions {
    query?: {
        /** Resource to get comments for */
        commentable?: {
            /** Type of the resource */
            type?: CommentableType;
            /** ID of the resource */
            id?: number;
        };
        /** Get replies of a specific comment ID */
        parent_id?: number;
        /** Sort option */
        sort?: CommentSort;
    };
}
interface ReplyToTopicOptions {
    body: {
        /** Content of the reply */
        body: string;
    };
}
interface CreateTopicOptions {
    body: {
        /** Content of the topic */
        body: string;
        /** ID of the forum to create the topic in */
        forum_id: number;
        /** Title of the topic */
        title: string;
        /** Create a poll with the topic? */
        with_poll?: boolean;
        /** Poll details */
        forum_topic_poll?: {
            /** Hide result (until voting period ends)? (Default: false) */
            hide_results?: boolean;
            /** Length of the voting period in days. 0 means that the voting will never end (default: 0). This parameter is required if `hide_results` option is enabled */
            length_days?: number;
            /** Max. number of votes each user can cast (default: 1) */
            max_options?: number;
            /** Newline-separated list of voting options. BBCode is supported */
            options: string;
            /** Title of the poll */
            title: string;
            /** Can a user change their votes? (Default: false) */
            vote_change?: boolean;
        };
    };
}
interface GetTopicOptions {
    query?: {
        /** Pagination cursor */
        cursor_string?: string;
        /** Sort posts by */
        sort?: 'id_asc' | 'id_desc';
        /** Max. number of posts to be returned (caps at 50) */
        limit?: number;
        /** First post ID to be returned with `sort` set to `id_asc`. This parameter is ignored if `cursor_string` is specified */
        start?: number;
        /** First post ID to be returned with `sort` set to `id_desc`. This parameter is ignored if `cursor_string` is specified */
        end?: number;
    };
}
interface UpdateTopicOptions {
    body?: {
        /** Forum topic details */
        forum_topic?: {
            /** Title of the topic */
            topic_title?: string;
        };
    };
}
interface UpdatePostOptions {
    body: {
        /** Content of the post in BBCode format */
        body: string;
    };
}
interface SearchOptions {
    query?: {
        /** Search only users, only wiki pages or both */
        mode?: 'all' | 'user' | 'wiki_page';
        /** Query string to search */
        query?: string;
        /** Page number */
        page?: number;
    };
}
interface GetPlaylistScoresOptions {
    query?: {
        /** Limit number of results */
        limit?: number;
        /** Sort option */
        sort?: MultiplayerScoresSort;
        /** Pagination cursor */
        cursor_string?: string;
    };
}
interface GetNewsListingOptions {
    query?: {
        /** Limit number of results */
        limit?: number;
        /** Filter news posts by a specific year */
        year?: number;
        /** Pagination cursor */
        cursor_string?: string;
    };
}
interface GetNewsPostOptions {
    query?: {
        /** Specify whether the query must be done with a news post ID (`id`) or a slug (unset value) */
        key?: 'id';
    };
}
interface GetRankingOptions {
    query?: {
        /** Filter by country code (only available for type `performance`) */
        country?: string;
        /** Show all users or friend ranking */
        filter?: 'all' | 'friends';
        /** ID of the spotlight (if type is `charts`) */
        spotlight?: number;
        /** Filter ranking by specified mode variant (only available for type `performance`) */
        variant?: string;
    };
}
interface GetSelfOptions {
    urlParams?: {
        /** Gamemode of the profile to return */
        mode: GameMode;
    };
}
interface GetUserKodosuOptions {
    query?: {
        /** Limit number of results */
        limit?: number;
        /** Pagination offset */
        offset?: number;
    };
}
interface GetUserScoresOptions {
    query?: {
        /** Limit number of results */
        limit?: number;
        /** Pagination offset */
        offset?: number;
        /** Gamemode of the scores to return */
        mode?: GameMode;
    };
}
interface GetUserRecentScoresOptions {
    query?: {
        /** Limit number of results */
        limit?: number;
        /** Pagination offset */
        offset?: number;
        /** Gamemode of the scores to return */
        mode?: GameMode;
        /** Include failed scores? */
        include_fails?: boolean | number;
    };
}
interface GetUserBeatmapsOptions {
    query?: {
        /** Limit number of results */
        limit?: number;
        /** Pagination offset */
        offset?: number;
    };
}
interface GetUserRecentActivityOptions {
    query?: {
        /** Limit number of results */
        limit?: number;
        /** Pagination offset */
        offset?: number;
    };
}
interface GetUserOptions {
    urlParams?: {
        /** Gamemode of the profile to return */
        mode?: GameMode;
    };
    query?: {
        /** Specify if the `user` param is an `id` or a `username` */
        key: 'id' | 'username';
    };
}
interface GetUsersOptions {
    query?: {
        /** An array of user IDs (can only take up to 50 IDs) */
        ids?: number[];
        /** Include `statistics_rulesets.variants`? */
        include_variant_statistics?: boolean;
    };
}

declare class Base<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> {
    protected accessToken: string;
    private fetch;
    private usingPolyfillFetch;
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    protected request<T>(endpoint: string, method: 'POST' | 'GET' | 'PATCH' | 'DELETE', options?: Options & {
        returnNullOn404?: boolean;
        dontParseResp?: boolean;
        apiVersion?: string;
    }): Promise<T>;
    /**
     * Prevents a request done to the current API to throw an `OsuJSUnexpectedResponseError` error.
     *
     * Documentation: {@link https://osujs.mario564.com/current/safe-parse}
     */
    safeParse<T extends Promise<any>>(request: T): Promise<SafeParse<Awaited<T>, TPolyfillFetch extends typeof polyfillFetch ? true : false>>;
    /**
     * Set a new access token to be used by the current client.
     *
     * Documentation: {@link https://osujs.mario564.com/current/set-access-token}
     */
    setAccessToken(accessToken: string): void;
}

/**
 * Class that wraps all user related endpoints
 */
declare class Users<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Makes a GET request to the `me` endpoint (requires the `identify` scope)
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-self}
     * @returns The user corresponding to the access token provided in the constructor of this class
     */
    getSelf(options?: GetSelfOptions): Promise<UserExtended & {
        is_restricted: boolean;
        session_verified: boolean;
        statistics_rulesets: StatisticsRulesets;
    }>;
    /**
     * Makes a GET request to the `/users/{user}/kudosu` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-user-kudosu}
     * @param user ID of the user to get kudosu from
     * @param options
     * @returns An array containing the specified user's kudosu history
     */
    getUserKudosu(user: number, options?: GetUserKodosuOptions): Promise<UserKudosuHistory[]>;
    /**
     * Makes a GET request to the `/users/{user}/recent_activity` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-user-recent-activity}
     * @param user ID of the user to get their recent activity from
     * @param options
     * @returns An array containing the specified user's recent activity (each event is a union, to discriminate, use the `type` key)
     */
    getUserRecentActivity(user: number, options?: GetUserRecentActivityOptions): Promise<UserEvent[]>;
    private getUserScoresBase;
    /**
     * Makes a GET request to the `/users/{user}/scores/{type}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-user-scores}
     * @param user ID of the user to get their scores
     * @param type Score type
     * @param options
     * @returns An array of the specified user's scores
     */
    getUserScores: <T extends UserScoreType>(user: number, type: T, options?: (T extends "recent" ? GetUserRecentScoresOptions : GetUserScoresOptions) | undefined) => Promise<T extends "best" ? UserBestScore[] : UserScore[]>;
    /**
     * Makes a GET request to the `/users/{user}/scores/{type}` endpoint with the `x-api-version` header set to `20220705`
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-user-scores}
     * @param user ID of the user to get their scores
     * @param type Score type
     * @param options
     * @returns An array of the specified user's scores
     */
    getUserScoresV2: <T extends UserScoreType>(user: number, type: T, options?: (T extends "recent" ? GetUserRecentScoresOptions : GetUserScoresOptions) | undefined) => Promise<T extends "best" ? UserBestScoreV2[] : UserScoreV2[]>;
    /**
     * Makes a GET request to the `/users/{user}/beatmapsets/{type}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-user-beatmaps}
     * @param user ID of the user to get their beatmapsets
     * @param type Type of beatmapsets to return
     * @param options
     * @returns An array of a user's beatmapsets
     */
    getUserBeatmaps<T extends UserBeatmapsType>(user: number, type: T, options?: GetUserBeatmapsOptions): Promise<T extends 'most_played' ? BeatmapPlaycount[] : (Beatmapset & {
        beatmaps: (Beatmap & {
            checksum: string | null;
        })[];
    })[]>;
    /**
     * Makes a GET request to the `/users/{user}/{mode?}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-user}
     * @param user ID or username of the user to get
     * @param options
     * @returns A user
     */
    getUser(user: number | string, options?: GetUserOptions): Promise<UserExtended>;
    /**
     * Makes a GET request to the `/users` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-users}
     * @returns An array of users
     */
    getUsers(options?: GetUsersOptions): Promise<(UserCompact & {
        country: Country;
        cover: Cover;
        groups: UserGroup[];
        statistics_rulesets: StatisticsRulesets;
    })[]>;
}

/**
 * Class that wraps all wiki related endpoints
 */
declare class Wiki<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Makes a GET request to the `/wiki/{locale}/{path}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-wiki-page}
     * @param locale Two-letter language code of the wiki page
     * @param path Path to the wiki page
     * @returns The wiki page
     */
    getWikiPage(locale: string, path: string): Promise<WikiPage>;
}

/**
 * Class that wraps all comment related endpoints
 */
declare class Comments<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Makes a GET request to the `/comments` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-comments}
     * @returns An object containing comments, users and other related data
     */
    getComments(options?: GetCommentsOptions): Promise<CommentBundle>;
    /**
     * Makes a GET request to the `/comments/{comment}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-comment}
     * @param comment ID of the comment to get related data from
     * @returns An object containing comments, users and other related data to the comment with the specified ID
     */
    getComment(comment: number): Promise<CommentBundle>;
}

/**
 * Class that wraps all multiplayer related endpoints
 */
declare class Multiplayer<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Makes a GET request to the `/rooms/{room}/playlist/{playlist}/scores` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-playlist-scores}
     * @param room ID of the room corresponding to the playlist
     * @param playlist ID of the playlist to get scores from
     * @returns An object containing playlist scores and metadata
     */
    getPlaylistScores(room: number, playlist: number, options?: GetPlaylistScoresOptions): Promise<MultiplayerScores>;
}

/**
 * Class that wraps all ranking related endpoints
 */
declare class Ranking<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Makes a GET request to the `/rankings/{mode}/{type}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-ranking}
     * @param mode Ranking gamemode
     * @param type Ranking type
     * @returns An object containing ranking data
     */
    getRanking(mode: GameMode, type: RankingType, options?: GetRankingOptions): Promise<Rankings>;
    /**
     * Makes a GET request to the `/spotights` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-spotlights}
     * @returns An array of spotlights
     */
    getSpotlights(): Promise<Spotlight[]>;
}

/**
 * Class that wraps all news related endpoints
 */
declare class News<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Makes a GET request to the `/news` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-news-listing}
     * @returns An object containing news posts and other additional data
     */
    getNewsListing(options?: GetNewsListingOptions): Promise<NewsListing>;
    /**
     * Makes a GET request to the `/news/{news}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-news-post}
     * @param news ID or slug of the news post to get
     * @returns A news post
     */
    getNewsPost(news: string | number, options?: GetNewsPostOptions): Promise<NewsPost & {
        content: string;
        navigation: NewsNavigation;
    }>;
}

/**
 * Class that wraps all beatmap related endpoints
 */
declare class Beatmaps<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Makes a GET request to the `/beatmaps/lookup` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/lookup-beatmap}
     * @returns A beatmap
     */
    lookupBeatmap(options?: LookupBeatmapOptions): Promise<(Beatmap & {
        beatmapset: Beatmapset & {
            ratings: number[];
        };
        checksum: string | null;
        failtimes: Fails;
        max_combo: number;
    }) | null>;
    private getBeatmapUserScoreBase;
    /**
     * Makes a GET request to the `/beatmaps/{beatmap}/scores/users/{user}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-beatmap-user-score}
     * @param beatmap ID of the beatmap to get scores from
     * @param user ID of the user to get scores from
     * @returns A user score on a beatmap
     */
    getBeatmapUserScore: (beatmap: number, user: number, options?: GetBeatmapScoresOptions) => Promise<BeatmapUserScore>;
    /**
     * Makes a GET request to the `/beatmaps/{beatmap}/scores/users/{user}` endpoint with the `x-api-version` header set to `20220705`
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-beatmap-user-score}
     * @param beatmap ID of the beatmap to get scores from
     * @param user ID of the user to get scores from
     * @returns A user score on a beatmap
     */
    getBeatmapUserScoreV2: (beatmap: number, user: number, options?: GetBeatmapScoresOptions) => Promise<BeatmapUserScoreV2>;
    private getBeatmapUserScoresBase;
    /**
     * Makes a GET request to the `/beatmaps/{beatmap}/scores/users/{user}/all` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-beatmap-user-scores}
     * @param beatmap ID of the beatmap to get scores from
     * @param user ID of the user to get scores from
     * @returns An array of user scores on a beatmap
     */
    getBeatmapUserScores: (beatmap: number, user: number, options?: GetBeatmapScoresOptions) => Promise<Score[]>;
    /**
     * Makes a GET request to the `/beatmaps/{beatmap}/scores/users/{user}/all` endpoint with the `x-api-version` header set to `20220705`
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-beatmap-user-scores}
     * @param beatmap ID of the beatmap to get scores from
     * @param user ID of the user to get scores from
     * @returns An array of user scores on a beatmap
     */
    getBeatmapUserScoresV2: (beatmap: number, user: number, options?: GetBeatmapScoresOptions) => Promise<ScoreV2[]>;
    private getBeatmapTopScoresBase;
    /**
     * Makes a GET request to the `/beatmaps/{beatmap}/scores` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-beatmap-top-scores}
     * @param beatmap ID of the beatmap to get top scores from
     * @returns An array of user scores on a beatmap
     */
    getBeatmapTopScores: (beatmap: number, options?: GetBeatmapScoresOptions) => Promise<(Score & {
        user: UserCompact & {
            country: Country;
            cover: Cover;
        };
    })[]>;
    /**
     * Makes a GET request to the `/beatmaps/{beatmap}/scores` endpoint with the `x-api-version` header set to `20220705`
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-beatmap-top-scores}
     * @param beatmap ID of the beatmap to get top scores from
     * @returns An array of user scores on a beatmap
     */
    getBeatmapTopScoresV2: (beatmap: number, options?: GetBeatmapScoresOptions) => Promise<(ScoreV2 & {
        user: UserCompact & {
            country: Country;
            cover: Cover;
        };
    })[]>;
    private getBeatmapTopNonLegacyScoresBase;
    /**
     * Makes a GET request to the `/beatmaps/{beatmap}/solo-scores` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-beatmap-top-non-legacy-scores}
     * @param beatmap ID of the beatmap to get top scores from
     * @returns An array of user scores on a beatmap
     */
    getBeatmapTopNonLegacyScores: (beatmap: number, options?: GetBeatmapTopNonLegacyScoresOptions) => Promise<(Score & {
        user: UserCompact & {
            country: Country;
            cover: Cover;
        };
    })[]>;
    /**
     * Makes a GET request to the `/beatmaps/{beatmap}/solo-scores` endpoint with the `x-api-version` header set to `20220705`
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-beatmap-top-non-legacy-scores}
     * @param beatmap ID of the beatmap to get top scores from
     * @returns An array of user scores on a beatmap
     */
    getBeatmapTopNonLegacyScoresV2: (beatmap: number, options?: GetBeatmapTopNonLegacyScoresOptions) => Promise<(ScoreV2 & {
        user: UserCompact & {
            country: Country;
            cover: Cover;
        };
    })[]>;
    /**
     * Makes a GET request to the `/beatmaps` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-beatmaps}
     * @returns An array of beatmaps
     */
    getBeatmaps(options?: GetBeatmapsOptions): Promise<(Beatmap & {
        failtimes: Fails;
        max_combo: number;
        checksum: string | null;
        beatmapset: Beatmapset & {
            ratings: number[];
        };
    })[]>;
    /**
     * Makes a GET request to the `/beatmaps/{beatmap}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-beatmap}
     * @param beatmap ID of the beatmap to get
     * @returns A beatmap
     */
    getBeatmap(beatmap: number): Promise<Beatmap & {
        beatmapset: Beatmapset & {
            ratings: number[];
        };
        checksum: string | null;
        failtimes: Fails;
        max_combo: number;
    }>;
    /**
     * Makes a POST request to the `/beatmaps/{beatmap}/attributes` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-beatmap-attributes}
     * @param beatmap ID of the beatmap to get its attributes
     * @param gamemode Gamemode attributes to get
     * @returns A beatmap's attributes
     */
    getBeatmapAttributes<T extends GameMode>(beatmap: number, gamemode: T, options?: GetBeatmapAttributesOptions): Promise<T extends 'osu' ? OsuBeatmapDifficultyAttributes : T extends 'taiko' ? TaikoBeatmapDifficultyAttributes : T extends 'fruits' ? FruitsBeatmapDifficultyAttributes : ManiaBeatmapDifficultyAttributes>;
}

/**
 * Class that wraps all changelog related endpoints
 */
declare class Changelog<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Makes a GET request to the `/changelog/{stream}/{build}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-changelog-build}
     * @param stream Update stream name
     * @param build Build version
     * @returns A changelog build
     */
    getChangelogBuild(stream: ChangelogStream, build: string): Promise<Build & {
        changelog_entries: (ChangelogEntry & {
            github_user: GithubUser;
            message: string | null;
            message_html: string | null;
        })[];
        versions: BuildVersions;
    }>;
    /**
     * Makes a GET request to the `/changelog` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-changelog-listing}
     * @returns An object containing a array of builds, update stream and search parameters used
     */
    getChangelogListing(options?: GetChangelogListingOptions): Promise<{
        builds: (Build & {
            changelog_entries: (ChangelogEntry & {
                github_user: GithubUser;
                message: string | null;
                message_html: string | null;
            })[];
        })[];
        search: {
            from: string | null;
            limit: 21;
            max_id: number | null;
            stream: string | null;
            to: string | null;
        };
        streams: (UpdateStream & {
            latest_build: Build;
            user_count: number;
        })[];
    }>;
    /**
     * Makes a GET request to the `/changelog/{changelog}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/lookup-changelog-build}
     * @param changelog Build version, update stream name, or build ID
     * @returns A changelog build
     */
    lookupChangelogBuild(changelog: string | number, options?: LookupChangelogBuildOptions): Promise<(Build & {
        changelog_entries: (ChangelogEntry & {
            github_user: GithubUser;
            message: string | null;
            message_html: string | null;
        })[];
        versions: BuildVersions;
    }) | null>;
}

/**
 * Class that wraps all chat related endpoints
 */
declare class Chat<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Makes a POST request to the `/chat/new` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/create-pm}
     * @returns An object containing the message sent and the channel it was sent to
     */
    createPM(options: CreatePMOptions): Promise<{
        channel: Channel;
        message: ChatMessage;
    }>;
    /**
     * Makes a POST request to the `/chat/channels` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/create-channel}
     * @param type Channel type to create or rejoin
     * @returns The created or rejoined channel
     */
    createChannel<T extends 'PM' | 'ANNOUNCE'>(type: T, options: T extends 'PM' ? CreatePMChannelOptions : CreateAnnounceChannelOptions): Promise<Channel>;
}

/**
 * Class that wraps all forum related endpoints
 */
declare class Forum<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Makes a POST request to the `/forums/topics/{topic}/reply` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/reply-to-topic}
     * @param topic ID of the topic to reply to
     * @returns A forum post
     */
    replyToTopic(topic: number, options: ReplyToTopicOptions): Promise<ForumPost & {
        body: ForumPostBody;
    }>;
    /**
     * Makes a POST request to the `/forums/topics` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/create-topic}
     * @returns A forum topic and the post attached to it
     */
    createTopic(options: CreateTopicOptions): Promise<{
        topic: ForumTopic;
        post: ForumPost & {
            body: ForumPostBody;
        };
    }>;
    /**
     * Makes a GET request to the `/forums/topics/{topic}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-topic}
     * @param topic ID of the topic to get its data and posts from
     * @returns An object containing the cursor string, posts and the topic itself
     */
    getTopic(topic: number, options?: GetTopicOptions): Promise<{
        cursor_string: Cursor;
        posts: (ForumPost & {
            body: ForumPostBody;
        })[];
        topic: ForumTopic;
    }>;
    /**
     * Makes a PATCH request to the `/forums/topics/{topic}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/update-topic}
     * @param topic ID of the topic to update
     * @returns A forum topic
     */
    updateTopic(topic: number, options?: UpdateTopicOptions): Promise<ForumTopic>;
    /**
     * Makes a PATCH request to the `/forums/posts/{post}` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/update-post}
     * @param post ID of the post to update
     * @returns A forum post
     */
    updatePost(post: number, options: UpdatePostOptions): Promise<ForumPost & {
        body: ForumPostBody;
    }>;
}

/**
 * Class that wraps all beatmapset discussion related endpoints
 */
declare class BeatmapsetDiscussions<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Makes a GET request to the `/beatmapsets/discussions/posts` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-discussion-posts}
     * @returns An object containing a cursor and arrays of beatmapsets, users, discussions and posts
     */
    getDiscussionPosts(options?: GetDiscussionPostsOptions): Promise<{
        beatmapsets: BeatmapsetCompact[];
        cursor_string: Cursor;
        discussions: BeatmapsetDiscussion[];
        posts: DiscussionPost[];
        users: UserCompact[];
    }>;
    /**
     * Makes a GET request to the `/beatmapsets/discussions/votes` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-discussion-votes}
     * @returns An object containing a cursor and arrays of discussions, users and votes
     */
    getDiscussionVotes(options?: GetDiscussionVotesOptions): Promise<{
        cursor_string: Cursor;
        discussions: BeatmapsetDiscussion[];
        users: UserCompact[];
        votes: DiscussionVote[];
    }>;
    /**
     * Makes a GET request to the `/beatmapsets/discussions` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-discussions}
     * @returns An object containing a cursor and arrays of beatmaps, discussions and users
     */
    getDiscussions(options?: GetDiscussionsOptions): Promise<{
        cursor_string: Cursor;
        users: UserCompact[];
        discussions: BeatmapsetDiscussion[];
        included_discussions: BeatmapsetDiscussion[];
        beatmapsets: BeatmapsetCompact[];
        beatmaps: (Beatmap & {
            checksum: string | null;
        })[];
        reviews_config: {
            max_blocks: number;
        };
    }>;
}

/**
 * Class that wraps all endpoints of the current API (API v2)
 *
 * Documentation: {@link https://osujs.mario564.com/current}
 */
declare class Client<TPolyfillFetch extends typeof polyfillFetch | undefined = undefined> extends Base<TPolyfillFetch> {
    beatmaps: Beatmaps<TPolyfillFetch>;
    beatmapsetDiscussions: BeatmapsetDiscussions<TPolyfillFetch>;
    changelog: Changelog<TPolyfillFetch>;
    chat: Chat<TPolyfillFetch>;
    comments: Comments<TPolyfillFetch>;
    forum: Forum<TPolyfillFetch>;
    multiplayer: Multiplayer<TPolyfillFetch>;
    news: News<TPolyfillFetch>;
    ranking: Ranking<TPolyfillFetch>;
    users: Users<TPolyfillFetch>;
    wiki: Wiki<TPolyfillFetch>;
    /**
     * @param accessToken OAuth access token
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(accessToken: string, options?: {
        polyfillFetch?: TPolyfillFetch;
    });
    /**
     * Set a new access token to be used by the current client.
     *
     * Documentation: {@link https://osujs.mario564.com/current/set-access-token}
     */
    setAccessToken(accessToken: string): void;
    /**
     * Makes a GET request to the `/search` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/search}
     * @returns Users and wiki pages as results
     */
    search(options?: SearchOptions): Promise<SearchResults>;
    /**
     * Makes a DELETE request to the `/oauth/tokens/current` endpoint. Revokes the access token
     *
     * Documentation: {@link https://osujs.mario564.com/current/revoke-token}
     */
    revokeToken(): Promise<void>;
    /**
     * Make a GET request to an undocumented endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/current/get-undocumented}
     * @param endpoint The endpoint to make a request to
     */
    getUndocumented<T>(endpoint: string, options?: Omit<Options, 'body'>): Promise<T>;
}

/**
 * Timestamp string in ODBC canonical format
 */
type ODBCTimestamp = string;
type Genre = keyof typeof GenresEnum;
type Language = keyof typeof LanguagesEnum;
type ScoringType = keyof typeof ScoringTypeEnum;
type TeamType = keyof typeof TeamTypeEnum;
type TeamColor = keyof typeof TeamColorEnum;
type UserType = 'id' | 'string';
interface GetBeatmapsParams {
    /** Beatmaps ranked or loved since this date (in UTC) */
    since?: Date;
    /** Beatmaps with a specific beatmapset ID */
    s?: number;
    /** Beatmap with a specific beatmap ID */
    b?: number;
    /** Beatmaps created by user with a specific user ID or username */
    u?: string | number;
    /** Specify if `u` is a user ID (`id`) or a username (`string`) */
    type?: UserType;
    /** Beatmaps from a specific gamemode */
    m?: GameMode;
    /** Include converted beatmaps? */
    a?: boolean;
    /** Beatmap with a specific hash */
    h?: string;
    /** Limit amount of beatmaps to return (500 max.) */
    limit?: number;
    /** Mods to apply */
    mods?: Mod[];
}
interface GetUserParams {
    /** User with a specific user ID or username */
    u?: string | number;
    /** User gamemode profile */
    m?: GameMode;
    /** Specify if `u` is a user ID (`id`) or a username (`string`) */
    type?: UserType;
    /** Max. number of days between now and the last event's date (range: 1-31) */
    event_days?: number;
}
interface GetUserScoresBaseParams {
    /** Scores from a specific gamemode */
    m?: GameMode;
    /** Limit amount of scores to return (100 max.) */
    limit?: number;
    /** Specify if `u` is a user ID (`id`) or a username (`string`) */
    type?: UserType;
}
interface GetBeatmapScoresParams extends GetUserScoresBaseParams {
    /** Scores from a beatmap with a specific beatmap ID */
    b: number;
    /** Scores from a user with a specific user ID or username */
    u?: string | number;
}
interface GetUserScoresParams extends GetUserScoresBaseParams {
    /** Scores from a user with a specific user ID or username */
    u: string | number;
}
interface GetMultiplayerLobbyParams {
    /** Match with a specific match ID */
    mp: number;
}
interface GetReplayBaseParams {
    /** Replay gamemode */
    m?: GameMode;
    /** Replay with a specific list of mods */
    mods?: Mod[];
}
interface GetReplayByScoreIdParams extends GetReplayBaseParams {
    /** Replay from a score with a specific score ID */
    s: number;
}
interface GetReplayByBeatmapAndUserIdParams extends GetReplayBaseParams {
    /** Replay from a beatmap with a specific beatmap ID */
    b: number;
    /** Replay from a user with a specific user ID or username */
    u: string | number;
    /** Specify if `u` is a user ID (`id`) or a username (`string`) */
    type?: UserType;
}
interface LegacyBeatmap {
    approved: RankStatus;
    submit_date: ODBCTimestamp;
    approved_date: ODBCTimestamp;
    last_update: ODBCTimestamp;
    artist: string;
    beatmap_id: number;
    beatmapset_id: number;
    bpm: number;
    creator: string;
    creator_id: number;
    difficultyrating: number;
    diff_aim: number;
    diff_speed: number;
    diff_size: number;
    diff_overall: number;
    diff_approach: number;
    diff_drain: number;
    hit_length: number;
    source: string;
    genre: Genre;
    language: Language;
    title: string;
    total_length: number;
    version: string;
    file_md5: string;
    mode: GameMode;
    tags: string[];
    favourite_count: number;
    rating: number;
    playcount: number;
    passcount: number;
    count_normal: number;
    count_slider: number;
    count_spinner: number;
    max_combo: number;
    storyboard: boolean;
    video: boolean;
    download_available: boolean;
    audio_available: boolean;
}
interface LegacyUser {
    user_id: number;
    username: string;
    join_date: ODBCTimestamp;
    count300: number;
    count100: number;
    count50: number;
    playcount: number;
    ranked_score: number;
    total_score: number;
    pp_rank: number;
    level: number;
    pp_raw: number;
    accuracy: number;
    count_rank_ss: number;
    count_rank_ssh: number;
    count_rank_s: number;
    count_rank_sh: number;
    count_rank_a: number;
    country: string;
    total_seconds_played: number;
    pp_country_rank: number;
    events: LegacyEvent[];
}
interface LegacyEvent {
    display_html: string;
    beatmap_id: number;
    beatmapset_id: number;
    date: ODBCTimestamp;
    epicfactor: number;
}
interface BaseScore {
    score: number;
    count300: number;
    count100: number;
    count50: number;
    countmiss: number;
    maxcombo: number;
    countkatu: number;
    countgeki: number;
    perfect: boolean;
    enabled_mods: Mod[];
}
interface LegacyBeatmapScore extends BaseScore {
    score_id: number;
    username: string;
    user_id: number;
    date: ODBCTimestamp;
    rank: Rank;
    pp: number;
    replay_available: boolean;
}
interface LegacyUserRecentScore extends BaseScore {
    beatmap_id: number;
    user_id: number;
    date: ODBCTimestamp;
    rank: Rank;
}
interface LegacyUserBestScore extends LegacyUserRecentScore {
    score_id: number;
    pp: number;
    replay_available: boolean;
}
interface LegacyMultiplayerLobby {
    match: LegacyMatch;
    games: LegacyGame[];
}
interface LegacyMatch {
    match_id: number;
    name: string;
    start_time: ODBCTimestamp;
    end_time: ODBCTimestamp | null;
}
interface LegacyGame {
    game_id: number;
    start_time: ODBCTimestamp;
    end_time: ODBCTimestamp | null;
    beatmap_id: number;
    play_mode: GameMode;
    scoring_type: ScoringType;
    team_type: TeamType;
    mods: Mod[];
    scores: LegacyMatchScore[];
}
interface LegacyMatchScore extends Omit<BaseScore, 'enabled_mods'> {
    slot: number;
    team: TeamColor | null;
    user_id: number;
    pass: boolean;
    enabled_mods: Mod[];
}

/**
 * Class that wraps all endpoints of the legacy API (API v1)
 */
declare class LegacyClient {
    private apiKey;
    private fetch;
    /**
     * @param apiKey API key
     * @param options.polyfillFetch In case developing with a Node.js version prior to 18, you need to pass a polyfill for the fetch API. Install `node-fetch`
     */
    constructor(apiKey: string, options?: {
        polyfillFetch?: typeof polyfillFetch;
    });
    private request;
    /**
     * Makes a GET request to the `get_beatmaps` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/legacy/get-beatmaps}
     * @returns An array of beatmaps
     */
    getBeatmaps(params: GetBeatmapsParams): Promise<LegacyBeatmap[]>;
    /**
     * Makes a GET request to the `get_user` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/legacy/get-user}
     * @returns A user if it exists, otherwise null
     */
    getUser(params: GetUserParams): Promise<LegacyUser | null>;
    /**
     * Makes a GET request to the `get_scores` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/legacy/get-beatmap-scores}
     * @returns An array of scores on a beatmap
     */
    getBeatmapScores(params: GetBeatmapScoresParams): Promise<LegacyBeatmapScore[]>;
    private getUserScores;
    /**
     * Makes a GET request to the `get_user_best` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/legacy/get-user-best-scores}
     * @returns An array of a user's top scores
     */
    getUserBestScores(params: GetUserScoresParams): Promise<LegacyUserBestScore[]>;
    /**
     * Makes a GET request to the `get_user_recent` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/legacy/get-user-recent-scores}
     * @returns An array of a user's most recent scores in 24 hours
     */
    getUserRecentScores(params: GetUserScoresParams): Promise<LegacyUserRecentScore[]>;
    /**
     * Makes a GET request to the `get_match` endpoint
     *
     * Documentation: {@link https://osujs.mario564.com/legacy/get-multiplayer-lobby}
     * @returns An object containing the match's information, games and each games' scores if the multiplayer lobby exists, otherwise null
     */
    getMultiplayerLobby(params: GetMultiplayerLobbyParams): Promise<LegacyMultiplayerLobby | null>;
    /**
     * Makes a GET request to the `get_replay`
     *
     * Documentation: {@link https://osujs.mario564.com/legacy/get-replay}
     * @param by Get replay by `score id` or `user & beatmap id`
     * @returns A string containing the Base64 encoded replay if the replay exists, otherwise null
     */
    getReplay<T extends 'score id' | 'user & beatmap id'>(by: T, params: T extends 'score id' ? GetReplayByScoreIdParams : GetReplayByBeatmapAndUserIdParams): Promise<string | null>;
}

/**
 * Convert an array of mods into its numerical representation. Only works with mods that are present in both legacy and current APIs. Only works with mods inside [this enum](https://github.com/ppy/osu-api/wiki#mods).
 *
 * Documentation: {@link https://osujs.mario564.com/extras/mod-enum-conversion}
 * @see getEnumMods for the inverse operation
 */
declare function getModsEnum(mods: Mod[], derivativeModsWithOriginal?: boolean): number;
/**
 * Convert a numerical representation of a mod or mod combination into an array of mods represented as strings. Returns and empty array if the input is 0. Only works with mods inside [this enum](https://github.com/ppy/osu-api/wiki#mods).
 *
 * Documentation: {@link https://osujs.mario564.com/extras/mod-enum-conversion}
 * @see getModsEnum for the inverse operation
 */
declare function getEnumMods(modEnum: number): Mod[];
/**
 * Determine if a value is an error thrown by osu.js
 *
 * Documentation: {@link https://osujs.mario564.com/extras/error-handling}
 */
declare function isOsuJSError(value: any): value is OsuJSError;

/**
 * URL builder
 *
 * Documentation: {@link https://osujs.mario564.com/extras/create-urls}
 */
declare const buildUrl: {
    /**
     * Create a custom URL using the ppy.sh domain as a base
     * @param path Path to set after `https://{subdomain}.ppy.sh/`
     * @param subdomain Specify a subdomain to point to, defaults to `osu`
     */
    custom: typeof createUrl;
    beatmapsetCover: (beatmapsetId: number) => string;
    beatmapsetThumbnail: (beatmapsetId: number) => string;
    beatmap: (beatmapId: number) => string;
    beatmapset: (beatmapsetId: number) => string;
    userAvatar: (userId: number) => string;
    user: (userId: number) => string;
    score: (gamemode: GameMode, scoreId: number) => string;
    forum: (forumId: number) => string;
    forumTopic: (topicId: number) => string;
    room: (roomId: number) => string;
    match: (matchId: number) => string;
    /**
     * @param clientId OAuth client ID
     * @param redirectUri OAuth redirect URI
     * @param scopes An array of OAuth scopes
     * @param state Data that will be returned when a temporary code is issued
     */
    authRequest: (clientId: number, redirectUri: string, scopes?: Scope[], state?: string) => string;
};
declare function createUrl(path: string, subdomain?: string): string;
/**
 * Score accuracy calculator
 *
 * Documentation: {@link https://osujs.mario564.com/extras/calculate-accuracy}
 */
declare const calcAccuracy: {
    /**
     * Calculate accuracy for osu! standard
     * @param c300 300s
     * @param c100 100s
     * @param c50 50s
     * @param misses Misses
     */
    osu: (c300: number, c100: number, c50: number, misses: number) => number;
    /**
     * Calculate accuracy for osu! taiko
     * @param geki Greats
     * @param katu Goods
     * @param misses Misses
     */
    taiko: (geki: number, katu: number, misses: number) => number;
    /**
     * Calculate accuracy for osu! catch
     * @param c300 Caught fruits
     * @param c100 Caught drops
     * @param c50 Caught droplets
     * @param katu Drops
     * @param misses Droplets
     */
    fruits: (c300: number, c100: number, c50: number, katu: number, misses: number) => number;
    /**
     * Calculate accuracy for osu! mania
     * @param geki Maxes
     * @param c300 300s
     * @param katu 200s
     * @param c100 100s
     * @param c50 50s
     * @param misses Misses
     * @param scoreV2 Apply score V2 formula?
     */
    mania: (geki: number, c300: number, katu: number, c100: number, c50: number, misses: number, scoreV2?: boolean) => number;
};
/**
 * Beatmap stat calculator based on mods
 *
 * Documentation: {@link https://osujs.mario564.com/extras/calculate-mod-stats}
 */
declare const calcModStat: {
    hr: {
        cs: (n: number) => number;
        od: typeof hrStat;
        ar: typeof hrStat;
        hp: typeof hrStat;
    };
    dt: {
        od: (n: number) => number;
        bpm: (n: number) => number;
        ar: (n: number) => number;
        length: (n: number) => number;
    };
    ez: {
        cs: typeof ezStat;
        od: typeof ezStat;
        ar: typeof ezStat;
        hp: typeof ezStat;
    };
    ht: {
        od: (n: number) => number;
        bpm: (n: number) => number;
        ar: (n: number) => number;
        length: (n: number) => number;
    };
};
declare function hrStat(n: number): number;
declare function ezStat(n: number): number;

export { AccuracyChallengeMod, AchievementGrouping, AdaptiveSpeedMod, AlternateMod, ApproachDifferentMod, Auth, AuthCodeGrant, AutopilotMod, AutoplayMod, BarrelRollMod, Beatmap, BeatmapCompact, BeatmapPlaycount, BeatmapUserScore, BeatmapUserScoreV2, Beatmaps, Beatmapset, BeatmapsetAvailability, BeatmapsetCompact, BeatmapsetDiscussion, BeatmapsetDiscussions, BeatmapsetHype, BlindsMod, BubblesMod, Build, BuildVersions, Changelog, ChangelogEntry, ChangelogStream, Channel, ChannelType, Chat, ChatMessage, ChatMessageType, CinemaMod, ClassicMod, Client, Comment, CommentBundle, CommentSort, CommentableMetadata, CommentableType, Comments, ConstantSpeedMod, Country, Cover, Covers, CreateAnnounceChannelOptions, CreatePMChannelOptions, CreatePMOptions, CreateTopicOptions, Cursor, DaycoreMod, DeflateMod, DepthMod, DifficultyAdjustMod, DiscussionMessageType, DiscussionPost, DiscussionVote, DoubleTimeMod, DualStagesMod, EasyMod, EventAchievement, EventBeatmap, EventBeatmapsetApprovedType, EventUser, FadeInMod, Fails, FlaslightMod, FloatingFruitsMod, Forum, ForumPoll, ForumPollOptions, ForumPost, ForumPostBody, ForumTopic, ForumTopicType, FreezeFrameMod, FruitsBeatmapDifficultyAttributes, GameMode, Genre, GenresEnum, GetBeatmapAttributesOptions, GetBeatmapScoresOptions, GetBeatmapScoresParams, GetBeatmapTopNonLegacyScoresOptions, GetBeatmapsOptions, GetBeatmapsParams, GetChangelogListingOptions, GetCommentsOptions, GetDiscussionPostsOptions, GetDiscussionVotesOptions, GetDiscussionsOptions, GetMultiplayerLobbyParams, GetNewsListingOptions, GetNewsPostOptions, GetPlaylistScoresOptions, GetRankingOptions, GetReplayByBeatmapAndUserIdParams, GetReplayByScoreIdParams, GetSelfOptions, GetTopicOptions, GetUserBeatmapsOptions, GetUserKodosuOptions, GetUserOptions, GetUserParams, GetUserRecentActivityOptions, GetUserRecentScoresOptions, GetUserScoresOptions, GetUserScoresParams, GetUsersOptions, GithubUser, Giver, GradeCounts, Group, GrowMod, GuestToken, HalfTimeMod, HardRockMod, HiddenMod, HoldOffMod, ISOTimestamp, InvertMod, Key10Mod, Key1Mod, Key2Mod, Key3Mod, Key4Mod, Key5Mod, Key6Mod, Key7Mod, Key8Mod, Key9Mod, KudosuAction, Language, LanguagesEnum, LegacyBeatmap, LegacyBeatmapScore, LegacyClient, LegacyEvent, LegacyGame, LegacyMatch, LegacyMatchScore, LegacyMultiplayerLobby, LegacyUser, LegacyUserBestScore, LegacyUserRecentScore, LookupBeatmapOptions, LookupChangelogBuildOptions, MagnetisedMod, ManiaBeatmapDifficultyAttributes, MirrorMod, Mod, ModSettings, ModesEnum, ModsEnum, MonthlyPlaycount, Multiplayer, MultiplayerScore, MultiplayerScoreMod, MultiplayerScoreStatistics, MultiplayerScores, MultiplayerScoresParams, MultiplayerScoresSort, MutedMod, News, NewsListing, NewsNavigation, NewsPost, NewsSearch, NewsSidebar, NightcoreMod, NoFailMod, NoScopeMod, ODBCTimestamp, Options, OsuBeatmapDifficultyAttributes, OsuJSError, OsuJSGeneralError, OsuJSUnexpectedResponseError, Page, PerfectMod, Playstyle, Post, ProfilePageSection, RandomMod, Rank, RankHighest, RankHistory, RankStatus, Ranking, RankingType, Rankings, RelaxMod, RepelMod, ReplyToTopicOptions, SafeParse, Scope, Score, ScoreStatistics, ScoreV2, ScoreV2Mod, ScoringType, ScoringTypeEnum, SearchOptions, SearchResult, SearchResults, SingleTapMod, SpinInMod, Spotlight, SpotlightType, SpunOutMod, StatisticsRulesets, StatusEnum, StrictTrackingMod, SuddenDeathMod, SwapMod, SynesthesiaMod, TaikoBeatmapDifficultyAttributes, TargetPracticeMod, TeamColor, TeamColorEnum, TeamType, TeamTypeEnum, Token, TouchDeviceMod, TraceableMod, TransformMod, UpdatePostOptions, UpdateStream, UpdateTopicOptions, User, UserAccountHistory, UserAccountHistoryType, UserAchievement, UserActiveTournamentBanner, UserBadge, UserBeatmapsType, UserBestScore, UserBestScoreV2, UserCompact, UserEvent, UserEventAchievement, UserEventBeatmapPlaycount, UserEventBeatmapsetApprove, UserEventBeatmapsetDelete, UserEventBeatmapsetUpdate, UserEventRankAchieved, UserEventRankLost, UserEventType, UserEventUserUpdate, UserEventUsernameUpdate, UserExtended, UserGroup, UserKudosu, UserKudosuHistory, UserLevel, UserScore, UserScoreType, UserScoreV2, UserStatistics, UserStatisticsVariant, Users, Weight, WiggleMod, Wiki, WikiPage, WindDownMod, WindUpMod, buildUrl, calcAccuracy, calcModStat, getEnumMods, getModsEnum, isOsuJSError };
