/
client.ts
62 lines (57 loc) · 1.95 KB
/
client.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { type AuthProvider, getValidTokenFromProviderForIntent } from '@twurple/auth';
import { Client as BaseClient, type Options as BaseOptions } from 'tmi.js';
/**
* The tmi.js options, with the auth provider replacing the identity option.
*
* @inheritDoc
*/
export interface Options extends Omit<BaseOptions, 'identity'> {
/**
* An authentication provider that supplies tokens to the client.
*
* For more information, see the {@link AuthProvider} documentation.
*/
authProvider: AuthProvider;
/**
* The intents to use with the auth provider. Will always additionally check the "chat" intent last.
*/
authIntents?: string[];
}
/**
* An extension of the tmi.js client which extends it with {@link AuthProvider} integration.
*/
export class DecoratedClient extends BaseClient {
/**
* Creates a new tmi.js client which utilizes the given {@link AuthProvider} instance.
*
* @param opts The tmi.js options, with the auth provider replacing the identity option.
*/
constructor(opts: Options) {
const { authProvider, authIntents = [], ...tmiOpts } = opts;
super({
...tmiOpts,
identity: {
// need this because we can't get a username dynamically, but need something to not default to justinfan
username: 'dummy',
password: async () => {
let lastTokenError: Error | undefined = undefined;
for (const intent of [...authIntents, 'chat']) {
try {
const { accessToken } = await getValidTokenFromProviderForIntent(authProvider, intent, [
'chat:read',
'chat:edit',
]);
return accessToken.accessToken;
} catch (e) {
lastTokenError = e as Error;
}
}
throw new Error('Could not find a token for any given intent', { cause: lastTokenError });
},
},
});
}
}
export const Client = DecoratedClient as typeof DecoratedClient & ((opts: Options) => DecoratedClient);
// eslint-disable-next-line @typescript-eslint/no-redeclare
export type Client = DecoratedClient;