@sockethub/platform-irc 4.0.0-alpha.12 → 4.0.0-alpha.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +233 -5
- package/dist/index.d.ts +136 -0
- package/dist/index.js +501 -250
- package/dist/index.js.map +15 -16
- package/dist/schema.d.ts +324 -0
- package/{src/types.ts → dist/types.d.ts} +3 -1
- package/package.json +9 -9
- package/src/ambient.d.ts +0 -35
- package/src/index.test.data.ts +0 -68
- package/src/index.test.ts +0 -294
- package/src/index.ts +0 -783
- package/src/octal-hack.d.ts +0 -2
- package/src/octal-hack.js +0 -4
- package/src/schema.ts +0 -70
package/README.md
CHANGED
|
@@ -18,6 +18,10 @@ messages.
|
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
20
20
|
|
|
21
|
+
IRC room targets use `channel@server` in `target.id` (for example
|
|
22
|
+
`general@irc.libera.chat`). When you include `target.name`, use the channel
|
|
23
|
+
name as it appears on IRC (for example `#general`).
|
|
24
|
+
|
|
21
25
|
### Send Message Example
|
|
22
26
|
|
|
23
27
|
```json
|
|
@@ -33,8 +37,9 @@ messages.
|
|
|
33
37
|
"type": "person"
|
|
34
38
|
},
|
|
35
39
|
"target": {
|
|
36
|
-
"id": "
|
|
37
|
-
"type": "room"
|
|
40
|
+
"id": "general@irc.libera.chat",
|
|
41
|
+
"type": "room",
|
|
42
|
+
"name": "#general"
|
|
38
43
|
},
|
|
39
44
|
"object": {
|
|
40
45
|
"type": "message",
|
|
@@ -58,8 +63,9 @@ messages.
|
|
|
58
63
|
"type": "person"
|
|
59
64
|
},
|
|
60
65
|
"target": {
|
|
61
|
-
"id": "
|
|
62
|
-
"type": "room"
|
|
66
|
+
"id": "general@irc.libera.chat",
|
|
67
|
+
"type": "room",
|
|
68
|
+
"name": "#general"
|
|
63
69
|
}
|
|
64
70
|
}
|
|
65
71
|
```
|
|
@@ -89,6 +95,227 @@ messages.
|
|
|
89
95
|
}
|
|
90
96
|
```
|
|
91
97
|
|
|
98
|
+
### Update Topic Example
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"type": "update",
|
|
103
|
+
"@context": [
|
|
104
|
+
"https://www.w3.org/ns/activitystreams",
|
|
105
|
+
"https://sockethub.org/ns/context/v1.jsonld",
|
|
106
|
+
"https://sockethub.org/ns/context/platform/irc/v1.jsonld"
|
|
107
|
+
],
|
|
108
|
+
"actor": {
|
|
109
|
+
"id": "mynick@irc.libera.chat",
|
|
110
|
+
"type": "person"
|
|
111
|
+
},
|
|
112
|
+
"target": {
|
|
113
|
+
"id": "general@irc.libera.chat",
|
|
114
|
+
"type": "room",
|
|
115
|
+
"name": "#general"
|
|
116
|
+
},
|
|
117
|
+
"object": {
|
|
118
|
+
"type": "topic",
|
|
119
|
+
"content": "New channel topic"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Update Nickname Example
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"type": "update",
|
|
129
|
+
"@context": [
|
|
130
|
+
"https://www.w3.org/ns/activitystreams",
|
|
131
|
+
"https://sockethub.org/ns/context/v1.jsonld",
|
|
132
|
+
"https://sockethub.org/ns/context/platform/irc/v1.jsonld"
|
|
133
|
+
],
|
|
134
|
+
"actor": {
|
|
135
|
+
"id": "mynick@irc.libera.chat",
|
|
136
|
+
"type": "person"
|
|
137
|
+
},
|
|
138
|
+
"target": {
|
|
139
|
+
"id": "newnick@irc.libera.chat",
|
|
140
|
+
"type": "person"
|
|
141
|
+
},
|
|
142
|
+
"object": {
|
|
143
|
+
"type": "address"
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Query Attendance Example
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"type": "query",
|
|
153
|
+
"@context": [
|
|
154
|
+
"https://www.w3.org/ns/activitystreams",
|
|
155
|
+
"https://sockethub.org/ns/context/v1.jsonld",
|
|
156
|
+
"https://sockethub.org/ns/context/platform/irc/v1.jsonld"
|
|
157
|
+
],
|
|
158
|
+
"actor": {
|
|
159
|
+
"id": "mynick@irc.libera.chat",
|
|
160
|
+
"type": "person"
|
|
161
|
+
},
|
|
162
|
+
"target": {
|
|
163
|
+
"id": "general@irc.libera.chat",
|
|
164
|
+
"type": "room",
|
|
165
|
+
"name": "#general"
|
|
166
|
+
},
|
|
167
|
+
"object": {
|
|
168
|
+
"type": "attendance"
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Query Attendance Response Example
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"type": "query",
|
|
178
|
+
"@context": [
|
|
179
|
+
"https://www.w3.org/ns/activitystreams",
|
|
180
|
+
"https://sockethub.org/ns/context/v1.jsonld",
|
|
181
|
+
"https://sockethub.org/ns/context/platform/irc/v1.jsonld"
|
|
182
|
+
],
|
|
183
|
+
"actor": {
|
|
184
|
+
"id": "general@irc.libera.chat",
|
|
185
|
+
"type": "room",
|
|
186
|
+
"name": "#general"
|
|
187
|
+
},
|
|
188
|
+
"target": {},
|
|
189
|
+
"object": {
|
|
190
|
+
"type": "attendance",
|
|
191
|
+
"members": ["alice", "bob", "carol"]
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Disconnect Example
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"type": "disconnect",
|
|
201
|
+
"@context": [
|
|
202
|
+
"https://www.w3.org/ns/activitystreams",
|
|
203
|
+
"https://sockethub.org/ns/context/v1.jsonld",
|
|
204
|
+
"https://sockethub.org/ns/context/platform/irc/v1.jsonld"
|
|
205
|
+
],
|
|
206
|
+
"actor": {
|
|
207
|
+
"id": "mynick@irc.libera.chat",
|
|
208
|
+
"type": "person"
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Authentication
|
|
214
|
+
|
|
215
|
+
Authenticated connections use SASL. Two mechanisms are supported:
|
|
216
|
+
|
|
217
|
+
* **`PLAIN`** — sends a username and secret via SASL PLAIN. This is the
|
|
218
|
+
default mechanism, and is supported by most IRC networks (Libera.Chat,
|
|
219
|
+
OFTC, etc.). Both `password` and `token` use PLAIN by default. Use
|
|
220
|
+
`token` for personal access tokens (e.g. Libera.Chat NickServ tokens)
|
|
221
|
+
to avoid storing primary account passwords.
|
|
222
|
+
* **`OAUTHBEARER`** — sends an OAuth 2.0 access token instead of a password
|
|
223
|
+
([RFC 7628](https://datatracker.ietf.org/doc/html/rfc7628)). Requires
|
|
224
|
+
`saslMechanism: "OAUTHBEARER"` to be set explicitly. Adoption on
|
|
225
|
+
public IRC networks is still limited; the main deployment is SourceHut's
|
|
226
|
+
`chat.sr.ht` (via the [soju](https://soju.im/) bouncer). Major networks
|
|
227
|
+
such as Libera.Chat, OFTC, and Hackint do not currently advertise
|
|
228
|
+
OAUTHBEARER. See emersion's [IRC × OAuth 2.0](https://emersion.fr/blog/2022/irc-and-oauth2/)
|
|
229
|
+
writeup for background. How to obtain the token is provider-specific and
|
|
230
|
+
outside the scope of this module.
|
|
231
|
+
|
|
232
|
+
`password` and `token` are mutually exclusive. Both default to SASL PLAIN;
|
|
233
|
+
set `saslMechanism: "OAUTHBEARER"` explicitly for OAuth 2.0 bearer tokens.
|
|
234
|
+
Secure connections validate the IRC server's TLS certificate by default. The
|
|
235
|
+
optional `allowInvalidCert` field defaults to `false`; when set to `true`, it
|
|
236
|
+
disables TLS certificate validation for secure connections. Use this
|
|
237
|
+
security-relevant opt-out only for trusted self-signed IRC networks.
|
|
238
|
+
|
|
239
|
+
### Credentials with password (SASL PLAIN)
|
|
240
|
+
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"type": "credentials",
|
|
244
|
+
"@context": [
|
|
245
|
+
"https://www.w3.org/ns/activitystreams",
|
|
246
|
+
"https://sockethub.org/ns/context/v1.jsonld",
|
|
247
|
+
"https://sockethub.org/ns/context/platform/irc/v1.jsonld"
|
|
248
|
+
],
|
|
249
|
+
"actor": {
|
|
250
|
+
"id": "mynick@irc.libera.chat",
|
|
251
|
+
"type": "person"
|
|
252
|
+
},
|
|
253
|
+
"object": {
|
|
254
|
+
"type": "credentials",
|
|
255
|
+
"nick": "mynick",
|
|
256
|
+
"server": "irc.libera.chat",
|
|
257
|
+
"password": "secret",
|
|
258
|
+
"port": 6697,
|
|
259
|
+
"secure": true
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Credentials with personal access token (SASL PLAIN)
|
|
265
|
+
|
|
266
|
+
Networks like Libera.Chat accept NickServ personal access tokens via
|
|
267
|
+
SASL PLAIN. Use the `token` field instead of `password` to make the
|
|
268
|
+
distinction clear:
|
|
269
|
+
|
|
270
|
+
```json
|
|
271
|
+
{
|
|
272
|
+
"type": "credentials",
|
|
273
|
+
"@context": [
|
|
274
|
+
"https://www.w3.org/ns/activitystreams",
|
|
275
|
+
"https://sockethub.org/ns/context/v1.jsonld",
|
|
276
|
+
"https://sockethub.org/ns/context/platform/irc/v1.jsonld"
|
|
277
|
+
],
|
|
278
|
+
"actor": {
|
|
279
|
+
"id": "mynick@irc.libera.chat",
|
|
280
|
+
"type": "person"
|
|
281
|
+
},
|
|
282
|
+
"object": {
|
|
283
|
+
"type": "credentials",
|
|
284
|
+
"nick": "mynick",
|
|
285
|
+
"server": "irc.libera.chat",
|
|
286
|
+
"token": "my-personal-access-token",
|
|
287
|
+
"port": 6697,
|
|
288
|
+
"secure": true
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Credentials with OAuth token (SASL OAUTHBEARER)
|
|
294
|
+
|
|
295
|
+
```json
|
|
296
|
+
{
|
|
297
|
+
"type": "credentials",
|
|
298
|
+
"@context": [
|
|
299
|
+
"https://www.w3.org/ns/activitystreams",
|
|
300
|
+
"https://sockethub.org/ns/context/v1.jsonld",
|
|
301
|
+
"https://sockethub.org/ns/context/platform/irc/v1.jsonld"
|
|
302
|
+
],
|
|
303
|
+
"actor": {
|
|
304
|
+
"id": "mynick@chat.sr.ht",
|
|
305
|
+
"type": "person"
|
|
306
|
+
},
|
|
307
|
+
"object": {
|
|
308
|
+
"type": "credentials",
|
|
309
|
+
"nick": "mynick",
|
|
310
|
+
"server": "chat.sr.ht",
|
|
311
|
+
"token": "oauth-access-token",
|
|
312
|
+
"saslMechanism": "OAUTHBEARER",
|
|
313
|
+
"port": 6697,
|
|
314
|
+
"secure": true
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
92
319
|
## Features
|
|
93
320
|
|
|
94
321
|
* **Channel communication**: Join and participate in IRC channels
|
|
@@ -106,4 +333,5 @@ messages.
|
|
|
106
333
|
|
|
107
334
|
## API
|
|
108
335
|
|
|
109
|
-
|
|
336
|
+
API reference docs are generated from the source JSDoc and are not committed to this repository.
|
|
337
|
+
Run `bun run doc` in this package to generate them locally.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This is a platform for Sockethub implementing IRC functionality.
|
|
3
|
+
*
|
|
4
|
+
* Developed by Nick Jennings (https://github.com/silverbucket)
|
|
5
|
+
*
|
|
6
|
+
* Sockethub is licensed under the LGPLv3.
|
|
7
|
+
* See the LICENSE file for details.
|
|
8
|
+
*
|
|
9
|
+
* The latest version of this module can be found here:
|
|
10
|
+
* git://github.com/sockethub/sockethub.git
|
|
11
|
+
*
|
|
12
|
+
* For more information about Sockethub visit http://sockethub.org/.
|
|
13
|
+
*
|
|
14
|
+
* This program is distributed in the hope that it will be useful,
|
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
17
|
+
*/
|
|
18
|
+
import type { ActivityStream, PersistentPlatformConfig, PersistentPlatformInterface, PlatformCallback, PlatformSchemaStruct, PlatformSession } from "@sockethub/schemas";
|
|
19
|
+
import { type IrcSocketInstance } from "irc-socket-sasl";
|
|
20
|
+
import type { PlatformIrcCredentialsObject } from "./types.js";
|
|
21
|
+
export type { IrcSocketInstance } from "irc-socket-sasl";
|
|
22
|
+
export type { PlatformIrcCredentialsObject } from "./types.js";
|
|
23
|
+
export declare function flattenConnectOptions(options: Record<string, unknown>): Record<string, unknown>;
|
|
24
|
+
export type GetClientCallback = (err: string | null, client?: IrcSocketInstance) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Handles all actions related to communication via the IRC protocol.
|
|
27
|
+
*/
|
|
28
|
+
export declare class IRC implements PersistentPlatformInterface {
|
|
29
|
+
private readonly log;
|
|
30
|
+
credentialsHash: string | undefined;
|
|
31
|
+
config: PersistentPlatformConfig;
|
|
32
|
+
private readonly updateActor;
|
|
33
|
+
private readonly sendToClient;
|
|
34
|
+
private irc2as;
|
|
35
|
+
private forceDisconnect;
|
|
36
|
+
private clientConnecting;
|
|
37
|
+
private initialized;
|
|
38
|
+
private client?;
|
|
39
|
+
private jobQueue;
|
|
40
|
+
private channels;
|
|
41
|
+
private handledActors;
|
|
42
|
+
constructor(session: PlatformSession);
|
|
43
|
+
/**
|
|
44
|
+
* JSON schema defining the types this platform accepts.
|
|
45
|
+
*
|
|
46
|
+
* `password` and `token` are mutually exclusive. Both default to SASL
|
|
47
|
+
* PLAIN; set `saslMechanism: 'OAUTHBEARER'` explicitly for OAuth 2.0
|
|
48
|
+
* bearer tokens (RFC 7628). See the package README for canonical
|
|
49
|
+
* credentials payload examples.
|
|
50
|
+
*/
|
|
51
|
+
get schema(): PlatformSchemaStruct;
|
|
52
|
+
/**
|
|
53
|
+
* Returns whether the platform is ready to handle jobs.
|
|
54
|
+
* For IRC, this means we have successfully connected to the server.
|
|
55
|
+
*/
|
|
56
|
+
isInitialized(): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Function: connect
|
|
59
|
+
*
|
|
60
|
+
* Connect to an IRC server.
|
|
61
|
+
*
|
|
62
|
+
* @param {object} job activity streams object
|
|
63
|
+
* @param {object} credentials credentials object
|
|
64
|
+
* @param {object} done callback when job is done
|
|
65
|
+
*/
|
|
66
|
+
connect(job: ActivityStream, credentials: PlatformIrcCredentialsObject, done: PlatformCallback): void;
|
|
67
|
+
/**
|
|
68
|
+
* Function: join
|
|
69
|
+
*
|
|
70
|
+
* Join a room or private conversation.
|
|
71
|
+
*
|
|
72
|
+
* @param {object} job activity streams object
|
|
73
|
+
* @param {object} done callback when job is done
|
|
74
|
+
*/
|
|
75
|
+
join(job: ActivityStream, done: PlatformCallback): void;
|
|
76
|
+
/**
|
|
77
|
+
* Function leave
|
|
78
|
+
*
|
|
79
|
+
* Leave a room or private conversation.
|
|
80
|
+
*
|
|
81
|
+
* @param {object} job activity streams object
|
|
82
|
+
* @param {object} done callback when job is done
|
|
83
|
+
*/
|
|
84
|
+
leave(job: ActivityStream, done: PlatformCallback): void;
|
|
85
|
+
/**
|
|
86
|
+
* Function: send
|
|
87
|
+
*
|
|
88
|
+
* Send a message to a room or private conversation.
|
|
89
|
+
*
|
|
90
|
+
* @param {object} job activity streams object
|
|
91
|
+
* @param {object} done callback when job is done
|
|
92
|
+
*/
|
|
93
|
+
send(job: ActivityStream, done: PlatformCallback): void;
|
|
94
|
+
/**
|
|
95
|
+
* Function: update
|
|
96
|
+
*
|
|
97
|
+
* Indicate a change (i.e. room topic update, or nickname change).
|
|
98
|
+
*
|
|
99
|
+
* @param {object} job activity streams object
|
|
100
|
+
* @param {object} credentials credentials to verify this user is the right one
|
|
101
|
+
* @param {object} done callback when job is done
|
|
102
|
+
*/
|
|
103
|
+
update(job: ActivityStream, credentials: PlatformIrcCredentialsObject, done: PlatformCallback): void;
|
|
104
|
+
/**
|
|
105
|
+
* Function: query
|
|
106
|
+
*
|
|
107
|
+
* Indicate an intent to query something (e.g. get a list of users in a room).
|
|
108
|
+
*
|
|
109
|
+
* @param {object} job activity streams object
|
|
110
|
+
* @param {object} done callback when job is done
|
|
111
|
+
*/
|
|
112
|
+
query(job: ActivityStream, done: PlatformCallback): void;
|
|
113
|
+
/**
|
|
114
|
+
* Disconnect IRC client
|
|
115
|
+
* @param {object} job activity streams object
|
|
116
|
+
* @param done
|
|
117
|
+
*/
|
|
118
|
+
disconnect(job: ActivityStream, done: PlatformCallback): void;
|
|
119
|
+
cleanup(done: PlatformCallback): any;
|
|
120
|
+
/**
|
|
121
|
+
* Resolve an IRC channel name from a job target. Prefers `target.name`,
|
|
122
|
+
* falling back to the channel segment of `target.id` (`<server>/<channel>`).
|
|
123
|
+
* Returns undefined when no valid `#channel` can be determined, so callers
|
|
124
|
+
* never emit a bare `NAMES` command (which floods the client with the
|
|
125
|
+
* server's entire channel list).
|
|
126
|
+
*/
|
|
127
|
+
private resolveChannelName;
|
|
128
|
+
private isJoined;
|
|
129
|
+
private hasJoined;
|
|
130
|
+
private hasLeft;
|
|
131
|
+
private getClient;
|
|
132
|
+
private ircConnect;
|
|
133
|
+
private completeJob;
|
|
134
|
+
private registerListeners;
|
|
135
|
+
}
|
|
136
|
+
export default IRC;
|