/// <reference types="lru-cache" />
/// <reference types="node" />
/// <reference types="koa__router" />
/// <reference types="ws" />
import * as utils from 'koishi-utils';
import { Observed, Logger } from 'koishi-utils';
import LruCache from 'lru-cache';
import { AxiosRequestConfig } from 'axios';
import { Server } from 'http';
import { inspect } from 'util';
import Router from '@koa/router';
import WebSocket from 'ws';
export type TableType = keyof Tables;
export interface Tables {
    user: User;
    channel: Channel;
}
export namespace Tables {
    type IndexType = string | number;
    type IndexKeys<O, T = any> = string & {
        [K in keyof O]: O[K] extends T ? K : never;
    }[keyof O];
    type QueryMap<O> = {
        [K in keyof O]?: O[K][];
    };
    export type Index<T extends TableType> = IndexKeys<Tables[T], IndexType>;
    export type Query<T extends TableType> = IndexType[] | QueryMap<Tables[T]>;
    export type Field<T extends TableType> = string & keyof Tables[T];
    interface Meta<O> {
        primary?: keyof O;
        unique?: (keyof O)[];
        type?: 'incremental';
    }
    export const config: {
        [T in TableType]?: Meta<Tables[T]>;
    };
    export function extend<T extends TableType>(name: T, meta?: Meta<Tables[T]>): void;
    export function resolveQuery<T extends TableType>(name: T, query: Query<T>): Record<string, any[]>;
    export {};
}
export interface User extends Record<Platform, string> {
    id: string;
    flag: number;
    authority: number;
    name: string;
    usage: Record<string, number>;
    timers: Record<string, number>;
}
export namespace User {
    export enum Flag {
        ignore = 1
    }
    export type Field = keyof User;
    export const fields: Field[];
    export type Index = Platform | 'name' | 'id';
    export type Observed<K extends Field = Field> = utils.Observed<Pick<User, K>, Promise<void>>;
    type Getter = <T extends Index>(type: T, id: string) => Partial<User>;
    export function extend(getter: Getter): void;
    export function create<T extends Index>(type: T, id: string): User;
    export {};
}
export interface Channel {
    id: string;
    flag: number;
    assignee: string;
    disable: string[];
}
export namespace Channel {
    export enum Flag {
        ignore = 1,
        silent = 4
    }
    export type Field = keyof Channel;
    export const fields: Field[];
    export type Observed<K extends Field = Field> = utils.Observed<Pick<Channel, K>, Promise<void>>;
    type Getter = (type: Platform, id: string) => Partial<Channel>;
    export function extend(getter: Getter): void;
    export function create(type: Platform, id: string): Channel;
    export {};
}
type MaybeArray<T> = T | T[];
export interface Database {
    get<T extends TableType, F extends Tables.Field<T>>(table: T, query: Tables.Query<T>, fields?: readonly F[]): Promise<Pick<Tables[T], F>[]>;
    remove<T extends TableType>(table: T, query: Tables.Query<T>): Promise<void>;
    create<T extends TableType>(table: T, data: Partial<Tables[T]>): Promise<Tables[T]>;
    update<T extends TableType>(table: T, data: Partial<Tables[T]>[], key?: Tables.Index<T>): Promise<void>;
    getUser<K extends User.Field, T extends User.Index>(type: T, id: string, fields?: readonly K[]): Promise<Pick<User, K | T>>;
    getUser<K extends User.Field, T extends User.Index>(type: T, ids: readonly string[], fields?: readonly K[]): Promise<Pick<User, K | T>[]>;
    setUser<T extends User.Index>(type: T, id: string, data: Partial<User>): Promise<void>;
    createUser<T extends User.Index>(type: T, id: string, data: Partial<User>): Promise<void>;
    removeUser<T extends User.Index>(type: T, id: string): Promise<void>;
    getChannel<K extends Channel.Field>(type: Platform, id: string, fields?: readonly K[]): Promise<Pick<Channel, K | 'id'>>;
    getChannel<K extends Channel.Field>(type: Platform, ids: readonly string[], fields?: readonly K[]): Promise<Pick<Channel, K | 'id'>[]>;
    getChannel<K extends Channel.Field>(type: Platform, id: MaybeArray<string>, fields?: readonly K[]): Promise<any>;
    getAssignedChannels<K extends Channel.Field>(fields?: readonly K[], assignMap?: Record<string, readonly string[]>): Promise<Pick<Channel, K>[]>;
    setChannel(type: Platform, id: string, data: Partial<Channel>): Promise<void>;
    createChannel(type: Platform, id: string, data: Partial<Channel>): Promise<void>;
    removeChannel(type: Platform, id: string): Promise<void>;
}
type Methods<S, T> = {
    [K in keyof S]?: S[K] extends (...args: infer R) => infer U ? (this: T, ...args: R) => U : S[K];
};
export namespace Database {
    export interface Statics {
    }
    type Constructor<T> = new (...args: any[]) => T;
    type ExtensionMethods<T> = Methods<Database, T extends Constructor<infer I> ? I : never>;
    type Extension<T> = ((Database: T) => void) | ExtensionMethods<T>;
    export function extend<K extends keyof Statics>(module: K, extension: Extension<Statics[K]>): void;
    export function extend<T extends Constructor<unknown>>(module: T, extension: Extension<T>): void;
    export {};
}
export interface Assets {
    types: readonly Assets.Type[];
    upload(url: string, file: string): Promise<string>;
    stats(): Promise<Assets.Stats>;
}
export namespace Assets {
    type Type = 'image' | 'audio' | 'video';
    interface Stats {
        assetCount?: number;
        assetSize?: number;
    }
}
export function getCommandNames(session: Session): string[];
export interface DelayOptions {
    character?: number;
    message?: number;
    cancel?: number;
    broadcast?: number;
    prompt?: number;
}
export interface AppOptions extends BotOptions {
    port?: number;
    bots?: BotOptions[];
    prefix?: string | string[];
    nickname?: string | string[];
    maxListeners?: number;
    prettyErrors?: boolean;
    processMessage?: (message: string) => string;
    delay?: DelayOptions;
    autoAssign?: boolean | ((session: Session) => boolean);
    autoAuthorize?: number | ((session: Session) => number);
    userCacheAge?: number;
    userCacheLength?: number;
    channelCacheLength?: number;
    channelCacheAge?: number;
    minSimilarity?: number;
    selfUrl?: string;
    axiosConfig?: AxiosRequestConfig;
}
export class App extends Context {
    app: this;
    options: AppOptions;
    status: App.Status;
    adapters: Adapter.Instances;
    registry: Map<Plugin<any>, Plugin.State>;
    _bots: Bot<never>[] & Record<string, Bot<never>>;
    _commands: Command[];
    _commandMap: Record<string, Command>;
    _shortcuts: Command.Shortcut[];
    _hooks: Record<keyof any, [Context, (...args: any[]) => any][]>;
    _userCache: Record<string, LruCache<string, Observed<Partial<User>, Promise<void>>>>;
    _channelCache: LruCache<string, Observed<Partial<Channel>, Promise<void>>>;
    _httpServer?: Server;
    _sessions: Record<string, Session>;
    private _nameRE;
    private _prefixRE;
    static defaultConfig: AppOptions;
    constructor(options?: AppOptions);
    createServer(): void;
    prepare(): void;
    start(): Promise<void>;
    private _listen;
    stop(): Promise<void>;
    private _close;
    private _process;
    private _suggest;
    private _handleMessage;
    private _handleArgv;
    private _handleShortcut;
}
export namespace App {
    enum Status {
        closed = 0,
        opening = 1,
        open = 2,
        closing = 3
    }
}
export type NextFunction = (next?: NextFunction) => Promise<void>;
export type Middleware = (session: Session, next: NextFunction) => any;
export type Promisify<T> = T extends Promise<unknown> ? T : Promise<T>;
export type Awaitable<T> = T extends Promise<unknown> ? T : T | Promise<T>;
export type Await<T> = T extends Promise<infer U> ? U : T;
export type Disposable = () => void;
export type Plugin<T = any> = Plugin.Function<T> | Plugin.Object<T>;
export namespace Plugin {
    export type Function<T = any> = (ctx: Context, options: T) => void;
    export interface Meta {
        name?: string;
        sideEffect?: boolean;
    }
    export interface Object<T = any> extends Meta {
        apply: Function<T>;
    }
    export type Config<T extends Plugin> = T extends Function<infer U> ? U : T extends Object<infer U> ? U : never;
    export interface State extends Meta {
        parent: State;
        children: Plugin[];
        disposables: Disposable[];
        dependencies: Set<State>;
    }
    export interface Packages {
    }
    export type Teleporter<D extends readonly (keyof Packages)[]> = (ctx: Context, ...modules: From<D>) => void;
    type From<D extends readonly unknown[]> = D extends readonly [infer L, ...infer R] ? [L extends keyof Packages ? Packages[L] : unknown, ...From<R>] : [];
    export {};
}
type Filter = (session: Session) => boolean;
type PartialSeletor<T> = (...values: T[]) => Context;
interface Selector<T> extends PartialSeletor<T> {
    except?: PartialSeletor<T>;
}
export class Context {
    filter: Filter;
    app?: App;
    private _plugin;
    static readonly middleware: unique symbol;
    static readonly current: unique symbol;
    protected _bots: Bot[] & Record<string, Bot>;
    database: Database;
    assets: Assets;
    router: Router;
    protected constructor(filter: Filter, app?: App, _plugin?: Plugin);
    [inspect.custom](): string;
    private createSelector;
    get user(): Selector<string>;
    get self(): Selector<string>;
    get group(): Selector<string>;
    get channel(): Selector<string>;
    get platform(): Selector<never>;
    get private(): Selector<string>;
    get bots(): Bot<never>[] & Record<string, Bot<never>>;
    logger(name: string): Logger;
    select<K extends keyof Session>(key: K, ...values: Session[K][]): Context;
    unselect<K extends keyof Session>(key: K, ...values: Session[K][]): Context;
    all(): Context;
    union(arg: Filter | Context): Context;
    intersect(arg: Filter | Context): Context;
    match(session?: Session): boolean;
    get state(): Plugin.State;
    addSideEffect(state?: Plugin.State): void;
    private teleport;
    with<D extends readonly (keyof Plugin.Packages)[]>(deps: D, callback: Plugin.Teleporter<D>): this;
    plugin<T extends Plugin>(plugin: T, options?: Plugin.Config<T>): this;
    dispose(plugin?: Plugin<any>): Promise<void>;
    parallel<K extends EventName>(name: K, ...args: Parameters<EventMap[K]>): Promise<Await<ReturnType<EventMap[K]>>[]>;
    parallel<K extends EventName>(session: Session, name: K, ...args: Parameters<EventMap[K]>): Promise<Await<ReturnType<EventMap[K]>>[]>;
    emit<K extends EventName>(name: K, ...args: Parameters<EventMap[K]>): void;
    emit<K extends EventName>(session: Session, name: K, ...args: Parameters<EventMap[K]>): void;
    waterfall<K extends EventName>(name: K, ...args: Parameters<EventMap[K]>): Promisify<ReturnType<EventMap[K]>>;
    waterfall<K extends EventName>(session: Session, name: K, ...args: Parameters<EventMap[K]>): Promisify<ReturnType<EventMap[K]>>;
    chain<K extends EventName>(name: K, ...args: Parameters<EventMap[K]>): ReturnType<EventMap[K]>;
    chain<K extends EventName>(session: Session, name: K, ...args: Parameters<EventMap[K]>): ReturnType<EventMap[K]>;
    serial<K extends EventName>(name: K, ...args: Parameters<EventMap[K]>): Promisify<ReturnType<EventMap[K]>>;
    serial<K extends EventName>(session: Session, name: K, ...args: Parameters<EventMap[K]>): Promisify<ReturnType<EventMap[K]>>;
    bail<K extends EventName>(name: K, ...args: Parameters<EventMap[K]>): ReturnType<EventMap[K]>;
    bail<K extends EventName>(session: Session, name: K, ...args: Parameters<EventMap[K]>): ReturnType<EventMap[K]>;
    on<K extends EventName>(name: K, listener: EventMap[K], prepend?: boolean): () => boolean;
    before<K extends BeforeEventName>(name: K, listener: BeforeEventMap[K], append?: boolean): () => boolean;
    once<K extends EventName>(name: K, listener: EventMap[K], prepend?: boolean): () => boolean;
    off<K extends EventName>(name: K, listener: EventMap[K]): boolean;
    middleware(middleware: Middleware, prepend?: boolean): () => boolean;
    private createTimerDispose;
    setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): () => boolean;
    setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): () => boolean;
    command<D extends string>(def: D, config?: Command.Config): Command<never, never, Domain.ArgumentType<D>>;
    command<D extends string>(def: D, desc: string, config?: Command.Config): Command<never, never, Domain.ArgumentType<D>>;
    transformAssets(content: string, assets?: Assets): Promise<string>;
    getBot(platform: Platform, selfId?: string): Bot<never>;
    getSelfIds(type?: Platform, assignees?: readonly string[]): Record<string, readonly string[]>;
    broadcast(content: string, forced?: boolean): Promise<string[]>;
    broadcast(channels: readonly string[], content: string, forced?: boolean): Promise<string[]>;
    static delegate(key: string & keyof Context): void;
}
type FlattenEvents<T> = {
    [K in keyof T & string]: K | `${K}/${FlattenEvents<T[K]>}`;
}[keyof T & string];
type SessionEventMap = {
    [K in FlattenEvents<Session.Events>]: K extends `${infer X}/${infer R}` ? R extends `${infer Y}/${any}` ? (session: Session.Payload<X, Y>) => void : (session: Session.Payload<X, R>) => void : (session: Session.Payload<K>) => void;
};
type EventName = keyof EventMap;
type OmitSubstring<S extends string, T extends string> = S extends `${infer L}${T}${infer R}` ? `${L}${R}` : never;
type BeforeEventName = OmitSubstring<EventName & string, 'before-'>;
type BeforeEventMap = {
    [E in EventName & string as OmitSubstring<E, 'before-'>]: EventMap[E];
};
export interface EventMap extends SessionEventMap {
    [Context.middleware]: Middleware;
    'appellation'(name: string, session: Session): string;
    'before-parse'(content: string, session: Session): Argv;
    'parse'(argv: Argv, session: Session): string;
    'before-attach-channel'(session: Session, fields: Set<Channel.Field>): void;
    'attach-channel'(session: Session): Awaitable<void | boolean>;
    'before-attach-user'(session: Session, fields: Set<User.Field>): void;
    'attach-user'(session: Session): Awaitable<void | boolean>;
    'before-attach'(session: Session): void;
    'attach'(session: Session): void;
    'before-send'(session: Session<never, never, Platform, 'send'>): Awaitable<void | boolean>;
    'before-command'(argv: Argv): Awaitable<void | string>;
    'command'(argv: Argv): Awaitable<void>;
    'middleware'(session: Session): void;
    'plugin-added'(plugin: Plugin, registry: Map<Plugin, Plugin.State>): void;
    'plugin-removed'(plugin: Plugin, registry: Map<Plugin, Plugin.State>): void;
    'before-connect'(): Awaitable<void>;
    'connect'(): void;
    'before-disconnect'(): Awaitable<void>;
    'disconnect'(): void;
}
export interface Domain {
    string: string;
    number: number;
    boolean: boolean;
    text: string;
    user: string;
    channel: string;
    integer: number;
    posint: number;
    date: Date;
}
export namespace Domain {
    type Builtin = keyof Domain;
    type ParamType<S extends string, F> = S extends `${any}:${infer T}` ? T extends Builtin ? Domain[T] : F : F;
    type Replace<S extends string, X extends string, Y extends string> = S extends `${infer L}${X}${infer R}` ? `${L}${Y}${Replace<R, X, Y>}` : S;
    type ExtractAll<S extends string, F> = S extends `${infer L}]${infer R}` ? [ParamType<L, F>, ...ExtractAll<R, F>] : [];
    type ExtractFirst<S extends string, F> = S extends `${infer L}]${any}` ? ParamType<L, F> : boolean;
    type ExtractSpread<S extends string> = S extends `${infer L}...${infer R}` ? [...ExtractAll<L, string>, ...ExtractFirst<R, string>[]] : [...ExtractAll<S, string>, ...string[]];
    export type ArgumentType<S extends string> = ExtractSpread<Replace<S, '>', ']'>>;
    export type OptionType<S extends string, T extends Type> = [T] extends [Builtin] ? Domain[T] : [T] extends [RegExp] ? string : T extends (source: string) => infer R ? R : ExtractFirst<Replace<S, '>', ']'>, any>;
    export type Type = Builtin | RegExp | Transform<any>;
    export interface Declaration {
        name?: string;
        type?: Type;
        fallback?: any;
        variadic?: boolean;
        required?: boolean;
    }
    export type Transform<T> = (source: string, session: Session) => T;
    export function create<K extends keyof Domain>(name: K, callback: Transform<Domain[K]>): void;
    export interface OptionConfig<T extends Type = Type> {
        value?: any;
        fallback?: any;
        type?: T;
        /** hide the option by default */
        hidden?: boolean | ((session: Session) => boolean);
        authority?: number;
        notUsage?: boolean;
    }
    export interface OptionDeclaration extends Declaration, OptionConfig {
        description?: string;
        values?: Record<string, any>;
    }
    type OptionDeclarationMap = Record<string, OptionDeclaration>;
    export class CommandBase {
        name: string;
        description: string;
        declaration: string;
        _arguments: Declaration[];
        _options: OptionDeclarationMap;
        private _error;
        private _namedOptions;
        private _symbolicOptions;
        constructor(name: string, declaration: string, description: string);
        _createOption(name: string, def: string, config?: OptionConfig): void;
        private _assignOption;
        removeOption<K extends string>(name: K): boolean;
        private _parseValue;
        parse(argv: Argv): Argv;
        parse(source: string, terminator?: string): Argv;
        private stringifyArg;
        stringify(args: readonly string[], options: any): string;
    }
    export {};
}
export interface Token {
    rest?: string;
    content: string;
    quoted: boolean;
    terminator: string;
    inters: Argv[];
}
export interface Argv<U extends User.Field = never, G extends Channel.Field = never, A extends any[] = any[], O = {}> {
    args?: A;
    options?: O;
    error?: string;
    source?: string;
    initiator?: string;
    terminator?: string;
    session?: Session<U, G>;
    command?: Command<U, G, A, O>;
    rest?: string;
    pos?: number;
    root?: boolean;
    tokens?: Token[];
    name?: string;
    next?: NextFunction;
}
export namespace Argv {
    interface Interpolation {
        terminator?: string;
        parse?(source: string): Argv;
    }
    function interpolate(initiator: string, terminator: string, parse?: (source: string) => Argv): void;
    class Tokenizer {
        private bracs;
        constructor();
        interpolate(initiator: string, terminator: string, parse?: (source: string) => Argv): void;
        parseToken(source: string, stopReg?: string): Token;
        parse(source: string, terminator?: string): Argv;
        stringify(argv: Argv): string;
    }
    function parse(source: string, terminator?: string): Argv<never, never, any[], {}>;
    function stringify(argv: Argv): string;
    function revert(token: Token): void;
    const createDomain: typeof Domain.create;
    function parsePid(target: string): [Platform, string];
}
export type UserType<T, U extends User.Field = User.Field> = T | ((user: Pick<User, U>) => T);
export type Extend<O extends {}, K extends string, T> = {
    [P in K | keyof O]?: (P extends keyof O ? O[P] : unknown) & (P extends K ? T : unknown);
};
export namespace Command {
    interface Config {
        /** hide all options by default */
        hideOptions?: boolean;
        /** hide command */
        hidden?: boolean;
        /** min authority */
        authority?: number;
        /** disallow unknown options */
        checkUnknown?: boolean;
        /** check argument count */
        checkArgCount?: boolean;
        /** show command warnings */
        showWarning?: boolean;
        /** usage identifier */
        usageName?: string;
        /** max usage per day */
        maxUsage?: UserType<number>;
        /** min interval */
        minInterval?: UserType<number>;
        /** depend on existing commands */
        patch?: boolean;
    }
    interface Shortcut {
        name?: string | RegExp;
        command?: Command;
        authority?: number;
        prefix?: boolean;
        fuzzy?: boolean;
        args?: string[];
        greedy?: boolean;
        options?: Record<string, any>;
    }
    type Action<U extends User.Field = never, G extends Channel.Field = never, A extends any[] = any[], O extends {} = {}> = (argv: Argv<U, G, A, O>, ...args: A) => void | string | Promise<void | string>;
    type Usage<U extends User.Field = never, G extends Channel.Field = never> = string | ((session: Session<U, G>) => string | Promise<string>);
}
export class Command<U extends User.Field = never, G extends Channel.Field = never, A extends any[] = any[], O extends {} = {}> extends Domain.CommandBase {
    context: Context;
    config: Command.Config;
    children: Command[];
    parent: Command;
    _aliases: string[];
    _examples: string[];
    _usage?: Command.Usage;
    _disposed?: boolean;
    _disposables?: Disposable[];
    private _userFields;
    private _channelFields;
    private _actions;
    private _checkers;
    static defaultConfig: Command.Config;
    static defaultOptionConfig: Domain.OptionConfig;
    private static _userFields;
    private static _channelFields;
    static userFields(fields: FieldCollector<'user'>): typeof Command;
    static channelFields(fields: FieldCollector<'channel'>): typeof Command;
    constructor(name: string, decl: string, desc: string, context: Context);
    get app(): App;
    private _registerAlias;
    [inspect.custom](): string;
    userFields<T extends User.Field = never>(fields: FieldCollector<'user', T, A, O>): Command<U | T, G, A, O>;
    channelFields<T extends Channel.Field = never>(fields: FieldCollector<'channel', T, A, O>): Command<U, G | T, A, O>;
    alias(...names: string[]): this;
    shortcut(name: string | RegExp, config?: Command.Shortcut): this;
    subcommand<D extends string>(def: D, config?: Command.Config): Command<never, never, Domain.ArgumentType<D>>;
    subcommand<D extends string>(def: D, desc: string, config?: Command.Config): Command<never, never, Domain.ArgumentType<D>>;
    usage(text: Command.Usage<U, G>): this;
    example(example: string): this;
    option<K extends string, D extends string, T extends Domain.Type>(name: K, desc: D, config?: Domain.OptionConfig<T>): Command<U, G, A, Extend<O, K, Domain.OptionType<D, T>>>;
    match(session: Session): boolean;
    getConfig<K extends keyof Command.Config>(key: K, session: Session): Exclude<Command.Config[K], (user: User) => any>;
    check(callback: Command.Action<U, G, A, O>, prepend?: boolean): this;
    action(callback: Command.Action<U, G, A, O>, append?: boolean): this;
    execute(argv0: Argv<U, G, A, O>, next?: NextFunction): Promise<string>;
    dispose(): void;
}
export function getUsageName(command: Command): string;
export type ValidationField = 'authority' | 'usage' | 'timers';
export function getUsage(name: string, user: Pick<User, 'usage'>): number;
export function checkUsage(name: string, user: Pick<User, 'usage'>, maxUsage?: number): boolean;
export function checkTimer(name: string, { timers }: Pick<User, 'timers'>, offset?: number): boolean;
type UnionToIntersection<U> = (U extends any ? (key: U) => void : never) extends (key: infer I) => void ? I : never;
type Flatten<T, K extends keyof T = keyof T> = UnionToIntersection<T[K]>;
type InnerKeys<T, K extends keyof T = keyof T> = keyof Flatten<T> & keyof Flatten<T, K>;
export interface Session<U, G, P, X, Y> extends MessageBase, Partial<ChannelInfo>, Partial<GroupInfo> {
}
export namespace Session {
    type Genres = 'friend' | 'channel' | 'group' | 'group-member' | 'group-role' | 'group-file' | 'group-emoji';
    type Actions = 'added' | 'deleted' | 'updated';
    export interface Events extends Record<`${Genres}-${Actions}`, {}> {
    }
    export type MessageAction = 'message' | 'message-deleted' | 'message-updated' | 'send';
    export type Message = Session<never, never, Platform, MessageAction>;
    export interface Events extends Record<MessageAction, MessageType> {
    }
    export type RequestAction = 'friend-request' | 'group-request' | 'group-member-request';
    export type Request = Session<never, never, Platform, RequestAction>;
    export interface Events extends Record<RequestAction, {}> {
    }
    export interface Events {
        'friend-request': {};
        'group-request': {};
        'group-member-request': {};
        'group-added': GroupMemberChangeType;
        'group-member-added': GroupMemberChangeType;
        'group-deleted': GroupMemberChangeType;
        'group-member-deleted': GroupMemberChangeType;
        'group-member': {
            'role': {};
            'ban': {};
        };
        'notice': {
            'poke': {};
            'lucky-king': {};
            'honor': {
                'talkative': {};
                'performer': {};
                'emotion': {};
            };
        };
    }
    export interface GroupMemberChangeType {
        'active': {};
        'passive': {};
    }
    export interface MessageType {
        'private': {};
        'group': {};
    }
    type ParamX<X> = Extract<keyof Events, X>;
    type ParamY<X, Y> = Extract<InnerKeys<Events, ParamX<X>>, Y>;
    export type Payload<X, Y = any> = Session<never, never, Platform, ParamX<X>, ParamY<X, Y>>;
    export {};
}
export interface Parsed {
    content: string;
    prefix: string;
    appel: boolean;
}
export class Session<U extends User.Field = never, G extends Channel.Field = never, P extends Platform = Platform, X extends keyof Session.Events = keyof Session.Events, Y extends InnerKeys<Session.Events, X> = InnerKeys<Session.Events, X>> {
    type?: X;
    subtype?: Y;
    subsubtype?: InnerKeys<UnionToIntersection<Session.Events[X]>, Y>;
    platform?: P;
    selfId?: string;
    operatorId?: string;
    targetId?: string;
    duration?: number;
    file?: FileInfo;
    readonly app: App;
    readonly bot: Bot.Instance<P>;
    readonly sid: string;
    uid: string;
    cid: string;
    gid: string;
    id?: string;
    argv?: Argv<U, G>;
    user?: User.Observed<U>;
    channel?: Channel.Observed<G>;
    parsed?: Parsed;
    private _delay?;
    private _queued;
    private _hooks;
    private _promise;
    static readonly send: unique symbol;
    constructor(app: App, session: Partial<Session>);
    toJSON(): Partial<Session>;
    private _preprocess;
    preprocess(): Promise<string>;
    get username(): string;
    get database(): Database;
    send(message: string): Promise<void>;
    cancelQueued(delay?: number): void;
    sendQueued(content: string, delay?: number): Promise<void>;
    resolveValue<T>(source: T | ((session: Session) => T)): T;
    getChannel<K extends Channel.Field = never>(id?: string, assignee?: string, fields?: readonly K[]): Promise<Pick<Channel, "id" | K>>;
    /** 在当前会话上绑定一个可观测频道实例 */
    observeChannel<T extends Channel.Field = never>(fields?: Iterable<T>): Promise<Channel.Observed<T | G>>;
    getUser<K extends User.Field = never>(id?: string, authority?: number, fields?: readonly K[]): Promise<Pick<User, P | K>>;
    /** 在当前会话上绑定一个可观测用户实例 */
    observeUser<T extends User.Field = never>(fields?: Iterable<T>): Promise<User.Observed<T | U>>;
    collect<T extends TableType>(key: T, argv: Argv, fields?: Set<keyof Tables[T]>): Set<keyof Tables[T]>;
    resolve(argv: Argv): Command<never, never, any[], {}>;
    execute(content: string, next?: true | NextFunction): Promise<string>;
    execute(argv: Argv, next?: true | NextFunction): Promise<string>;
    middleware(middleware: Middleware): () => boolean;
    prompt(timeout?: number): Promise<string>;
    suggest(options: SuggestOptions): Promise<void>;
}
export interface SuggestOptions {
    target: string;
    items: string[];
    next?: NextFunction;
    prefix?: string;
    suffix: string;
    minSimilarity?: number;
    apply: (this: Session, suggestion: string, next: NextFunction) => void;
}
export function getSessionId(session: Session): string;
export type FieldCollector<T extends TableType, K = keyof Tables[T], A extends any[] = any[], O = {}> = Iterable<K> | ((argv: Argv<never, never, A, O>, fields: Set<keyof Tables[T]>) => void);
export interface FileInfo {
    id: string;
    name: string;
    size: number;
    busid: number;
}
export interface BotOptions {
    type?: string;
    token?: string;
    selfId?: string;
}
type BotList<T extends Bot> = Array<T> & Record<string, T>;
export function createBots<T extends Bot>(key: 'selfId' | 'sid'): BotList<T>;
export abstract class Adapter<P extends Platform = Platform> {
    app: App;
    private Bot?;
    bots: BotList<Bot.Instance<P>>;
    abstract start(): Promise<void>;
    abstract stop?(): void;
    constructor(app: App, Bot?: Bot.Constructor<P>);
    create(options: BotOptions, constructor?: Bot.Constructor<P>): Bot.Instance<P>;
    dispatch(session: Session): void;
}
export namespace Adapter {
    type Constructor<T extends Platform = Platform> = new (app: App, bot: BotOptions) => Adapter<T>;
    type Instances = {
        [K in string]: K extends `${infer T}:${any}` ? Adapter<T & Platform> : Adapter<K & Platform>;
    };
    const types: Record<string, Constructor>;
    function from(app: App, bot: BotOptions): Adapter<never>;
    function redirect(target: string | ((bot: BotOptions) => string)): Constructor<never>;
    interface WsClientOptions {
        retryLazy?: number;
        retryTimes?: number;
        retryInterval?: number;
    }
    abstract class WsClient<P extends Platform = Platform> extends Adapter<P> {
        abstract prepare(bot: Bot.Instance<P>): WebSocket | Promise<WebSocket>;
        abstract connect(bot: Bot.Instance<P>): Promise<void>;
        private _listening;
        options: WsClientOptions;
        static options: WsClientOptions;
        constructor(app: App, Bot: Bot.Constructor<P>, options?: WsClientOptions);
        private _listen;
        start(): Promise<void>;
        stop(): void;
    }
}
export interface Bot<P = Platform> extends BotOptions, UserBase {
    [Session.send](session: Session, message: string): Promise<void>;
    status: Bot.Status;
    socket?: WebSocket;
    version?: string;
    getStatus(): Promise<Bot.Status>;
    sendMessage(channelId: string, content: string): Promise<string>;
    sendPrivateMessage(userId: string, content: string): Promise<string>;
    getMessage(channelId: string, messageId: string): Promise<MessageInfo>;
    editMessage(channelId: string, messageId: string, content: string): Promise<void>;
    deleteMessage(channelId: string, messageId: string): Promise<void>;
    getSelf(): Promise<UserInfo>;
    getUser(userId: string): Promise<UserInfo>;
    getFriendList(): Promise<UserInfo[]>;
    getGroup(groupId: string): Promise<GroupInfo>;
    getGroupList(): Promise<GroupInfo[]>;
    getGroupMember(groupId: string, userId: string): Promise<GroupMemberInfo>;
    getGroupMemberList(groupId: string): Promise<GroupMemberInfo[]>;
    getChannel(channelId: string): Promise<ChannelInfo>;
    getChannelList(groupId: string): Promise<ChannelInfo[]>;
    handleFriendRequest(messageId: string, approve: boolean, comment?: string): Promise<void>;
    handleGroupRequest(messageId: string, approve: boolean, comment?: string): Promise<void>;
    handleGroupMemberRequest(messageId: string, approve: boolean, comment?: string): Promise<void>;
}
export class Bot<P extends Platform> {
    adapter: Adapter<P>;
    readonly app: App;
    readonly logger: Logger;
    readonly platform: P;
    constructor(adapter: Adapter<P>, options: BotOptions);
    get sid(): string;
    createSession(session: Partial<Session<never, never, P, 'send'>>): Session<never, never, P, "send", "private" | "group">;
    getGroupMemberMap(groupId: string): Promise<{
        [k: string]: string;
    }>;
    broadcast(channels: string[], content: string, delay?: number): Promise<string[]>;
}
export namespace Bot {
    interface Platforms {
    }
    type Instance<T extends Platform> = [T] extends [never] ? Bot<T> : Platforms[T];
    type Constructor<T extends Platform> = new (adapter: Adapter, options: BotOptions) => Instance<T>;
    enum Status {
        /** 正常运行 */
        GOOD = 0,
        /** 机器人处于闲置状态 */
        BOT_IDLE = 1,
        /** 机器人离线 */
        BOT_OFFLINE = 2,
        /** 无法获得状态 */
        NET_ERROR = 3,
        /** 服务器状态异常 */
        SERVER_ERROR = 4,
        /** 机器人被封禁 */
        BANNED = 5,
        /** 正在尝试连接 */
        CONNECTING = 6
    }
}
export type Platform = keyof Bot.Platforms;
export interface ChannelInfo {
    channelId: string;
    channelName: string;
}
export interface GroupInfo {
    groupId: string;
    groupName: string;
}
export interface UserBase {
    username: string;
    nickname?: string;
    avatar?: string;
    discriminator?: string;
    isBot?: boolean;
}
export interface UserInfo extends UserBase {
    userId: string;
}
export interface GroupMemberInfo extends UserInfo {
    roles?: string[];
}
export interface AuthorInfo extends GroupMemberInfo {
    anonymous?: string;
}
export interface MessageBase {
    messageId?: string;
    channelId?: string;
    groupId?: string;
    userId?: string;
    content?: string;
    timestamp?: number;
    author?: AuthorInfo;
    quote?: MessageInfo;
}
export interface MessageInfo extends MessageBase {
    subtype?: keyof Session.Events['message'];
}
export * from 'koishi-utils';
export const version: string;export default function apply(ctx: Context): void;
