@@ -16,20 +16,26 @@ export interface Message {
16
16
17
17
interface ParserOptions {
18
18
supportsMessageTags : boolean ;
19
+ /**
20
+ * @param stripColors If true, strip IRC colors.
21
+ */
19
22
stripColors : boolean ;
20
23
}
21
24
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 = / ^ ( [ ^ ] + ) * / ;
23
29
24
- const IRC_LINE_MATCH_WITH_TAGS = / ^ (?< tags > @ [ ^ ] + ) ? : (?< prefix > [ ^ ] + ) + (?< content > .+ ) / ;
25
30
26
31
/**
27
32
* parseMessage(line, stripColors)
28
33
*
29
34
* takes a raw "line" from the IRC server and turns it into an object with
30
35
* useful keys
31
36
* @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.
33
39
* @return A parsed message object.
34
40
*/
35
41
export function parseMessage ( line : string , opts : Partial < ParserOptions > | boolean = false ) : Message {
@@ -49,40 +55,42 @@ export function parseMessage(line: string, opts: Partial<ParserOptions>|boolean
49
55
}
50
56
51
57
// 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 - z A - Z 0 - 9 \[ \] \\ ` ^ { } | - ] * ) ( ! ( [ ^ @ ] + ) @ ( .* ) ) ? $ / ) ;
57
68
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 - z A - Z 0 - 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
+ }
64
77
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
+ }
69
87
}
70
88
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
82
90
}
83
91
84
92
// Parse command
85
- match = content . match ( / ^ ( [ ^ ] + ) * / ) ;
93
+ match = content . match ( IRC_COMMAND_REGEX ) ;
86
94
87
95
if ( ! match ?. [ 1 ] ) {
88
96
throw Error ( 'Could not parse command' ) ;
0 commit comments