Skip to content

Commit 8822d9f

Browse files
committed
Use capability negotiations
1 parent 4118413 commit 8822d9f

File tree

3 files changed

+43
-31
lines changed

3 files changed

+43
-31
lines changed

src/capabilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ export class IrcCapabilities extends (EventEmitter as new () => IrcCapabilitiesE
6767
return this.userCapabilites.ready;
6868
}
6969

70+
public isSupported(capability: string) {
71+
return this.userCapabilites.caps.has(capability);
72+
}
73+
7074
public get supportsSasl() {
7175
if (!this.serverCapabilites.ready) {
7276
throw Error('Server response has not arrived yet');

src/irc.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,7 @@ export class Client extends (EventEmitter as unknown as new () => TypedEmitter<C
13641364
}
13651365
const message = parseMessage(line, {
13661366
stripColors: this.opt.stripColors,
1367-
supportsMessageTags: true,
1367+
supportsMessageTags: this.state.capabilities.isSupported('message-tags'),
13681368
});
13691369
try {
13701370
this.emit('raw', message);

src/parse_message.ts

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,26 @@ export interface Message {
1616

1717
interface ParserOptions {
1818
supportsMessageTags: boolean;
19+
/**
20+
* @param stripColors If true, strip IRC colors.
21+
*/
1922
stripColors: boolean;
2023
}
2124

22-
const IRC_LINE_MATCH = /^:(?<prefix>[^ ]+) +(?<content>.+)/;
25+
const IRC_LINE_MATCH_REGEX = /^:(?<prefix>[^ ]+) +(?<content>.+)/;
26+
const IRC_LINE_MATCH_WITH_TAGS_REGEX = /^(?<tags>@[^ ]+ )?:(?<prefix>[^ ]+) +(?<content>.+)/;
27+
28+
const IRC_COMMAND_REGEX = /^([^ ]+) */;
2329

24-
const IRC_LINE_MATCH_WITH_TAGS = /^(?<tags>@[^ ]+ )?:(?<prefix>[^ ]+) +(?<content>.+)/;
2530

2631
/**
2732
* parseMessage(line, stripColors)
2833
*
2934
* takes a raw "line" from the IRC server and turns it into an object with
3035
* useful keys
3136
* @param line Raw message from IRC server.
32-
* @param stripColors If true, strip IRC colors.
37+
* @param opts Additional options for parsing.
38+
* For legacy reasons this can be a boolean which maps to the `stripColors` propety.
3339
* @return A parsed message object.
3440
*/
3541
export function parseMessage(line: string, opts: Partial<ParserOptions>|boolean = false): Message {
@@ -49,40 +55,42 @@ export function parseMessage(line: string, opts: Partial<ParserOptions>|boolean
4955
}
5056

5157
// Parse prefix
52-
let match = line.match(opts.supportsMessageTags ? IRC_LINE_MATCH_WITH_TAGS : IRC_LINE_MATCH);
53-
if (!match) {
54-
// Unparseable format.
55-
throw Error(`Invalid format, could not parse message '${line}''`);
56-
}
58+
let match = line.match(opts.supportsMessageTags ? IRC_LINE_MATCH_WITH_TAGS_REGEX : IRC_LINE_MATCH_REGEX);
59+
let content = line;
60+
if (match) {
61+
const { prefix, tags, content: ctnt } = match.groups || {};
62+
content = ctnt;
63+
if (!prefix) {
64+
throw Error('No prefix on message');
65+
}
66+
message.prefix = prefix;
67+
const prefixMatch = message.prefix.match(/^([_a-zA-Z0-9\[\]\\`^{}|-]*)(!([^@]+)@(.*))?$/);
5768

58-
const { prefix, tags, content } = match.groups || {};
59-
if (!prefix) {
60-
throw Error('No prefix on message');
61-
}
62-
message.prefix = prefix;
63-
const prefixMatch = message.prefix.match(/^([_a-zA-Z0-9\[\]\\`^{}|-]*)(!([^@]+)@(.*))?$/);
69+
if (prefixMatch) {
70+
message.nick = prefixMatch[1];
71+
message.user = prefixMatch[3];
72+
message.host = prefixMatch[4];
73+
}
74+
else {
75+
message.server = message.prefix;
76+
}
6477

65-
if (prefixMatch) {
66-
message.nick = prefixMatch[1];
67-
message.user = prefixMatch[3];
68-
message.host = prefixMatch[4];
78+
// Parse the message tags
79+
if (tags) {
80+
message.tags = new Map(
81+
// Strip @
82+
tags.substring(1).trim().split(';').map(
83+
(tag) => tag.split('=', 2)
84+
) as Array<[string, string|undefined]>
85+
);
86+
}
6987
}
7088
else {
71-
message.server = message.prefix;
72-
}
73-
74-
// Parse the message tags
75-
if (tags) {
76-
message.tags = new Map(
77-
// Strip @
78-
tags.substring(1).trim().split(';').map(
79-
(tag) => tag.split('=', 2)
80-
) as Array<[string, string|undefined]>
81-
);
89+
// Still allowed, it might just be a command
8290
}
8391

8492
// Parse command
85-
match = content.match(/^([^ ]+) */);
93+
match = content.match(IRC_COMMAND_REGEX);
8694

8795
if (!match?.[1]) {
8896
throw Error('Could not parse command');

0 commit comments

Comments
 (0)