diff --git a/types/tmi.js/index.d.ts b/types/tmi.js/index.d.ts new file mode 100644 index 0000000000..dab0ce635b --- /dev/null +++ b/types/tmi.js/index.d.ts @@ -0,0 +1,299 @@ +// Type definitions for tmi.js v1.3.1 +// Project: https://docs.tmijs.org/v1.3.0/index.html +// Definitions by: William Papsco +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// Twitch IRC docs: https://dev.twitch.tv/docs/irc/ +// Last updated: 2019/2/27 + +declare module 'tmi.js' { + import { StrictEventEmitter } from "strict-event-emitter-types" + + interface Actions { + action(channel: string, message: string): Promise<[string]>, + ban(channel: string, username: string, reason?: string): Promise<[string, string, string]>, + clear(channel: string): Promise<[string]>, + color(color: string): Promise<[string]>, + commercial(channel: string, seconds: number): Promise<[string, number]>, + connect(): Promise<[string, number]>, + disconnect(): Promise<[string, number]>, + emoteonly(channel: string): Promise<[string]>, + emoteonlyoff(channel: string): Promise<[string]>, + followersonly(channel: string, length?: number): Promise<[string, number]>, + followersonlyoff(channel: string): Promise<[string]>, + host(channel: string, target: string): Promise<[string, string]>, + join(channel: string): Promise<[string]>, + mod(channel: string, username: string): Promise<[string, string]>, + mods(channel: string): Promise, + part(channel: string): Promise<[string]>, + ping(): Promise<[number]>, + r9kbeta(channel: string): Promise<[string]>, + r9kbetaoff(channel: string): Promise<[string]>, + raw(message: string): Promise<[string]>, + say(channel: string, message: string): Promise<[string]>, + slow(channel: string, length?: number): Promise<[string]>, + slowoff(channel: string): Promise<[string]>, + subscribers(channel: string): Promise<[string]>, + subscribersoff(channel: string): Promise<[string]>, + timeout(channel: string, username: string, length?: number, reason?: string): Promise<[string, string, number, string]> + unban(channel: string, username: string): Promise<[string, string]>, + unhost(channel: string): Promise<[string]>, + unmod(channel: string, username: string): Promise<[string, string]>, + whisper(username: string, message: string): Promise<[string, string]> + } + + interface Events { + action(channel: string, userstate: ChatUserstate, message: string, self: boolean): void + ban(channel: string, username: string, reason: string): void, + chat(channel: string, userstate: ChatUserstate, message: string, self: boolean): void, + cheer(channel: string, userstate: ChatUserstate, message: string): void, + clearchat(channel: string): void, + connected(address: string, port: number): void, + connecting(address: string, port: number): void, + disconnected(reason: string): void, + emoteonly(channel: string, enabled: boolean): void, + emotesets(sets: string, obj: EmoteObj): void, + followersonly(channel: string, enabled: boolean, length: number): void, + hosted(channel: string, username: string, viewers: number, autohost: boolean): void, + hosting(channel: string, target: string, viewers: number): void, + join(channel: string, username: string, self: boolean): void, + logon(): void, + message(channel: string, userstate: ChatUserstate, message: string, self: boolean): void, + mod(channel: string, username: string): void, + mods(channel: string, mods: string[]): void, + notice(channel: string, msgid: MsgID, message: string): void, + part(channel: string, username: string, self: boolean): void, + ping(): void, + pong(latency: number): void, + r9kbeta(channel: string, enabled: boolean): void, + reconnect(): void, + resub(channel: string, username: string, months: number, message: string, userstate: SubUserstate, methods: ResubMethod): void, + roomstate(channel: string, state: RoomState): void, + serverchange(channel: string): void, + slowmode(channel: string, enabled: boolean, length: number): void, + subscribers(channel: string, enabled: boolean): void, + subscription(channel: string, username: string, method: ResubMethod, message: string, userstate: SubUserstate): void, + timeout(channel: string, username: string, reason: string, duration: number): void, + unhost(channel: string, viewers: number): void, + unmod(channel: string, username: string): void, + whisper(from: string, userstate: ChatUserstate, message: string, self: boolean): void + } + + interface ClientBase { + getChannels(): string[], + getOptions(): Options, + getUsername(): string, + isMod(channel: string, username: string): boolean, + readyState(): "CONNECTING" | "OPEN" | "CLOSING" | "CLOSED", + on(event: any, listener: any): Client, + addListener(event: any, listener: any): Client, + removeListener(event: any, listener: any): Client, + removeAllListeners

(event?: P): Client, + setMaxListeners(n: number): Client, + emits(events: (keyof Events)[], values: any[][]): void, //wish this could work better but either I'm just not smart enough or it's not possible + emit: (event: any) => boolean, + once(event: any, listener: any): Client, + listenerCount

