@sockethub/platform-irc 4.0.0-alpha.10 → 4.0.0-alpha.12
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 +33 -15
- package/dist/index.js +16451 -832
- package/dist/index.js.map +157 -15
- package/package.json +6 -5
- package/src/ambient.d.ts +35 -0
- package/src/index.test.data.ts +10 -2
- package/src/index.test.ts +45 -28
- package/src/index.ts +71 -52
- package/src/octal-hack.d.ts +2 -0
- package/src/octal-hack.js +2 -2
- package/src/schema.ts +4 -0
- package/src/types.ts +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sockethub/platform-irc",
|
|
3
3
|
"description": "A sockethub platform module implementing IRC functionality",
|
|
4
|
-
"version": "4.0.0-alpha.
|
|
4
|
+
"version": "4.0.0-alpha.12",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Nick Jennings <nick@silverbucket.net>",
|
|
7
7
|
"license": "LGPL-3.0+",
|
|
@@ -42,24 +42,25 @@
|
|
|
42
42
|
"scripts": {
|
|
43
43
|
"build": "bun build src/index.ts --outdir dist --target node --format esm --sourcemap=external",
|
|
44
44
|
"clean": "rm -rf dist",
|
|
45
|
+
"clean:deps": "rm -rf node_modules",
|
|
45
46
|
"doc": "typedoc --options typedoc.json"
|
|
46
47
|
},
|
|
47
48
|
"dependencies": {
|
|
48
|
-
"@sockethub/irc2as": "^4.0.0-alpha.
|
|
49
|
+
"@sockethub/irc2as": "^4.0.0-alpha.12",
|
|
49
50
|
"irc-socket-sasl": "^4.0.0"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
|
-
"@sockethub/schemas": "^3.0.0-alpha.
|
|
53
|
+
"@sockethub/schemas": "^3.0.0-alpha.12",
|
|
53
54
|
"@types/bun": "latest",
|
|
54
55
|
"typedoc": "^0.28.14"
|
|
55
56
|
},
|
|
56
57
|
"peerDependencies": {
|
|
57
|
-
"@sockethub/server": "^5.0.0-alpha.
|
|
58
|
+
"@sockethub/server": "^5.0.0-alpha.12"
|
|
58
59
|
},
|
|
59
60
|
"peerDependenciesMeta": {
|
|
60
61
|
"@sockethub/server": {
|
|
61
62
|
"optional": true
|
|
62
63
|
}
|
|
63
64
|
},
|
|
64
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "f039dab3c3f67cbbf204476fc397532e973f82a8"
|
|
65
66
|
}
|
package/src/ambient.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
declare module "irc-socket-sasl" {
|
|
2
|
+
export interface IrcSocketInstance {
|
|
3
|
+
end?: () => void;
|
|
4
|
+
raw: (message: string) => void;
|
|
5
|
+
once: (
|
|
6
|
+
event: string,
|
|
7
|
+
handler: (...args: Array<unknown>) => void,
|
|
8
|
+
) => void;
|
|
9
|
+
on: (event: string, handler: (...args: Array<unknown>) => void) => void;
|
|
10
|
+
connect: () => Promise<unknown>;
|
|
11
|
+
}
|
|
12
|
+
const IrcSocket: new (...args: Array<unknown>) => IrcSocketInstance;
|
|
13
|
+
export default IrcSocket;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare module "@sockethub/irc2as" {
|
|
17
|
+
interface IrcToActivityStreamsOptions {
|
|
18
|
+
server: string;
|
|
19
|
+
contexts?: Array<string>;
|
|
20
|
+
context?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class IrcToActivityStreams {
|
|
24
|
+
constructor(options: IrcToActivityStreamsOptions);
|
|
25
|
+
input(data: unknown): void;
|
|
26
|
+
events: {
|
|
27
|
+
on(event: string, handler: (...args: Array<unknown>) => void): void;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare module "./octal-hack.js" {
|
|
33
|
+
const buildCommand: (input: string) => string;
|
|
34
|
+
export default buildCommand;
|
|
35
|
+
}
|
package/src/index.test.data.ts
CHANGED
|
@@ -4,7 +4,11 @@ export default [
|
|
|
4
4
|
valid: true,
|
|
5
5
|
type: "credentials",
|
|
6
6
|
input: {
|
|
7
|
-
context:
|
|
7
|
+
"@context": [
|
|
8
|
+
"https://www.w3.org/ns/activitystreams",
|
|
9
|
+
"https://sockethub.org/ns/context/v1.jsonld",
|
|
10
|
+
"https://sockethub.org/ns/context/platform/irc/v1.jsonld",
|
|
11
|
+
],
|
|
8
12
|
type: "credentials",
|
|
9
13
|
actor: {
|
|
10
14
|
id: "sh-9K3Vk@irc.freenode.net",
|
|
@@ -33,7 +37,11 @@ export default [
|
|
|
33
37
|
valid: false,
|
|
34
38
|
type: "credentials",
|
|
35
39
|
input: {
|
|
36
|
-
context:
|
|
40
|
+
"@context": [
|
|
41
|
+
"https://www.w3.org/ns/activitystreams",
|
|
42
|
+
"https://sockethub.org/ns/context/v1.jsonld",
|
|
43
|
+
"https://sockethub.org/ns/context/platform/irc/v1.jsonld",
|
|
44
|
+
],
|
|
37
45
|
type: "credentials",
|
|
38
46
|
actor: {
|
|
39
47
|
id: "sh-9K3Vk@irc.freenode.net",
|
package/src/index.test.ts
CHANGED
|
@@ -3,7 +3,9 @@ import { beforeEach, describe, expect, it } from "bun:test";
|
|
|
3
3
|
import {
|
|
4
4
|
type ActivityStream,
|
|
5
5
|
type CredentialsObject,
|
|
6
|
+
addPlatformContext,
|
|
6
7
|
addPlatformSchema,
|
|
8
|
+
buildCanonicalContext,
|
|
7
9
|
getPlatformSchema,
|
|
8
10
|
validateCredentials,
|
|
9
11
|
validatePlatformSchema,
|
|
@@ -30,8 +32,12 @@ const targetRoom = {
|
|
|
30
32
|
name: "#a-room",
|
|
31
33
|
};
|
|
32
34
|
|
|
35
|
+
const IRC_CONTEXT = buildCanonicalContext(
|
|
36
|
+
"https://sockethub.org/ns/context/platform/irc/v1.jsonld",
|
|
37
|
+
);
|
|
38
|
+
|
|
33
39
|
const validCredentials = {
|
|
34
|
-
context:
|
|
40
|
+
"@context": IRC_CONTEXT,
|
|
35
41
|
type: "credentials",
|
|
36
42
|
actor: actor,
|
|
37
43
|
object: {
|
|
@@ -45,7 +51,12 @@ describe("Initialize IRC Platform", () => {
|
|
|
45
51
|
let platform;
|
|
46
52
|
beforeEach(() => {
|
|
47
53
|
platform = new IRC({
|
|
48
|
-
|
|
54
|
+
log: {
|
|
55
|
+
error: () => {},
|
|
56
|
+
warn: () => {},
|
|
57
|
+
info: () => {},
|
|
58
|
+
debug: () => {},
|
|
59
|
+
},
|
|
49
60
|
updateActor: function async() {
|
|
50
61
|
return Promise.resolve();
|
|
51
62
|
},
|
|
@@ -64,6 +75,7 @@ describe("Initialize IRC Platform", () => {
|
|
|
64
75
|
if (!getPlatformSchema("irc/credentials")) {
|
|
65
76
|
addPlatformSchema(platform.schema.credentials, `irc/credentials`);
|
|
66
77
|
}
|
|
78
|
+
addPlatformContext("irc", platform.schema.contextUrl);
|
|
67
79
|
});
|
|
68
80
|
|
|
69
81
|
it("lists required types enum", () => {
|
|
@@ -84,7 +96,6 @@ describe("Initialize IRC Platform", () => {
|
|
|
84
96
|
connectTimeoutMs: 30000,
|
|
85
97
|
persist: true,
|
|
86
98
|
requireCredentials: ["connect", "update"],
|
|
87
|
-
initialized: false,
|
|
88
99
|
});
|
|
89
100
|
});
|
|
90
101
|
|
|
@@ -98,25 +109,30 @@ describe("Initialize IRC Platform", () => {
|
|
|
98
109
|
});
|
|
99
110
|
|
|
100
111
|
it("invalid credentials type", () => {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
+
const result = validateCredentials({
|
|
113
|
+
"@context": IRC_CONTEXT,
|
|
114
|
+
type: "credentials",
|
|
115
|
+
actor,
|
|
116
|
+
// @ts-expect-error test invalid params
|
|
117
|
+
object: {
|
|
118
|
+
host: "example.com",
|
|
119
|
+
port: "6667",
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
expect([
|
|
123
|
+
"[irc] /object: must have required property 'type'",
|
|
124
|
+
"[irc] /object/port: must be number",
|
|
125
|
+
"[irc] /object: must match exactly one schema in oneOf: credentials, feed, message, me, person, room, service, platform, website, attendance, presence, relationship, topic, address, heartbeat",
|
|
126
|
+
]).toContain(result);
|
|
112
127
|
});
|
|
113
128
|
|
|
114
129
|
it("invalid credentials port", () => {
|
|
115
130
|
expect(
|
|
116
131
|
// @ts-expect-error test invalid params
|
|
117
132
|
validateCredentials({
|
|
118
|
-
context:
|
|
133
|
+
"@context": IRC_CONTEXT,
|
|
119
134
|
type: "credentials",
|
|
135
|
+
actor,
|
|
120
136
|
object: {
|
|
121
137
|
type: "credentials",
|
|
122
138
|
host: "example.com",
|
|
@@ -130,8 +146,9 @@ describe("Initialize IRC Platform", () => {
|
|
|
130
146
|
expect(
|
|
131
147
|
// @ts-expect-error test invalid params
|
|
132
148
|
validateCredentials({
|
|
133
|
-
context:
|
|
149
|
+
"@context": IRC_CONTEXT,
|
|
134
150
|
type: "credentials",
|
|
151
|
+
actor,
|
|
135
152
|
object: {
|
|
136
153
|
type: "credentials",
|
|
137
154
|
host: "example.com",
|
|
@@ -148,7 +165,7 @@ describe("Initialize IRC Platform", () => {
|
|
|
148
165
|
beforeEach((done) => {
|
|
149
166
|
platform.connect(
|
|
150
167
|
{
|
|
151
|
-
context:
|
|
168
|
+
"@context": IRC_CONTEXT,
|
|
152
169
|
type: "connect",
|
|
153
170
|
actor: actor,
|
|
154
171
|
},
|
|
@@ -161,7 +178,7 @@ describe("Initialize IRC Platform", () => {
|
|
|
161
178
|
beforeEach((done) => {
|
|
162
179
|
platform.join(
|
|
163
180
|
{
|
|
164
|
-
context:
|
|
181
|
+
"@context": IRC_CONTEXT,
|
|
165
182
|
type: "join",
|
|
166
183
|
actor: actor,
|
|
167
184
|
target: targetRoom,
|
|
@@ -178,7 +195,7 @@ describe("Initialize IRC Platform", () => {
|
|
|
178
195
|
it("leave()", (done) => {
|
|
179
196
|
platform.leave(
|
|
180
197
|
{
|
|
181
|
-
context:
|
|
198
|
+
"@context": IRC_CONTEXT,
|
|
182
199
|
type: "leave",
|
|
183
200
|
actor: actor,
|
|
184
201
|
target: targetRoom,
|
|
@@ -191,7 +208,7 @@ describe("Initialize IRC Platform", () => {
|
|
|
191
208
|
it("send()", (done) => {
|
|
192
209
|
platform.send(
|
|
193
210
|
{
|
|
194
|
-
context:
|
|
211
|
+
"@context": IRC_CONTEXT,
|
|
195
212
|
type: "send",
|
|
196
213
|
actor: actor,
|
|
197
214
|
object: { content: "har dee dar" },
|
|
@@ -205,7 +222,7 @@ describe("Initialize IRC Platform", () => {
|
|
|
205
222
|
it("update() topic", (done) => {
|
|
206
223
|
platform.update(
|
|
207
224
|
{
|
|
208
|
-
context:
|
|
225
|
+
"@context": IRC_CONTEXT,
|
|
209
226
|
type: "update",
|
|
210
227
|
actor: actor,
|
|
211
228
|
object: { type: "topic", content: "important details" },
|
|
@@ -220,7 +237,7 @@ describe("Initialize IRC Platform", () => {
|
|
|
220
237
|
it("update() nick change", (done) => {
|
|
221
238
|
platform.update(
|
|
222
239
|
{
|
|
223
|
-
context:
|
|
240
|
+
"@context": IRC_CONTEXT,
|
|
224
241
|
type: "update",
|
|
225
242
|
actor: actor,
|
|
226
243
|
object: { type: "address" },
|
|
@@ -235,7 +252,7 @@ describe("Initialize IRC Platform", () => {
|
|
|
235
252
|
it("query()", (done) => {
|
|
236
253
|
platform.query(
|
|
237
254
|
{
|
|
238
|
-
context:
|
|
255
|
+
"@context": IRC_CONTEXT,
|
|
239
256
|
type: "query",
|
|
240
257
|
actor: actor,
|
|
241
258
|
target: targetRoom,
|
|
@@ -247,28 +264,28 @@ describe("Initialize IRC Platform", () => {
|
|
|
247
264
|
});
|
|
248
265
|
|
|
249
266
|
it("disconnect()", (done) => {
|
|
250
|
-
expect(platform.
|
|
267
|
+
expect(platform.isInitialized()).toEqual(true);
|
|
251
268
|
let cleanupCalled = false;
|
|
252
269
|
platform.cleanup = (cb) => {
|
|
253
270
|
cleanupCalled = true;
|
|
254
271
|
cb();
|
|
255
272
|
}
|
|
256
273
|
platform.disconnect({
|
|
257
|
-
context:
|
|
274
|
+
"@context": IRC_CONTEXT,
|
|
258
275
|
type: "disconnect",
|
|
259
276
|
actor: actor,
|
|
260
277
|
},
|
|
261
278
|
() => {
|
|
262
|
-
expect(platform.
|
|
279
|
+
expect(platform.isInitialized()).toEqual(true);
|
|
263
280
|
expect(cleanupCalled).toEqual(true);
|
|
264
281
|
done();
|
|
265
282
|
});
|
|
266
283
|
});
|
|
267
284
|
|
|
268
285
|
it("cleanup()", (done) => {
|
|
269
|
-
expect(platform.
|
|
286
|
+
expect(platform.isInitialized()).toEqual(true);
|
|
270
287
|
platform.cleanup(() => {
|
|
271
|
-
expect(platform.
|
|
288
|
+
expect(platform.isInitialized()).toEqual(false);
|
|
272
289
|
done();
|
|
273
290
|
});
|
|
274
291
|
});
|
package/src/index.ts
CHANGED
|
@@ -18,8 +18,6 @@
|
|
|
18
18
|
|
|
19
19
|
import net from "node:net";
|
|
20
20
|
import tls from "node:tls";
|
|
21
|
-
import IrcSocket from "irc-socket-sasl";
|
|
22
|
-
|
|
23
21
|
import { IrcToActivityStreams } from "@sockethub/irc2as";
|
|
24
22
|
import type {
|
|
25
23
|
ActivityStream,
|
|
@@ -32,15 +30,19 @@ import type {
|
|
|
32
30
|
PlatformSession,
|
|
33
31
|
PlatformUpdateActor,
|
|
34
32
|
} from "@sockethub/schemas";
|
|
33
|
+
import { buildCanonicalContext } from "@sockethub/schemas";
|
|
34
|
+
import IrcSocket, { type IrcSocketInstance } from "irc-socket-sasl";
|
|
35
35
|
|
|
36
36
|
import { PlatformIrcSchema } from "./schema.js";
|
|
37
37
|
import type { PlatformIrcCredentialsObject } from "./types.js";
|
|
38
38
|
|
|
39
39
|
export type GetClientCallback = (
|
|
40
40
|
err: string | null,
|
|
41
|
-
client?:
|
|
41
|
+
client?: IrcSocketInstance,
|
|
42
42
|
) => void;
|
|
43
43
|
|
|
44
|
+
type JobQueueHandler = (err?: Error | string) => void | Promise<void>;
|
|
45
|
+
|
|
44
46
|
interface IrcSocketOptionsCapabilities {
|
|
45
47
|
requires: string[];
|
|
46
48
|
}
|
|
@@ -77,26 +79,26 @@ interface IrcSocketOptions {
|
|
|
77
79
|
* @param {object} cfg a unique config object for this instance
|
|
78
80
|
*/
|
|
79
81
|
export default class IRC implements PersistentPlatformInterface {
|
|
80
|
-
|
|
82
|
+
private readonly log: Logger;
|
|
81
83
|
credentialsHash: string;
|
|
82
84
|
config: PersistentPlatformConfig = {
|
|
83
85
|
persist: true,
|
|
84
86
|
requireCredentials: ["connect", "update"],
|
|
85
|
-
initialized: false,
|
|
86
87
|
connectTimeoutMs: 30000,
|
|
87
88
|
};
|
|
88
89
|
private readonly updateActor: PlatformUpdateActor;
|
|
89
90
|
private readonly sendToClient: PlatformSendToClient;
|
|
90
|
-
private irc2as
|
|
91
|
+
private irc2as!: IrcToActivityStreams;
|
|
91
92
|
private forceDisconnect = false;
|
|
92
93
|
private clientConnecting = false;
|
|
93
|
-
private
|
|
94
|
-
private
|
|
94
|
+
private initialized = false;
|
|
95
|
+
private client?: IrcSocketInstance;
|
|
96
|
+
private jobQueue: Array<JobQueueHandler> = []; // list of handlers to confirm when message delivery confirmed
|
|
95
97
|
private channels = new Set();
|
|
96
98
|
private handledActors = new Set();
|
|
97
99
|
|
|
98
100
|
constructor(session: PlatformSession) {
|
|
99
|
-
this.
|
|
101
|
+
this.log = session.log;
|
|
100
102
|
this.sendToClient = session.sendToClient;
|
|
101
103
|
this.updateActor = session.updateActor;
|
|
102
104
|
}
|
|
@@ -146,6 +148,14 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
146
148
|
return PlatformIrcSchema;
|
|
147
149
|
}
|
|
148
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Returns whether the platform is ready to handle jobs.
|
|
153
|
+
* For IRC, this means we have successfully connected to the server.
|
|
154
|
+
*/
|
|
155
|
+
isInitialized(): boolean {
|
|
156
|
+
return this.initialized;
|
|
157
|
+
}
|
|
158
|
+
|
|
149
159
|
/**
|
|
150
160
|
* Function: connect
|
|
151
161
|
*
|
|
@@ -196,13 +206,13 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
196
206
|
*
|
|
197
207
|
*/
|
|
198
208
|
join(job: ActivityStream, done: PlatformCallback) {
|
|
199
|
-
this.debug(`join() called for ${job.actor.id}`);
|
|
209
|
+
this.log.debug(`join() called for ${job.actor.id}`);
|
|
200
210
|
this.getClient(job.actor.id, false, (err, client) => {
|
|
201
211
|
if (err) {
|
|
202
212
|
return done(err);
|
|
203
213
|
}
|
|
204
214
|
if (this.channels.has(job.target.name)) {
|
|
205
|
-
this.debug(`channel ${job.target.name} already joined`);
|
|
215
|
+
this.log.debug(`channel ${job.target.name} already joined`);
|
|
206
216
|
return done();
|
|
207
217
|
}
|
|
208
218
|
// join channel
|
|
@@ -210,7 +220,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
210
220
|
this.hasJoined(job.target.name);
|
|
211
221
|
done();
|
|
212
222
|
});
|
|
213
|
-
this.debug(`sending join ${job.target.name}`);
|
|
223
|
+
this.log.debug(`sending join ${job.target.name}`);
|
|
214
224
|
client.raw(["JOIN", job.target.name]);
|
|
215
225
|
client.raw(`PING ${job.actor.name}`);
|
|
216
226
|
});
|
|
@@ -243,7 +253,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
243
253
|
*
|
|
244
254
|
*/
|
|
245
255
|
leave(job: ActivityStream, done: PlatformCallback) {
|
|
246
|
-
this.debug(`leave() called for ${job.actor.name}`);
|
|
256
|
+
this.log.debug(`leave() called for ${job.actor.name}`);
|
|
247
257
|
this.getClient(job.actor.id, false, (err, client) => {
|
|
248
258
|
if (err) {
|
|
249
259
|
return done(err);
|
|
@@ -287,7 +297,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
287
297
|
*
|
|
288
298
|
*/
|
|
289
299
|
send(job: ActivityStream, done: PlatformCallback) {
|
|
290
|
-
this.debug(
|
|
300
|
+
this.log.debug(
|
|
291
301
|
`send() called for ${job.actor.id} target: ${job.target.id}`,
|
|
292
302
|
);
|
|
293
303
|
this.getClient(job.actor.id, false, async (err, client) => {
|
|
@@ -322,9 +332,11 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
322
332
|
// so the following line needs to be commented out when the API doc is built.
|
|
323
333
|
// investigate:
|
|
324
334
|
// https://github.com/jsdoc2md/jsdoc-to-markdown/issues/197#issuecomment-976851915
|
|
325
|
-
const buildCommand = await import(
|
|
335
|
+
const { default: buildCommand } = await import(
|
|
336
|
+
"./octal-hack.js"
|
|
337
|
+
);
|
|
326
338
|
const message = buildCommand(job.object.content);
|
|
327
|
-
// biome-ignore lint/style/useTemplate:
|
|
339
|
+
// biome-ignore lint/style/useTemplate: IRC raw command formatting
|
|
328
340
|
client.raw("PRIVMSG " + job.target.name + " :" + message);
|
|
329
341
|
return done("IRC commands temporarily disabled");
|
|
330
342
|
}
|
|
@@ -398,13 +410,13 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
398
410
|
credentials: PlatformIrcCredentialsObject,
|
|
399
411
|
done: PlatformCallback,
|
|
400
412
|
) {
|
|
401
|
-
this.debug(`update() called for ${job.actor.id}`);
|
|
413
|
+
this.log.debug(`update() called for ${job.actor.id}`);
|
|
402
414
|
this.getClient(job.actor.id, false, (err, client) => {
|
|
403
415
|
if (err) {
|
|
404
416
|
return done(err);
|
|
405
417
|
}
|
|
406
418
|
if (job.object.type === "address") {
|
|
407
|
-
this.debug(
|
|
419
|
+
this.log.debug(
|
|
408
420
|
`changing nick from ${job.actor.name} to ${job.target.name}`,
|
|
409
421
|
);
|
|
410
422
|
this.handledActors.add(job.target.id);
|
|
@@ -423,7 +435,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
423
435
|
client.raw(["NICK", job.target.name]);
|
|
424
436
|
} else if (job.object.type === "topic") {
|
|
425
437
|
// update topic
|
|
426
|
-
this.debug(`changing topic in channel ${job.target.name}`);
|
|
438
|
+
this.log.debug(`changing topic in channel ${job.target.name}`);
|
|
427
439
|
this.jobQueue.push(done);
|
|
428
440
|
client.raw(["topic", job.target.name, job.object.content]);
|
|
429
441
|
} else {
|
|
@@ -487,14 +499,16 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
487
499
|
*
|
|
488
500
|
*/
|
|
489
501
|
query(job: ActivityStream, done: PlatformCallback) {
|
|
490
|
-
this.debug(`query() called for ${job.actor.id}`);
|
|
502
|
+
this.log.debug(`query() called for ${job.actor.id}`);
|
|
491
503
|
this.getClient(job.actor.id, false, (err, client) => {
|
|
492
504
|
if (err) {
|
|
493
505
|
return done(err);
|
|
494
506
|
}
|
|
495
507
|
|
|
496
508
|
if (job.object.type === "attendance") {
|
|
497
|
-
this.debug(
|
|
509
|
+
this.log.debug(
|
|
510
|
+
`query() - sending NAMES for ${job.target.name}`,
|
|
511
|
+
);
|
|
498
512
|
client.raw(["NAMES", job.target.name]);
|
|
499
513
|
done();
|
|
500
514
|
} else {
|
|
@@ -520,13 +534,13 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
520
534
|
* }
|
|
521
535
|
*/
|
|
522
536
|
disconnect(job: ActivityStream, done: PlatformCallback) {
|
|
523
|
-
this.debug(`disconnect called for ${job.actor.id}`);
|
|
537
|
+
this.log.debug(`disconnect called for ${job.actor.id}`);
|
|
524
538
|
this.cleanup(done);
|
|
525
539
|
}
|
|
526
540
|
|
|
527
541
|
cleanup(done: PlatformCallback) {
|
|
528
|
-
this.debug("cleanup() called");
|
|
529
|
-
this.
|
|
542
|
+
this.log.debug("cleanup() called");
|
|
543
|
+
this.initialized = false;
|
|
530
544
|
this.forceDisconnect = true;
|
|
531
545
|
if (typeof this.client === "object") {
|
|
532
546
|
if (typeof this.client.end === "function") {
|
|
@@ -551,7 +565,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
551
565
|
}
|
|
552
566
|
|
|
553
567
|
private hasJoined(channel: string) {
|
|
554
|
-
this.debug(`joined ${channel}`);
|
|
568
|
+
this.log.debug(`joined ${channel}`);
|
|
555
569
|
// keep track of channels joined
|
|
556
570
|
if (!this.channels.has(channel)) {
|
|
557
571
|
this.channels.add(channel);
|
|
@@ -559,7 +573,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
559
573
|
}
|
|
560
574
|
|
|
561
575
|
private hasLeft(channel: string) {
|
|
562
|
-
this.debug(`left ${channel}`);
|
|
576
|
+
this.log.debug(`left ${channel}`);
|
|
563
577
|
// keep track of channels left
|
|
564
578
|
if (this.channels.has(channel)) {
|
|
565
579
|
this.channels.delete(channel);
|
|
@@ -571,7 +585,9 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
571
585
|
credentials: PlatformIrcCredentialsObject | false,
|
|
572
586
|
cb: GetClientCallback,
|
|
573
587
|
) {
|
|
574
|
-
this.debug(
|
|
588
|
+
this.log.debug(
|
|
589
|
+
`getClient called, connecting: ${this.clientConnecting}`,
|
|
590
|
+
);
|
|
575
591
|
if (this.client) {
|
|
576
592
|
this.handledActors.add(key);
|
|
577
593
|
return cb(null, this.client);
|
|
@@ -581,7 +597,9 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
581
597
|
// client is in the process of connecting, wait
|
|
582
598
|
setTimeout(() => {
|
|
583
599
|
if (this.client) {
|
|
584
|
-
this.debug(
|
|
600
|
+
this.log.debug(
|
|
601
|
+
`resolving delayed getClient call for ${key}`,
|
|
602
|
+
);
|
|
585
603
|
this.handledActors.add(key);
|
|
586
604
|
return cb(null, this.client);
|
|
587
605
|
}
|
|
@@ -598,13 +616,13 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
598
616
|
|
|
599
617
|
this.ircConnect(credentials, (err, client) => {
|
|
600
618
|
if (err) {
|
|
601
|
-
this.
|
|
619
|
+
this.initialized = false;
|
|
602
620
|
return cb(err);
|
|
603
621
|
}
|
|
604
622
|
this.handledActors.add(key);
|
|
605
623
|
this.client = client;
|
|
606
624
|
this.registerListeners(credentials.object.server);
|
|
607
|
-
this.
|
|
625
|
+
this.initialized = true;
|
|
608
626
|
return cb(null, client);
|
|
609
627
|
});
|
|
610
628
|
}
|
|
@@ -645,16 +663,13 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
645
663
|
module_options.capabilities = { requires: ["sasl"] };
|
|
646
664
|
}
|
|
647
665
|
|
|
648
|
-
this.debug(
|
|
666
|
+
this.log.debug(
|
|
649
667
|
`attempting to connect to ${module_options.server}:${module_options.port} transport: ${
|
|
650
668
|
is_secure ? "secure" : "clear"
|
|
651
669
|
} sasl: ${is_sasl}`,
|
|
652
670
|
);
|
|
653
671
|
|
|
654
|
-
const client
|
|
655
|
-
module_options,
|
|
656
|
-
is_secure ? tls : net,
|
|
657
|
-
);
|
|
672
|
+
const client = new IrcSocket(module_options, is_secure ? tls : net);
|
|
658
673
|
|
|
659
674
|
const forceDisconnect = (err: string) => {
|
|
660
675
|
this.forceDisconnect = true;
|
|
@@ -669,17 +684,17 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
669
684
|
};
|
|
670
685
|
|
|
671
686
|
client.once("error", (err: string) => {
|
|
672
|
-
this.debug(`irc client 'error' occurred
|
|
687
|
+
this.log.debug(`irc client 'error' occurred.`, { err });
|
|
673
688
|
forceDisconnect("error connecting to server.");
|
|
674
689
|
});
|
|
675
690
|
|
|
676
691
|
client.once("close", () => {
|
|
677
|
-
this.debug(`irc client 'close' event fired.`);
|
|
692
|
+
this.log.debug(`irc client 'close' event fired.`);
|
|
678
693
|
forceDisconnect("connection to server closed.");
|
|
679
694
|
});
|
|
680
695
|
|
|
681
696
|
client.once("timeout", () => {
|
|
682
|
-
this.debug("timeout occurred, force-disconnect");
|
|
697
|
+
this.log.debug("timeout occurred, force-disconnect");
|
|
683
698
|
forceDisconnect("connection timeout to server.");
|
|
684
699
|
});
|
|
685
700
|
|
|
@@ -694,33 +709,36 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
694
709
|
return cb("force disconnect active, aborting connect.");
|
|
695
710
|
}
|
|
696
711
|
|
|
697
|
-
this.debug(
|
|
712
|
+
this.log.debug(
|
|
698
713
|
`connected to ${module_options.server} capabilities: `,
|
|
699
|
-
capabilities,
|
|
714
|
+
{ capabilities },
|
|
700
715
|
);
|
|
701
716
|
return cb(null, client);
|
|
702
717
|
});
|
|
703
718
|
}
|
|
704
719
|
|
|
705
720
|
private completeJob(err?: string) {
|
|
706
|
-
this.debug(`completing job, queue count: ${this.jobQueue.length}`);
|
|
721
|
+
this.log.debug(`completing job, queue count: ${this.jobQueue.length}`);
|
|
707
722
|
const done = this.jobQueue.shift();
|
|
708
723
|
if (typeof done === "function") {
|
|
709
724
|
done(err);
|
|
710
725
|
} else if (this.jobQueue.length === 0) {
|
|
711
|
-
this.debug(
|
|
726
|
+
this.log.debug(
|
|
712
727
|
"WARNING: job completion event received with an empty job queue.",
|
|
713
728
|
);
|
|
714
729
|
} else {
|
|
715
|
-
this.debug(
|
|
730
|
+
this.log.debug(
|
|
716
731
|
`WARNING: job completion found non-function in queue (${typeof done}), ${this.jobQueue.length} items remain.`,
|
|
717
732
|
);
|
|
718
733
|
}
|
|
719
734
|
}
|
|
720
735
|
|
|
721
736
|
private registerListeners(server: string) {
|
|
722
|
-
this.irc2as = new IrcToActivityStreams({
|
|
723
|
-
|
|
737
|
+
this.irc2as = new IrcToActivityStreams({
|
|
738
|
+
server: server,
|
|
739
|
+
contexts: buildCanonicalContext(this.schema.contextUrl),
|
|
740
|
+
});
|
|
741
|
+
this.client.on("data", (data: unknown) => {
|
|
724
742
|
this.irc2as.input(data);
|
|
725
743
|
});
|
|
726
744
|
|
|
@@ -732,32 +750,33 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
732
750
|
) {
|
|
733
751
|
this.completeJob();
|
|
734
752
|
} else {
|
|
735
|
-
this.debug(
|
|
736
|
-
|
|
737
|
-
|
|
753
|
+
this.log.debug(
|
|
754
|
+
`calling sendToClient for ${asObject.actor.id}`,
|
|
755
|
+
[...this.handledActors.keys()],
|
|
756
|
+
);
|
|
738
757
|
this.sendToClient(asObject);
|
|
739
758
|
}
|
|
740
759
|
});
|
|
741
760
|
|
|
742
761
|
this.irc2as.events.on("unprocessed", (s: string) => {
|
|
743
|
-
this.debug(`unprocessed irc message:> ${s}`);
|
|
762
|
+
this.log.debug(`unprocessed irc message:> ${s}`);
|
|
744
763
|
});
|
|
745
764
|
|
|
746
765
|
// The generated eslint error expects that the `error` event is propagating an Error object
|
|
747
766
|
// however for irc2as this event delivers an AS object of type `error`.
|
|
748
767
|
|
|
749
768
|
this.irc2as.events.on("error", (asObject: ActivityStream) => {
|
|
750
|
-
this.debug(`message error response ${asObject.object.content}`);
|
|
769
|
+
this.log.debug(`message error response ${asObject.object.content}`);
|
|
751
770
|
this.completeJob(asObject.object.content);
|
|
752
771
|
});
|
|
753
772
|
|
|
754
773
|
this.irc2as.events.on("pong", (timestamp: string) => {
|
|
755
|
-
this.debug(`received PONG at ${timestamp}`);
|
|
774
|
+
this.log.debug(`received PONG at ${timestamp}`);
|
|
756
775
|
this.completeJob();
|
|
757
776
|
});
|
|
758
777
|
|
|
759
778
|
this.irc2as.events.on("ping", (timestamp: string) => {
|
|
760
|
-
this.debug(`received PING at ${timestamp}`);
|
|
779
|
+
this.log.debug(`received PING at ${timestamp}`);
|
|
761
780
|
this.client.raw("PONG");
|
|
762
781
|
});
|
|
763
782
|
}
|