///
///
///
///
import * as utils from 'koishi-utils';
import { MaybeArray, Get, Extract, Observed, Logger, Promisify, Awaitable } 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;
type Primitive = string | number;
type Comparable = Primitive | Date;
type Keys = string & {
[K in keyof O]: O[K] extends T ? K : never;
}[keyof O];
export interface Tables {
user: User;
channel: Channel;
}
export namespace Tables {
interface Field {
type: Field.Type;
length?: number;
nullable?: boolean;
initial?: T;
precision?: number;
scale?: number;
}
namespace Field {
export const number: Type[];
export const string: Type[];
export const date: Type[];
export const object: Type[];
export type Type = T extends number ? 'integer' | 'unsigned' | 'float' | 'double' | 'decimal' : T extends string ? 'char' | 'string' | 'text' : T extends Date ? 'timestamp' | 'date' | 'time' : T extends any[] ? 'list' | 'json' : T extends object ? 'json' : never;
type WithParam = S | `${S}(${any})`;
export type Extension = {
[K in keyof O]?: Field | WithParam>;
};
export type Config = {
[K in keyof O]?: Field;
};
export function parse(source: string | Field): Field;
export {};
}
interface Extension {
type?: 'random' | 'incremental';
primary?: Keys;
unique?: MaybeArray>[];
foreign?: {
[K in keyof O]?: [TableType, string];
};
fields?: Field.Extension;
}
interface Config extends Extension {
fields?: Field.Config;
}
const config: Record;
function extend(name: T, meta?: Extension): void;
function create(name: T): Tables[T];
}
export type Query = Query.Expr | Query.Shorthand;
export namespace Query {
export type Field = string & keyof Tables[T];
export type Index = Keys;
export interface FieldExpr {
$in?: Extract;
$nin?: Extract;
$eq?: Extract;
$ne?: Extract;
$gt?: Extract;
$gte?: Extract;
$lt?: Extract;
$lte?: Extract;
$el?: T extends (infer U)[] ? FieldQuery : never;
$size?: Extract;
$regex?: Extract;
$regexFor?: Extract;
$bitsAllClear?: Extract;
$bitsAllSet?: Extract;
$bitsAnyClear?: Extract;
$bitsAnySet?: Extract;
}
export interface LogicalExpr {
$or?: Expr[];
$and?: Expr[];
$not?: Expr;
$expr?: Eval.Boolean;
}
export type Shorthand = Extract | Extract | Extract;
export type FieldQuery = FieldExpr | Shorthand;
export type Expr = LogicalExpr & {
[K in keyof T]?: FieldQuery;
};
export function resolve(name: T, query?: Query): Expr;
export interface ModifierExpr {
limit?: number;
offset?: number;
fields?: K[];
}
export type Modifier = T[] | ModifierExpr;
export function resolveModifier(modifier: Modifier): ModifierExpr;
type Projection = Record>;
type MapEval = {
[K in keyof P]: Eval;
};
export interface Database {
drop(table?: TableType): Promise;
get>(table: T, query: Query, modifier?: Modifier): Promise[]>;
remove(table: T, query: Query): Promise;
create(table: T, data: Partial): Promise;
update(table: T, data: Partial[], key?: Index): Promise;
aggregate>(table: T, fields: P, query?: Query): Promise>;
}
export {};
}
export type Eval = U extends number ? number : U extends boolean ? boolean : U extends string ? Get : U extends Eval.NumericExpr ? number : U extends Eval.BooleanExpr ? boolean : U extends Eval.AggregationExpr ? number : never;
export namespace Eval {
type Any = A | number | boolean | Keys | NumericExpr | BooleanExpr;
type GeneralExpr = NumericExpr & BooleanExpr & AggregationExpr;
type Numeric = A | number | Keys | NumericExpr;
type Boolean = boolean | Keys | BooleanExpr;
type Aggregation = Any<{}, AggregationExpr>;
interface NumericExpr {
$add?: Numeric[];
$multiply?: Numeric[];
$subtract?: [Numeric, Numeric];
$divide?: [Numeric, Numeric];
}
interface BooleanExpr {
$eq?: [Numeric, Numeric];
$ne?: [Numeric, Numeric];
$gt?: [Numeric, Numeric];
$gte?: [Numeric, Numeric];
$lt?: [Numeric, Numeric];
$lte?: [Numeric, Numeric];
}
interface AggregationExpr {
$sum?: Any;
$avg?: Any;
$max?: Any;
$min?: Any;
$count?: Any;
}
}
export interface User extends Record {
id: string;
flag: number;
authority: number;
name: string;
usage: Record;
timers: Record;
}
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 = utils.Observed, Promise>;
type Getter = (type: T, id: string) => Partial;
/**
* @deprecated use `Tables.extend('user', { fields })` instead
*/
export function extend(getter: Getter): void;
export function create(type: T, id: string): User;
export interface Database {
getUser(type: T, id: string, modifier?: Query.Modifier): Promise>;
getUser(type: T, ids: string[], modifier?: Query.Modifier): Promise[]>;
getUser(type: T, id: MaybeArray, modifier?: Query.Modifier): Promise;
setUser(type: T, id: string, data: Partial): Promise;
createUser(type: T, id: string, data: Partial): Promise;
}
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 = utils.Observed, Promise>;
type Getter = (type: Platform, id: string) => Partial;
/**
* @deprecated use `Tables.extend('user', { fields })` instead
*/
export function extend(getter: Getter): void;
export function create(type: Platform, id: string): Channel;
export interface Database {
getChannel(type: Platform, id: string, modifier?: Query.Modifier): Promise>;
getChannel(type: Platform, ids: readonly string[], modifier?: Query.Modifier): Promise[]>;
getChannel(type: Platform, id: MaybeArray, modifier?: Query.Modifier): Promise;
getAssignedChannels(fields?: K[], assignMap?: Record): Promise[]>;
setChannel(type: Platform, id: string, data: Partial): Promise;
createChannel(type: Platform, id: string, data: Partial): Promise;
}
export {};
}
export interface Database extends Query.Database, User.Database, Channel.Database {
}
type Methods = {
[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 = new (...args: any[]) => T;
type ExtensionMethods = Methods ? I : never>;
type Extension = ((Database: T) => void) | ExtensionMethods;
export function extend(module: K, extension: Extension): void;
export function extend>(module: T, extension: Extension): void;
export {};
}
export interface Assets {
types: readonly Assets.Type[];
upload(url: string, file: string): Promise;
stats(): Promise;
}
export namespace Assets {
type Type = 'image' | 'audio' | 'video' | 'file';
interface Stats {
assetCount?: number;
assetSize?: number;
}
}
export interface HelpConfig extends Command.Config {
shortcut?: boolean;
options?: boolean;
}
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;
host?: string;
bots?: BotOptions[];
prefix?: string | string[] | ((session: Session.Message) => void | string | string[]);
nickname?: string | string[];
maxListeners?: number;
prettyErrors?: boolean;
processMessage?: (message: string) => string;
delay?: DelayOptions;
help?: boolean | HelpConfig;
autoAssign?: boolean | ((session: Session) => boolean);
autoAuthorize?: number | ((session: Session) => number);
userCacheAge?: number;
userCacheLength?: number;
channelCacheLength?: number;
channelCacheAge?: number;
minSimilarity?: number;
selfUrl?: string;
axiosConfig?: AxiosRequestConfig;
}
interface CommandMap extends Map {
resolve(key: string): Command;
}
export class App extends Context {
app: this;
options: AppOptions;
status: App.Status;
adapters: Adapter.Instances;
registry: Plugin.Registry;
_bots: Bot[] & Record>;
_commandList: Command[];
_commands: CommandMap;
_shortcuts: Command.Shortcut[];
_hooks: Record any][]>;
_userCache: Record, Promise>>>;
_channelCache: LruCache, Promise>>;
_httpServer?: Server;
_sessions: Record;
private _nameRE;
static defaultConfig: AppOptions;
constructor(options?: AppOptions);
createServer(): void;
prepare(): void;
start(): Promise;
private _listen;
stop(): Promise;
private _close;
private _resolvePrefixes;
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;
export type Middleware = (session: Session, next: NextFunction) => any;
export type Disposable = () => void;
export type Plugin = Plugin.Function | Plugin.Object;
export namespace Plugin {
export type Function = (ctx: Context, options: T) => void;
export interface Meta {
name?: string;
sideEffect?: boolean;
}
export interface Object extends Meta {
apply: Function;
}
export type Config = T extends Function ? U : T extends Object ? U : never;
export interface State extends Meta {
id?: string;
parent?: State;
context?: Context;
config?: T;
plugin?: Plugin;
children: Plugin[];
disposables: Disposable[];
}
export interface Packages {
}
export type Teleporter = (ctx: Context, ...modules: From) => void;
type From = D extends readonly [infer L, ...infer R] ? [L extends keyof Packages ? Packages[L] : unknown, ...From] : [];
export class Registry extends Map {
resolve(plugin: Plugin): Function;
get(plugin: Plugin): State;
set(plugin: Plugin, state: State): this;
has(plugin: Plugin): boolean;
delete(plugin: Plugin): boolean;
}
export {};
}
type Filter = (session: Session) => boolean;
type PartialSeletor = (...values: T[]) => Context;
interface Selector extends PartialSeletor {
except?: PartialSeletor;
}
export interface Context extends Context.Delegates {
}
export class Context {
filter: Filter;
app?: App;
private _plugin;
static readonly middleware: unique symbol;
static readonly current: unique symbol;
protected _bots: Bot[] & Record;
protected constructor(filter: Filter, app?: App, _plugin?: Plugin);
private static inspect;
[inspect.custom](): string;
private createSelector;
get user(): Selector;
get self(): Selector;
get group(): Selector;
get channel(): Selector;
get platform(): Selector;
get private(): Selector;
get bots(): Bot[] & Record>;
logger(name: string): Logger;
select(key: K, ...values: Session[K][]): Context;
unselect(key: K, ...values: Session[K][]): Context;
all(): Context;
union(arg: Filter | Context): Context;
intersect(arg: Filter | Context): Context;
except(arg: Filter | Context): Context;
match(session?: Session): boolean;
get state(): Plugin.State;
addSideEffect(state?: Plugin.State): void;
private teleport;
with(deps: D, callback: Plugin.Teleporter): this;
plugin(plugin: T, options?: boolean | Plugin.Config): this;
dispose(plugin?: Plugin): Promise;
parallel(name: K, ...args: Parameters): Promise;
parallel(session: Session, name: K, ...args: Parameters): Promise;
emit(name: K, ...args: Parameters): void;
emit(session: Session, name: K, ...args: Parameters): void;
waterfall(name: K, ...args: Parameters): Promisify>;
waterfall(session: Session, name: K, ...args: Parameters