(event: P): number, + } + + interface Badges { + admin?: string, + bits?: string, + broadcaster?: string, + global_mod?: string, + moderator?: string, + subscriber?: string, + staff?: string, + turbo?: string, + premium?: string + } + + interface CommonUserstate { + badges?: Badges, + color?: string, + "display-name"?: string, + emotes?: { [emoteid: string]: string[] }, + id?: string, + mod?: boolean, + turbo?: boolean, + 'emotes-raw'?: string, + 'badges-raw'?: string, + "room-id"?: string, + subscriber?: boolean, + 'user-type'?: "" | "mod" | "global_mod" | "admin" | "staff", + "user-id"?: string, + "tmi-sent-ts"?: string, + flags?: string, + } + + interface UserNoticeState extends CommonUserstate { + login?: string, + message?: string, + "system-msg"?: string, + } + + interface CommonSubUserstate extends UserNoticeState { + "msg-param-sub-plan"?: ResubMethod, + "msg-param-sub-plan-name"?: string + } + + interface ChatUserstate extends CommonUserstate { + 'message-type'?: "chat" | "action" | "whisper", + username?: string, + bits?: string, + } + + interface SubUserstate extends CommonSubUserstate { + 'message-type'?: "sub" | "resub", + "msg-param-cumulative-months"?: string | boolean, + "msg-param-should-share-streak"?: boolean, + "msg-param-streak-months"?: string | boolean, + } + + interface SubGiftUserstate extends CommonSubUserstate { + 'message-type'?: "subgift" | "anonsubgift", + "msg-param-recipient-display-name"?: string, + "msg-param-recipient-id"?: string, + "msg-param-recipient-user-name"?: string, + } + + interface RaidUserstate extends UserNoticeState { + "message-type"?: "raid" + "msg-param-displayName"?: string, + "msg-param-login"?: string, + "msg-param-viewerCount"?: string, + } + + interface RitualUserstate extends UserNoticeState { + "message-type"?: "ritual" + "msg-param-ritual-name"?: "new_chatter" + } + + type Userstate = ChatUserstate | SubGiftUserstate | SubUserstate | RaidUserstate | RitualUserstate + + interface EmoteObj { + [id: string]: [{ + code: string, + id: number + }] + } + + type MsgID = "already_banned" | + "already_emote_only_on" | + "already_emote_only_off" | + "already_subs_on" | + "already_subs_off" | + "bad_ban_admin" | + "bad_ban_broadcaster" | + "bad_ban_global_mod" | + "bad_ban_self" | + "bad_ban_staff" | + "bad_commercial_error" | + "bad_host_hosting" | + "bad_host_rate_exceeded" | + "bad_mod_mod" | + "bad_mod_banned" | + "bad_timeout_admin" | + "bad_timeout_global_mod" | + "bad_timeout_self" | + "bad_timeout_staff" | + "bad_unban_no_ban" | + "bad_unmod_mod" | + "ban_success" | + "cmds_available" | + "color_changed" | + "commercial_success" | + "emote_only_on" | + "emote_only_off" | + "hosts_remaining" | + "host_target_went_offline" | + "mod_success" | + "msg_banned" | + "msg_censored_broadcaster" | + "msg_channel_suspended" | + "msg_duplicate" | + "msg_emoteonly" | + "msg_ratelimit" | + "msg_subsonly" | + "msg_timedout" | + "msg_verified_email" | + "no_help" | + "no_permission" | + "not_hosting" | + "timeout_success" | + "unban_success" | + "unmod_success" | + "unrecognized_cmd" | + "usage_ban" | + "usage_clear" | + "usage_color" | + "usage_commercial" | + "usage_disconnect" | + "usage_emote_only_on" | + "usage_emote_only_off" | + "usage_help" | + "usage_host" | + "usage_me" | + "usage_mod" | + "usage_mods" | + "usage_r9k_on" | + "usage_r9k_off" | + "usage_slow_on" | + "usage_slow_off" | + "usage_subs_on" | + "usage_subs_off" | + "usage_timeout" | + "usage_unban" | + "usage_unhost" | + "usage_unmod" | + "whisper_invalid_self" | + "whisper_limit_per_min" | + "whisper_limit_per_sec" | + "whisper_restricted_recipient" + + type ResubMethod = "Prime" | "1000" | "2000" | "3000" + + interface RoomState { + "broadcaster-lang"?: string, + "emote-only"?: boolean, + "followers-only"?: string | boolean, + "r9k"?: boolean, + "rituals"?: boolean, + "room-id"?: string + "slow"?: string | boolean, + "subs-only"?: boolean, + "channel"?: string + } + + type Client = StrictEventEmitter & Actions + + interface Options { + options?: { + clientId?: string, + debug?: boolean + }, + connection?: { + server?: string, + port?: number, + reconnect?: boolean, + maxReconnectAttempts?: number, + maxReconnectInverval?: number, + reconnectDecay?: number, + reconnectInterval?: number, + secure?: boolean, + timeout?: number + }, + identity?: { + username?: string, + password?: string + }, + channels?: string[], + logger?: { + info?: (message: string) => any, + warn?: (message: string) => any, + error?: (message: string) => any + } + } + + export function client(opts: Options): Client + export function Client(opts: Options): Client +} \ No newline at end of file diff --git a/types/tmi.js/package.json b/types/tmi.js/package.json new file mode 100644 index 0000000000..dd5c6e4363 --- /dev/null +++ b/types/tmi.js/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "dependencies": { + "strict-event-emitter-types": "^2.0.0" + } +} \ No newline at end of file diff --git a/types/tmi.js/tmijs-tests.ts b/types/tmi.js/tmijs-tests.ts new file mode 100644 index 0000000000..e80ad43915 --- /dev/null +++ b/types/tmi.js/tmijs-tests.ts @@ -0,0 +1,110 @@ +import * as tmi from "tmi.js" + +const options: tmi.Options = { + channels: ['#channel1', '#channel2'], + connection: { + maxReconnectAttempts: 2, + maxReconnectInverval: 10, + port: 100, + reconnect: true, + reconnectDecay: 20, + reconnectInterval: 10, + secure: true, + timeout: 20 + }, + identity: { + password: "oauth:xxxOAuthIDHerexxx", + username: "yourusernamehere" + }, + logger: { + warn: console.log, + error: console.log, + info: console.log, + }, + options: { + clientId: "xxxapiidherexxx", + debug: true + } +} + +const client: tmi.Client = tmi.Client(options) + +client.connect().then(() => { + client.on("subscription", (channel: string, username: string, method: tmi.ResubMethod, msg: string, userstate: tmi.SubUserstate) => { + client.say(channel, "Thank you to " + userstate["display-name"] + "for subscribing!") + client.ping() + client.r9kbeta(channel) + client.r9kbetaoff(channel) + client.raw("xxxRawIRCHere") + switch (client.readyState()) { + case "CLOSED": + case "CLOSING": + case "CONNECTING": + case "OPEN": + break + } + client.slow(channel, 5) + client.slowoff(channel) + client.subscribers(channel) + client.subscribersoff(channel) + client.timeout(channel, username, 600, "timeoutreason") + client.ban(channel, username, "reason") + client.unban(channel, username) + client.host(channel, "tohost") + client.unhost(channel) + client.mod(channel, username) + client.unmod(channel, username) + client.whisper(username, "whisper") + client.part(channel) + switch (method) { + case "1000": + case "2000": + case "3000": + case "Prime": + break + } + const { badges, color, emotes, flags, id, login, message, mod, subscriber, turbo } = userstate + if (emotes) { + emotes.test.forEach(element => { + console.log(element) + }) + } + if (badges) { + const { admin, turbo, subscriber, bits, broadcaster, global_mod, moderator, premium, staff } = badges + } + userstate["display-name"] + userstate["emotes-raw"] + userstate["badges-raw"] + userstate["message-type"] + userstate["msg-param-cumulative-months"] + userstate["msg-param-should-share-streak"] + userstate["msg-param-streak-months"] + userstate["msg-param-sub-plan"] + userstate["msg-param-sub-plan-name"] + userstate["room-id"] + userstate["system-msg"] + userstate["tmi-sent-ts"] + userstate["user-id"] + userstate["user-type"] + }).on("roomstate", (chnl: string, roomstate: tmi.RoomState) => { + const { channel, r9k, rituals, slow } = roomstate + roomstate["broadcaster-lang"] + roomstate["emote-only"] + roomstate["followers-only"] + roomstate["room-id"] + roomstate["subs-only"] + }).once("chat", (channel: string, userstate: tmi.ChatUserstate, message: string, self: boolean) => { + const { badges, bits, color, emotes, flags, id, mod, subscriber, turbo, username } = userstate + userstate["badges-raw"] + userstate["display-name"] + userstate["emotes-raw"] + userstate["message-type"] + userstate["room-id"] + userstate["tmi-sent-ts"] + userstate["user-id"] + userstate["user-type"] + }).once("emotesets", (sets, emotes) => { + emotes.test[0].code + emotes.test[0].id + }) +}) \ No newline at end of file diff --git a/types/tmi.js/tsconfig.json b/types/tmi.js/tsconfig.json new file mode 100644 index 0000000000..da2062714c --- /dev/null +++ b/types/tmi.js/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + /* Basic Options */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + "strictNullChecks": true, /* Enable strict null checks. */ + "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + } +} \ No newline at end of file diff --git a/types/tmi.js/tslint.json b/types/tmi.js/tslint.json new file mode 100644 index 0000000000..2750cc0197 --- /dev/null +++ b/types/tmi.js/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" } \ No newline at end of file