@sockethub/platform-irc 4.0.0-alpha.6 → 4.0.0-alpha.7
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/dist/index.js +2194 -0
- package/dist/index.js.map +23 -0
- package/package.json +23 -10
- package/API.md +0 -421
- package/typedoc.json +0 -11
package/dist/index.js
ADDED
|
@@ -0,0 +1,2194 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
19
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
20
|
+
|
|
21
|
+
// ../../node_modules/r-result/result.js
|
|
22
|
+
var require_result = __commonJS((exports, module) => {
|
|
23
|
+
var inspect = __require("util").inspect;
|
|
24
|
+
var Ok = function(t) {
|
|
25
|
+
const Result = Object.create(methods);
|
|
26
|
+
Result.is_ok = true;
|
|
27
|
+
Result.value = t;
|
|
28
|
+
return Result;
|
|
29
|
+
};
|
|
30
|
+
var Fail = function(f) {
|
|
31
|
+
const Result = Object.create(methods);
|
|
32
|
+
Result.is_ok = false;
|
|
33
|
+
Result.value = f;
|
|
34
|
+
return Result;
|
|
35
|
+
};
|
|
36
|
+
var methods = {
|
|
37
|
+
ok: function(errorMessage) {
|
|
38
|
+
if (this.is_ok) {
|
|
39
|
+
return this.value;
|
|
40
|
+
} else {
|
|
41
|
+
if (errorMessage) {
|
|
42
|
+
throw new TypeError(errorMessage);
|
|
43
|
+
} else {
|
|
44
|
+
throw new TypeError("Attempted to unwrap Ok(t) but got Fail(f) instead.");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
fail: function(errorMessage) {
|
|
49
|
+
if (this.is_ok) {
|
|
50
|
+
if (errorMessage) {
|
|
51
|
+
throw new TypeError(errorMessage);
|
|
52
|
+
} else {
|
|
53
|
+
throw new TypeError("Attempted to unwrap Fail(f) but got Ok(t) instead.");
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
return this.value;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
isOk: function() {
|
|
60
|
+
return this.is_ok;
|
|
61
|
+
},
|
|
62
|
+
isFail: function() {
|
|
63
|
+
return !this.is_ok;
|
|
64
|
+
},
|
|
65
|
+
map: function(f) {
|
|
66
|
+
if (this.is_ok) {
|
|
67
|
+
return Ok(f(this.value));
|
|
68
|
+
} else {
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
mapFail: function(f) {
|
|
73
|
+
if (this.is_ok) {
|
|
74
|
+
return this;
|
|
75
|
+
} else {
|
|
76
|
+
return Fail(f(this.value));
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
and: function(rhsResult) {
|
|
80
|
+
if (this.is_ok) {
|
|
81
|
+
return rhsResult;
|
|
82
|
+
} else {
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
or: function(rhsResult) {
|
|
87
|
+
if (this.is_ok) {
|
|
88
|
+
return this;
|
|
89
|
+
} else {
|
|
90
|
+
return rhsResult;
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
andThen: function(f) {
|
|
94
|
+
if (this.is_ok) {
|
|
95
|
+
return f(this.value);
|
|
96
|
+
} else {
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
orElse: function(f) {
|
|
101
|
+
if (this.is_ok) {
|
|
102
|
+
return this;
|
|
103
|
+
} else {
|
|
104
|
+
return f(this.value);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
toArray: function() {
|
|
108
|
+
if (this.is_ok) {
|
|
109
|
+
return [this.value];
|
|
110
|
+
} else {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
unwrapOr: function(defaultValue) {
|
|
115
|
+
if (this.is_ok) {
|
|
116
|
+
return this.value;
|
|
117
|
+
} else {
|
|
118
|
+
return defaultValue;
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
unwrapOrElse: function(defaultFn) {
|
|
122
|
+
if (this.is_ok) {
|
|
123
|
+
return this.value;
|
|
124
|
+
} else {
|
|
125
|
+
return defaultFn(this.value);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
match: function(matchBlock) {
|
|
129
|
+
if (this.is_ok) {
|
|
130
|
+
return matchBlock.Ok(this.value);
|
|
131
|
+
} else {
|
|
132
|
+
return matchBlock.Fail(this.value);
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
inspect: function(depth, opts) {
|
|
136
|
+
var tag = this.is_ok ? "Ok" : "Fail";
|
|
137
|
+
var padding = this.is_ok ? " " : " ";
|
|
138
|
+
if (depth < 0) {
|
|
139
|
+
return opts.stylize("[" + tag + "]", "boolean");
|
|
140
|
+
}
|
|
141
|
+
var recurseOpts = {};
|
|
142
|
+
Object.keys(opts).forEach(function(key) {
|
|
143
|
+
recurseOpts[key] = opts[key];
|
|
144
|
+
});
|
|
145
|
+
recurseOpts.depth = opts.depth === null ? null : opts.depth - 1;
|
|
146
|
+
const inner = inspect(this.value, recurseOpts).replace(/\n/g, `
|
|
147
|
+
` + padding);
|
|
148
|
+
return opts.stylize(tag, "boolean") + "( " + inner + " )";
|
|
149
|
+
},
|
|
150
|
+
debug: function(logfn, inspectOpts) {
|
|
151
|
+
logfn(inspect(this, inspectOpts));
|
|
152
|
+
return this;
|
|
153
|
+
},
|
|
154
|
+
debugOk: function(logfn, inspectOpts) {
|
|
155
|
+
if (this.is_ok) {
|
|
156
|
+
logfn(inspect(this.value, inspectOpts));
|
|
157
|
+
}
|
|
158
|
+
return this;
|
|
159
|
+
},
|
|
160
|
+
debugFail: function(logfn, inspectOpts) {
|
|
161
|
+
if (!this.is_ok) {
|
|
162
|
+
logfn(inspect(this.value, inspectOpts));
|
|
163
|
+
}
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
module.exports = {
|
|
168
|
+
Ok,
|
|
169
|
+
Fail
|
|
170
|
+
};
|
|
171
|
+
var methodToFunction = function(method) {
|
|
172
|
+
return function() {
|
|
173
|
+
var context = arguments[0];
|
|
174
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
|
175
|
+
return method.apply(context, args);
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
Object.keys(methods).forEach(function(key) {
|
|
179
|
+
if (key === "inspect") {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
var method = methods[key];
|
|
183
|
+
module.exports[key] = methodToFunction(method);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// ../../node_modules/irc-socket-sasl/irc-socket.js
|
|
188
|
+
var require_irc_socket = __commonJS((exports, module) => {
|
|
189
|
+
var EventEmitter = __require("events").EventEmitter;
|
|
190
|
+
var format = __require("util").format;
|
|
191
|
+
var rresult = require_result();
|
|
192
|
+
var Ok = rresult.Ok;
|
|
193
|
+
var Fail = rresult.Fail;
|
|
194
|
+
var includes = function(array, value) {
|
|
195
|
+
return array.indexOf(value) !== -1;
|
|
196
|
+
};
|
|
197
|
+
var copyJsonMaybe = function(object) {
|
|
198
|
+
if (!object) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
return JSON.parse(JSON.stringify(object));
|
|
202
|
+
};
|
|
203
|
+
var endsWith = function(string, postfix) {
|
|
204
|
+
return string.lastIndexOf(postfix) === string.length - postfix.length;
|
|
205
|
+
};
|
|
206
|
+
var failures = {
|
|
207
|
+
killed: "killed",
|
|
208
|
+
nicknamesUnavailable: "nicknames unavailable",
|
|
209
|
+
badProxyConfiguration: "bad proxy configuration",
|
|
210
|
+
missingRequiredCapabilities: "missing required capabilities",
|
|
211
|
+
badPassword: "bad password",
|
|
212
|
+
socketEnded: "socket ended"
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
class IrcSocket extends EventEmitter {
|
|
216
|
+
constructor(config, netSocket) {
|
|
217
|
+
super();
|
|
218
|
+
this.impl = netSocket || config.socket;
|
|
219
|
+
this.status = "initialized";
|
|
220
|
+
this.pending = true;
|
|
221
|
+
this.startupPromise = new Promise((resolve, reject) => {
|
|
222
|
+
this.resolvePromise = (res) => {
|
|
223
|
+
this.pending = false;
|
|
224
|
+
resolve(res);
|
|
225
|
+
};
|
|
226
|
+
this.rejectPromise = (res) => {
|
|
227
|
+
this.pending = false;
|
|
228
|
+
reject(res);
|
|
229
|
+
};
|
|
230
|
+
});
|
|
231
|
+
this.proxy = config.proxy;
|
|
232
|
+
this.password = config.password;
|
|
233
|
+
this.capabilities = copyJsonMaybe(config.capabilities);
|
|
234
|
+
if (config.saslPassword) {
|
|
235
|
+
this.saslUsername = config.saslUsername || config.username;
|
|
236
|
+
this.saslPassword = config.saslPassword;
|
|
237
|
+
}
|
|
238
|
+
this.username = config.username;
|
|
239
|
+
this.realname = config.realname;
|
|
240
|
+
this.nicknames = config.nicknames.slice();
|
|
241
|
+
this.timeout = config.timeout || 5 * 60 * 1000;
|
|
242
|
+
this.connectOptions = typeof config.connectOptions === "object" ? Object.create(config.connectOptions) : {};
|
|
243
|
+
this.connectOptions.port = config.port || 6667;
|
|
244
|
+
this.connectOptions.host = config.server;
|
|
245
|
+
this.on("data", function(line) {
|
|
246
|
+
if (line.slice(0, 4) === "PING") {
|
|
247
|
+
this.raw(["PONG", line.slice(line.indexOf(":"))]);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
this.on("timeout", function() {
|
|
251
|
+
this.end();
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
static connectFailures = failures;
|
|
255
|
+
_setHandlers() {
|
|
256
|
+
let timeout = null;
|
|
257
|
+
const timeoutPeriod = this.timeout;
|
|
258
|
+
const onSilence = () => {
|
|
259
|
+
timeout = setTimeout(onNoPong, timeoutPeriod);
|
|
260
|
+
this.raw("PING :ignored");
|
|
261
|
+
};
|
|
262
|
+
const onNoPong = () => {
|
|
263
|
+
this.emit("timeout");
|
|
264
|
+
};
|
|
265
|
+
(() => {
|
|
266
|
+
const emitLine = this.emit.bind(this, "data");
|
|
267
|
+
let lastLine = "";
|
|
268
|
+
const onData = (data) => {
|
|
269
|
+
let lines = data.split(`\r
|
|
270
|
+
`);
|
|
271
|
+
lines[0] = lastLine + lines[0];
|
|
272
|
+
lastLine = lines.pop();
|
|
273
|
+
lines.forEach(function(line) {
|
|
274
|
+
emitLine(line.normalize());
|
|
275
|
+
});
|
|
276
|
+
clearTimeout(timeout);
|
|
277
|
+
timeout = setTimeout(onSilence, timeoutPeriod);
|
|
278
|
+
};
|
|
279
|
+
this.connection.on("data", onData);
|
|
280
|
+
})();
|
|
281
|
+
this.connection.once("connect", () => {
|
|
282
|
+
if (!this.pending) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
this.status = "starting";
|
|
286
|
+
this.emit("connect");
|
|
287
|
+
timeout = setTimeout(onSilence, timeoutPeriod);
|
|
288
|
+
let serverCapabilities, acknowledgedCapabilities, sentRequests, respondedRequests, allRequestsSent, nickname;
|
|
289
|
+
if (this.capabilities) {
|
|
290
|
+
this.capabilities.requires = this.capabilities.requires || [];
|
|
291
|
+
this.capabilities.wants = this.capabilities.wants || [];
|
|
292
|
+
acknowledgedCapabilities = this.capabilities.requires.slice();
|
|
293
|
+
sentRequests = 0;
|
|
294
|
+
respondedRequests = 0;
|
|
295
|
+
allRequestsSent = false;
|
|
296
|
+
}
|
|
297
|
+
const sendUser = () => {
|
|
298
|
+
this.raw(format("USER %s 8 * :%s", this.username, this.realname));
|
|
299
|
+
};
|
|
300
|
+
const sendNick = () => {
|
|
301
|
+
if (this.nicknames.length === 0) {
|
|
302
|
+
this.raw("QUIT");
|
|
303
|
+
this.resolvePromise(Fail(failures.nicknamesUnavailable));
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
nickname = this.nicknames[0];
|
|
307
|
+
this.nicknames.shift();
|
|
308
|
+
this.raw(["NICK", nickname]);
|
|
309
|
+
};
|
|
310
|
+
const startupHandler = (line) => {
|
|
311
|
+
const parts = line.split(" ");
|
|
312
|
+
if (parts[0] === "ERROR") {
|
|
313
|
+
this.resolvePromise(Fail(failures.badProxyConfiguration));
|
|
314
|
+
return;
|
|
315
|
+
} else if (parts[0] === "PING") {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const numeric = parts[1];
|
|
319
|
+
if (numeric === "CAP") {
|
|
320
|
+
let capabilities = this.capabilities;
|
|
321
|
+
if (parts[3] === "LS") {
|
|
322
|
+
serverCapabilities = parts.slice(4);
|
|
323
|
+
serverCapabilities[0] = serverCapabilities[0].slice(1);
|
|
324
|
+
if (capabilities.requires.length !== 0) {
|
|
325
|
+
if (capabilities.requires.every((capability) => {
|
|
326
|
+
return includes(serverCapabilities, capability);
|
|
327
|
+
})) {
|
|
328
|
+
this.raw(format("CAP REQ :%s", capabilities.requires.join(" ")));
|
|
329
|
+
sentRequests += 1;
|
|
330
|
+
} else {
|
|
331
|
+
this.raw("QUIT");
|
|
332
|
+
this.resolvePromise(Fail(failures.missingRequiredCapabilities));
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
capabilities.wants.filter((capability) => {
|
|
337
|
+
return includes(serverCapabilities, capability);
|
|
338
|
+
}).forEach((capability) => {
|
|
339
|
+
this.raw(format("CAP REQ :%s", capability));
|
|
340
|
+
sentRequests += 1;
|
|
341
|
+
});
|
|
342
|
+
return;
|
|
343
|
+
} else if (parts[3] === "NAK") {
|
|
344
|
+
respondedRequests += 1;
|
|
345
|
+
const capability = parts[4].slice(1);
|
|
346
|
+
if (includes(capabilities.requires, capability)) {
|
|
347
|
+
this.raw("QUIT");
|
|
348
|
+
this.resolvePromise(Fail(failures.missingRequiredCapabilities));
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
} else if (parts[3] === "ACK") {
|
|
352
|
+
respondedRequests += 1;
|
|
353
|
+
const capability = parts[4].slice(1);
|
|
354
|
+
if (includes(capabilities.wants, capability)) {
|
|
355
|
+
acknowledgedCapabilities.push(capability);
|
|
356
|
+
}
|
|
357
|
+
if (acknowledgedCapabilities.includes("sasl")) {
|
|
358
|
+
this.raw(["AUTHENTICATE", "PLAIN"]);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (sentRequests === respondedRequests) {
|
|
362
|
+
if (!this.saslPassword) {
|
|
363
|
+
this.raw("CAP END");
|
|
364
|
+
}
|
|
365
|
+
sendUser();
|
|
366
|
+
sendNick();
|
|
367
|
+
}
|
|
368
|
+
} else if (numeric === "NOTICE") {
|
|
369
|
+
if (endsWith(line, "Login unsuccessful")) {
|
|
370
|
+
this.resolvePromise(Fail(failures.badPassword));
|
|
371
|
+
}
|
|
372
|
+
} else if (parts[0] === "AUTHENTICATE") {
|
|
373
|
+
if (parts[1] === "+") {
|
|
374
|
+
const encPW = Buffer.from(this.saslUsername + "\x00" + this.saslUsername + "\x00" + this.saslPassword).toString("base64");
|
|
375
|
+
this.raw(["AUTHENTICATE", encPW]);
|
|
376
|
+
}
|
|
377
|
+
} else if (numeric === "903") {
|
|
378
|
+
this.raw("CAP END");
|
|
379
|
+
} else if (numeric === "001") {
|
|
380
|
+
this.status = "running";
|
|
381
|
+
const data = {
|
|
382
|
+
capabilities: acknowledgedCapabilities,
|
|
383
|
+
nickname
|
|
384
|
+
};
|
|
385
|
+
this.emit("ready", data);
|
|
386
|
+
this.resolvePromise(Ok(data));
|
|
387
|
+
} else if (includes(["410", "421"], numeric)) {
|
|
388
|
+
if (this.capabilities.requires) {
|
|
389
|
+
this.raw("QUIT");
|
|
390
|
+
this.resolvePromise(Fail(failures.missingRequiredCapabilities));
|
|
391
|
+
} else {
|
|
392
|
+
sendUser();
|
|
393
|
+
sendNick();
|
|
394
|
+
}
|
|
395
|
+
} else if (numeric === "464") {
|
|
396
|
+
this.resolvePromise(Fail(failures.badPassword));
|
|
397
|
+
} else if (includes(["431", "432", "433", "436", "437", "484"], numeric)) {
|
|
398
|
+
sendNick();
|
|
399
|
+
} else if (numeric === "PING") {}
|
|
400
|
+
};
|
|
401
|
+
this.on("data", startupHandler);
|
|
402
|
+
this.startupPromise.finally(() => {
|
|
403
|
+
this.removeListener("data", startupHandler);
|
|
404
|
+
});
|
|
405
|
+
if (typeof this.proxy === "object") {
|
|
406
|
+
const proxy = this.proxy;
|
|
407
|
+
this.raw(["WEBIRC", proxy.password, proxy.username, proxy.hostname, proxy.ip]);
|
|
408
|
+
}
|
|
409
|
+
if (typeof this.password === "string") {
|
|
410
|
+
this.raw(["PASS", this.password]);
|
|
411
|
+
}
|
|
412
|
+
if (typeof this.capabilities === "object") {
|
|
413
|
+
this.raw("CAP LS");
|
|
414
|
+
} else {
|
|
415
|
+
sendUser();
|
|
416
|
+
sendNick();
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
this.connection.on("error", (error) => {
|
|
420
|
+
this.status = "closed";
|
|
421
|
+
this.emit("error", error);
|
|
422
|
+
});
|
|
423
|
+
this.connection.on("close", () => {
|
|
424
|
+
if (this.status === "starting" || this.status === "connecting") {
|
|
425
|
+
this.resolvePromise(Fail(failures.killed));
|
|
426
|
+
}
|
|
427
|
+
this.status = "closed";
|
|
428
|
+
this.emit("close");
|
|
429
|
+
});
|
|
430
|
+
this.connection.on("end", () => {
|
|
431
|
+
this.emit("end");
|
|
432
|
+
if (this.pending) {
|
|
433
|
+
this.resolvePromise(Fail(failures.socketEnded));
|
|
434
|
+
}
|
|
435
|
+
clearTimeout(timeout);
|
|
436
|
+
});
|
|
437
|
+
this.connection.on("timeout", () => {
|
|
438
|
+
this.emit("timeout");
|
|
439
|
+
});
|
|
440
|
+
this.connection.setEncoding("utf-8");
|
|
441
|
+
this.connection.setNoDelay();
|
|
442
|
+
}
|
|
443
|
+
connect() {
|
|
444
|
+
if (this.isStarted()) {
|
|
445
|
+
throw new Error("Cannot restart an irc Socket.");
|
|
446
|
+
}
|
|
447
|
+
this.status = "connecting";
|
|
448
|
+
this.connection = this.impl.connect(this.connectOptions);
|
|
449
|
+
this._setHandlers(this.connection);
|
|
450
|
+
return this.startupPromise;
|
|
451
|
+
}
|
|
452
|
+
end() {
|
|
453
|
+
if (!this.isConnected()) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
if (this.pending) {
|
|
457
|
+
this.resolvePromise(Fail(failures.socketEnded));
|
|
458
|
+
}
|
|
459
|
+
this.connection.end();
|
|
460
|
+
}
|
|
461
|
+
raw(message) {
|
|
462
|
+
if (!this.isConnected()) {
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
if (Array.isArray(message)) {
|
|
466
|
+
message = message.join(" ");
|
|
467
|
+
}
|
|
468
|
+
if (message.indexOf(`
|
|
469
|
+
`) !== -1) {
|
|
470
|
+
throw new Error("Newline detected in message. Use multiple raws instead.");
|
|
471
|
+
}
|
|
472
|
+
this.connection.write(message + `\r
|
|
473
|
+
`, "utf-8");
|
|
474
|
+
}
|
|
475
|
+
setTimeout(timeout, callback) {
|
|
476
|
+
this.connection.setTimeout(timeout, callback);
|
|
477
|
+
}
|
|
478
|
+
isStarted() {
|
|
479
|
+
return this.status !== "initialized";
|
|
480
|
+
}
|
|
481
|
+
isConnected() {
|
|
482
|
+
return includes(["connecting", "starting", "running"], this.status);
|
|
483
|
+
}
|
|
484
|
+
isReady() {
|
|
485
|
+
return this.status === "running";
|
|
486
|
+
}
|
|
487
|
+
getRealName() {
|
|
488
|
+
return this._realname;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
module.exports = IrcSocket;
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
// ../../node_modules/ms/index.js
|
|
495
|
+
var require_ms = __commonJS((exports, module) => {
|
|
496
|
+
var s = 1000;
|
|
497
|
+
var m = s * 60;
|
|
498
|
+
var h = m * 60;
|
|
499
|
+
var d = h * 24;
|
|
500
|
+
var w = d * 7;
|
|
501
|
+
var y = d * 365.25;
|
|
502
|
+
module.exports = function(val, options) {
|
|
503
|
+
options = options || {};
|
|
504
|
+
var type = typeof val;
|
|
505
|
+
if (type === "string" && val.length > 0) {
|
|
506
|
+
return parse(val);
|
|
507
|
+
} else if (type === "number" && isFinite(val)) {
|
|
508
|
+
return options.long ? fmtLong(val) : fmtShort(val);
|
|
509
|
+
}
|
|
510
|
+
throw new Error("val is not a non-empty string or a valid number. val=" + JSON.stringify(val));
|
|
511
|
+
};
|
|
512
|
+
function parse(str) {
|
|
513
|
+
str = String(str);
|
|
514
|
+
if (str.length > 100) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str);
|
|
518
|
+
if (!match) {
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
var n = parseFloat(match[1]);
|
|
522
|
+
var type = (match[2] || "ms").toLowerCase();
|
|
523
|
+
switch (type) {
|
|
524
|
+
case "years":
|
|
525
|
+
case "year":
|
|
526
|
+
case "yrs":
|
|
527
|
+
case "yr":
|
|
528
|
+
case "y":
|
|
529
|
+
return n * y;
|
|
530
|
+
case "weeks":
|
|
531
|
+
case "week":
|
|
532
|
+
case "w":
|
|
533
|
+
return n * w;
|
|
534
|
+
case "days":
|
|
535
|
+
case "day":
|
|
536
|
+
case "d":
|
|
537
|
+
return n * d;
|
|
538
|
+
case "hours":
|
|
539
|
+
case "hour":
|
|
540
|
+
case "hrs":
|
|
541
|
+
case "hr":
|
|
542
|
+
case "h":
|
|
543
|
+
return n * h;
|
|
544
|
+
case "minutes":
|
|
545
|
+
case "minute":
|
|
546
|
+
case "mins":
|
|
547
|
+
case "min":
|
|
548
|
+
case "m":
|
|
549
|
+
return n * m;
|
|
550
|
+
case "seconds":
|
|
551
|
+
case "second":
|
|
552
|
+
case "secs":
|
|
553
|
+
case "sec":
|
|
554
|
+
case "s":
|
|
555
|
+
return n * s;
|
|
556
|
+
case "milliseconds":
|
|
557
|
+
case "millisecond":
|
|
558
|
+
case "msecs":
|
|
559
|
+
case "msec":
|
|
560
|
+
case "ms":
|
|
561
|
+
return n;
|
|
562
|
+
default:
|
|
563
|
+
return;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
function fmtShort(ms) {
|
|
567
|
+
var msAbs = Math.abs(ms);
|
|
568
|
+
if (msAbs >= d) {
|
|
569
|
+
return Math.round(ms / d) + "d";
|
|
570
|
+
}
|
|
571
|
+
if (msAbs >= h) {
|
|
572
|
+
return Math.round(ms / h) + "h";
|
|
573
|
+
}
|
|
574
|
+
if (msAbs >= m) {
|
|
575
|
+
return Math.round(ms / m) + "m";
|
|
576
|
+
}
|
|
577
|
+
if (msAbs >= s) {
|
|
578
|
+
return Math.round(ms / s) + "s";
|
|
579
|
+
}
|
|
580
|
+
return ms + "ms";
|
|
581
|
+
}
|
|
582
|
+
function fmtLong(ms) {
|
|
583
|
+
var msAbs = Math.abs(ms);
|
|
584
|
+
if (msAbs >= d) {
|
|
585
|
+
return plural(ms, msAbs, d, "day");
|
|
586
|
+
}
|
|
587
|
+
if (msAbs >= h) {
|
|
588
|
+
return plural(ms, msAbs, h, "hour");
|
|
589
|
+
}
|
|
590
|
+
if (msAbs >= m) {
|
|
591
|
+
return plural(ms, msAbs, m, "minute");
|
|
592
|
+
}
|
|
593
|
+
if (msAbs >= s) {
|
|
594
|
+
return plural(ms, msAbs, s, "second");
|
|
595
|
+
}
|
|
596
|
+
return ms + " ms";
|
|
597
|
+
}
|
|
598
|
+
function plural(ms, msAbs, n, name) {
|
|
599
|
+
var isPlural = msAbs >= n * 1.5;
|
|
600
|
+
return Math.round(ms / n) + " " + name + (isPlural ? "s" : "");
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
// ../../node_modules/debug/src/common.js
|
|
605
|
+
var require_common = __commonJS((exports, module) => {
|
|
606
|
+
function setup(env) {
|
|
607
|
+
createDebug.debug = createDebug;
|
|
608
|
+
createDebug.default = createDebug;
|
|
609
|
+
createDebug.coerce = coerce;
|
|
610
|
+
createDebug.disable = disable;
|
|
611
|
+
createDebug.enable = enable;
|
|
612
|
+
createDebug.enabled = enabled;
|
|
613
|
+
createDebug.humanize = require_ms();
|
|
614
|
+
createDebug.destroy = destroy;
|
|
615
|
+
Object.keys(env).forEach((key) => {
|
|
616
|
+
createDebug[key] = env[key];
|
|
617
|
+
});
|
|
618
|
+
createDebug.names = [];
|
|
619
|
+
createDebug.skips = [];
|
|
620
|
+
createDebug.formatters = {};
|
|
621
|
+
function selectColor(namespace) {
|
|
622
|
+
let hash = 0;
|
|
623
|
+
for (let i = 0;i < namespace.length; i++) {
|
|
624
|
+
hash = (hash << 5) - hash + namespace.charCodeAt(i);
|
|
625
|
+
hash |= 0;
|
|
626
|
+
}
|
|
627
|
+
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
|
|
628
|
+
}
|
|
629
|
+
createDebug.selectColor = selectColor;
|
|
630
|
+
function createDebug(namespace) {
|
|
631
|
+
let prevTime;
|
|
632
|
+
let enableOverride = null;
|
|
633
|
+
let namespacesCache;
|
|
634
|
+
let enabledCache;
|
|
635
|
+
function debug(...args) {
|
|
636
|
+
if (!debug.enabled) {
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
const self = debug;
|
|
640
|
+
const curr = Number(new Date);
|
|
641
|
+
const ms = curr - (prevTime || curr);
|
|
642
|
+
self.diff = ms;
|
|
643
|
+
self.prev = prevTime;
|
|
644
|
+
self.curr = curr;
|
|
645
|
+
prevTime = curr;
|
|
646
|
+
args[0] = createDebug.coerce(args[0]);
|
|
647
|
+
if (typeof args[0] !== "string") {
|
|
648
|
+
args.unshift("%O");
|
|
649
|
+
}
|
|
650
|
+
let index = 0;
|
|
651
|
+
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
|
|
652
|
+
if (match === "%%") {
|
|
653
|
+
return "%";
|
|
654
|
+
}
|
|
655
|
+
index++;
|
|
656
|
+
const formatter = createDebug.formatters[format];
|
|
657
|
+
if (typeof formatter === "function") {
|
|
658
|
+
const val = args[index];
|
|
659
|
+
match = formatter.call(self, val);
|
|
660
|
+
args.splice(index, 1);
|
|
661
|
+
index--;
|
|
662
|
+
}
|
|
663
|
+
return match;
|
|
664
|
+
});
|
|
665
|
+
createDebug.formatArgs.call(self, args);
|
|
666
|
+
const logFn = self.log || createDebug.log;
|
|
667
|
+
logFn.apply(self, args);
|
|
668
|
+
}
|
|
669
|
+
debug.namespace = namespace;
|
|
670
|
+
debug.useColors = createDebug.useColors();
|
|
671
|
+
debug.color = createDebug.selectColor(namespace);
|
|
672
|
+
debug.extend = extend;
|
|
673
|
+
debug.destroy = createDebug.destroy;
|
|
674
|
+
Object.defineProperty(debug, "enabled", {
|
|
675
|
+
enumerable: true,
|
|
676
|
+
configurable: false,
|
|
677
|
+
get: () => {
|
|
678
|
+
if (enableOverride !== null) {
|
|
679
|
+
return enableOverride;
|
|
680
|
+
}
|
|
681
|
+
if (namespacesCache !== createDebug.namespaces) {
|
|
682
|
+
namespacesCache = createDebug.namespaces;
|
|
683
|
+
enabledCache = createDebug.enabled(namespace);
|
|
684
|
+
}
|
|
685
|
+
return enabledCache;
|
|
686
|
+
},
|
|
687
|
+
set: (v) => {
|
|
688
|
+
enableOverride = v;
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
if (typeof createDebug.init === "function") {
|
|
692
|
+
createDebug.init(debug);
|
|
693
|
+
}
|
|
694
|
+
return debug;
|
|
695
|
+
}
|
|
696
|
+
function extend(namespace, delimiter) {
|
|
697
|
+
const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace);
|
|
698
|
+
newDebug.log = this.log;
|
|
699
|
+
return newDebug;
|
|
700
|
+
}
|
|
701
|
+
function enable(namespaces) {
|
|
702
|
+
createDebug.save(namespaces);
|
|
703
|
+
createDebug.namespaces = namespaces;
|
|
704
|
+
createDebug.names = [];
|
|
705
|
+
createDebug.skips = [];
|
|
706
|
+
const split = (typeof namespaces === "string" ? namespaces : "").trim().replace(/\s+/g, ",").split(",").filter(Boolean);
|
|
707
|
+
for (const ns of split) {
|
|
708
|
+
if (ns[0] === "-") {
|
|
709
|
+
createDebug.skips.push(ns.slice(1));
|
|
710
|
+
} else {
|
|
711
|
+
createDebug.names.push(ns);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
function matchesTemplate(search, template) {
|
|
716
|
+
let searchIndex = 0;
|
|
717
|
+
let templateIndex = 0;
|
|
718
|
+
let starIndex = -1;
|
|
719
|
+
let matchIndex = 0;
|
|
720
|
+
while (searchIndex < search.length) {
|
|
721
|
+
if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) {
|
|
722
|
+
if (template[templateIndex] === "*") {
|
|
723
|
+
starIndex = templateIndex;
|
|
724
|
+
matchIndex = searchIndex;
|
|
725
|
+
templateIndex++;
|
|
726
|
+
} else {
|
|
727
|
+
searchIndex++;
|
|
728
|
+
templateIndex++;
|
|
729
|
+
}
|
|
730
|
+
} else if (starIndex !== -1) {
|
|
731
|
+
templateIndex = starIndex + 1;
|
|
732
|
+
matchIndex++;
|
|
733
|
+
searchIndex = matchIndex;
|
|
734
|
+
} else {
|
|
735
|
+
return false;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
while (templateIndex < template.length && template[templateIndex] === "*") {
|
|
739
|
+
templateIndex++;
|
|
740
|
+
}
|
|
741
|
+
return templateIndex === template.length;
|
|
742
|
+
}
|
|
743
|
+
function disable() {
|
|
744
|
+
const namespaces = [
|
|
745
|
+
...createDebug.names,
|
|
746
|
+
...createDebug.skips.map((namespace) => "-" + namespace)
|
|
747
|
+
].join(",");
|
|
748
|
+
createDebug.enable("");
|
|
749
|
+
return namespaces;
|
|
750
|
+
}
|
|
751
|
+
function enabled(name) {
|
|
752
|
+
for (const skip of createDebug.skips) {
|
|
753
|
+
if (matchesTemplate(name, skip)) {
|
|
754
|
+
return false;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
for (const ns of createDebug.names) {
|
|
758
|
+
if (matchesTemplate(name, ns)) {
|
|
759
|
+
return true;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
return false;
|
|
763
|
+
}
|
|
764
|
+
function coerce(val) {
|
|
765
|
+
if (val instanceof Error) {
|
|
766
|
+
return val.stack || val.message;
|
|
767
|
+
}
|
|
768
|
+
return val;
|
|
769
|
+
}
|
|
770
|
+
function destroy() {
|
|
771
|
+
console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
|
|
772
|
+
}
|
|
773
|
+
createDebug.enable(createDebug.load());
|
|
774
|
+
return createDebug;
|
|
775
|
+
}
|
|
776
|
+
module.exports = setup;
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
// ../../node_modules/debug/src/browser.js
|
|
780
|
+
var require_browser = __commonJS((exports, module) => {
|
|
781
|
+
exports.formatArgs = formatArgs;
|
|
782
|
+
exports.save = save;
|
|
783
|
+
exports.load = load;
|
|
784
|
+
exports.useColors = useColors;
|
|
785
|
+
exports.storage = localstorage();
|
|
786
|
+
exports.destroy = (() => {
|
|
787
|
+
let warned = false;
|
|
788
|
+
return () => {
|
|
789
|
+
if (!warned) {
|
|
790
|
+
warned = true;
|
|
791
|
+
console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
|
|
792
|
+
}
|
|
793
|
+
};
|
|
794
|
+
})();
|
|
795
|
+
exports.colors = [
|
|
796
|
+
"#0000CC",
|
|
797
|
+
"#0000FF",
|
|
798
|
+
"#0033CC",
|
|
799
|
+
"#0033FF",
|
|
800
|
+
"#0066CC",
|
|
801
|
+
"#0066FF",
|
|
802
|
+
"#0099CC",
|
|
803
|
+
"#0099FF",
|
|
804
|
+
"#00CC00",
|
|
805
|
+
"#00CC33",
|
|
806
|
+
"#00CC66",
|
|
807
|
+
"#00CC99",
|
|
808
|
+
"#00CCCC",
|
|
809
|
+
"#00CCFF",
|
|
810
|
+
"#3300CC",
|
|
811
|
+
"#3300FF",
|
|
812
|
+
"#3333CC",
|
|
813
|
+
"#3333FF",
|
|
814
|
+
"#3366CC",
|
|
815
|
+
"#3366FF",
|
|
816
|
+
"#3399CC",
|
|
817
|
+
"#3399FF",
|
|
818
|
+
"#33CC00",
|
|
819
|
+
"#33CC33",
|
|
820
|
+
"#33CC66",
|
|
821
|
+
"#33CC99",
|
|
822
|
+
"#33CCCC",
|
|
823
|
+
"#33CCFF",
|
|
824
|
+
"#6600CC",
|
|
825
|
+
"#6600FF",
|
|
826
|
+
"#6633CC",
|
|
827
|
+
"#6633FF",
|
|
828
|
+
"#66CC00",
|
|
829
|
+
"#66CC33",
|
|
830
|
+
"#9900CC",
|
|
831
|
+
"#9900FF",
|
|
832
|
+
"#9933CC",
|
|
833
|
+
"#9933FF",
|
|
834
|
+
"#99CC00",
|
|
835
|
+
"#99CC33",
|
|
836
|
+
"#CC0000",
|
|
837
|
+
"#CC0033",
|
|
838
|
+
"#CC0066",
|
|
839
|
+
"#CC0099",
|
|
840
|
+
"#CC00CC",
|
|
841
|
+
"#CC00FF",
|
|
842
|
+
"#CC3300",
|
|
843
|
+
"#CC3333",
|
|
844
|
+
"#CC3366",
|
|
845
|
+
"#CC3399",
|
|
846
|
+
"#CC33CC",
|
|
847
|
+
"#CC33FF",
|
|
848
|
+
"#CC6600",
|
|
849
|
+
"#CC6633",
|
|
850
|
+
"#CC9900",
|
|
851
|
+
"#CC9933",
|
|
852
|
+
"#CCCC00",
|
|
853
|
+
"#CCCC33",
|
|
854
|
+
"#FF0000",
|
|
855
|
+
"#FF0033",
|
|
856
|
+
"#FF0066",
|
|
857
|
+
"#FF0099",
|
|
858
|
+
"#FF00CC",
|
|
859
|
+
"#FF00FF",
|
|
860
|
+
"#FF3300",
|
|
861
|
+
"#FF3333",
|
|
862
|
+
"#FF3366",
|
|
863
|
+
"#FF3399",
|
|
864
|
+
"#FF33CC",
|
|
865
|
+
"#FF33FF",
|
|
866
|
+
"#FF6600",
|
|
867
|
+
"#FF6633",
|
|
868
|
+
"#FF9900",
|
|
869
|
+
"#FF9933",
|
|
870
|
+
"#FFCC00",
|
|
871
|
+
"#FFCC33"
|
|
872
|
+
];
|
|
873
|
+
function useColors() {
|
|
874
|
+
if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) {
|
|
875
|
+
return true;
|
|
876
|
+
}
|
|
877
|
+
if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
|
|
878
|
+
return false;
|
|
879
|
+
}
|
|
880
|
+
let m;
|
|
881
|
+
return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || typeof navigator !== "undefined" && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31 || typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
|
|
882
|
+
}
|
|
883
|
+
function formatArgs(args) {
|
|
884
|
+
args[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args[0] + (this.useColors ? "%c " : " ") + "+" + module.exports.humanize(this.diff);
|
|
885
|
+
if (!this.useColors) {
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
const c = "color: " + this.color;
|
|
889
|
+
args.splice(1, 0, c, "color: inherit");
|
|
890
|
+
let index = 0;
|
|
891
|
+
let lastC = 0;
|
|
892
|
+
args[0].replace(/%[a-zA-Z%]/g, (match) => {
|
|
893
|
+
if (match === "%%") {
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
index++;
|
|
897
|
+
if (match === "%c") {
|
|
898
|
+
lastC = index;
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
args.splice(lastC, 0, c);
|
|
902
|
+
}
|
|
903
|
+
exports.log = console.debug || console.log || (() => {});
|
|
904
|
+
function save(namespaces) {
|
|
905
|
+
try {
|
|
906
|
+
if (namespaces) {
|
|
907
|
+
exports.storage.setItem("debug", namespaces);
|
|
908
|
+
} else {
|
|
909
|
+
exports.storage.removeItem("debug");
|
|
910
|
+
}
|
|
911
|
+
} catch (error) {}
|
|
912
|
+
}
|
|
913
|
+
function load() {
|
|
914
|
+
let r;
|
|
915
|
+
try {
|
|
916
|
+
r = exports.storage.getItem("debug") || exports.storage.getItem("DEBUG");
|
|
917
|
+
} catch (error) {}
|
|
918
|
+
if (!r && typeof process !== "undefined" && "env" in process) {
|
|
919
|
+
r = process.env.DEBUG;
|
|
920
|
+
}
|
|
921
|
+
return r;
|
|
922
|
+
}
|
|
923
|
+
function localstorage() {
|
|
924
|
+
try {
|
|
925
|
+
return localStorage;
|
|
926
|
+
} catch (error) {}
|
|
927
|
+
}
|
|
928
|
+
module.exports = require_common()(exports);
|
|
929
|
+
var { formatters } = module.exports;
|
|
930
|
+
formatters.j = function(v) {
|
|
931
|
+
try {
|
|
932
|
+
return JSON.stringify(v);
|
|
933
|
+
} catch (error) {
|
|
934
|
+
return "[UnexpectedJSONParseError]: " + error.message;
|
|
935
|
+
}
|
|
936
|
+
};
|
|
937
|
+
});
|
|
938
|
+
|
|
939
|
+
// ../../node_modules/has-flag/index.js
|
|
940
|
+
var require_has_flag = __commonJS((exports, module) => {
|
|
941
|
+
module.exports = (flag, argv = process.argv) => {
|
|
942
|
+
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
943
|
+
const position = argv.indexOf(prefix + flag);
|
|
944
|
+
const terminatorPosition = argv.indexOf("--");
|
|
945
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
946
|
+
};
|
|
947
|
+
});
|
|
948
|
+
|
|
949
|
+
// ../../node_modules/supports-color/index.js
|
|
950
|
+
var require_supports_color = __commonJS((exports, module) => {
|
|
951
|
+
var os = __require("os");
|
|
952
|
+
var tty = __require("tty");
|
|
953
|
+
var hasFlag = require_has_flag();
|
|
954
|
+
var { env } = process;
|
|
955
|
+
var flagForceColor;
|
|
956
|
+
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
957
|
+
flagForceColor = 0;
|
|
958
|
+
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
959
|
+
flagForceColor = 1;
|
|
960
|
+
}
|
|
961
|
+
function envForceColor() {
|
|
962
|
+
if ("FORCE_COLOR" in env) {
|
|
963
|
+
if (env.FORCE_COLOR === "true") {
|
|
964
|
+
return 1;
|
|
965
|
+
}
|
|
966
|
+
if (env.FORCE_COLOR === "false") {
|
|
967
|
+
return 0;
|
|
968
|
+
}
|
|
969
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
function translateLevel(level) {
|
|
973
|
+
if (level === 0) {
|
|
974
|
+
return false;
|
|
975
|
+
}
|
|
976
|
+
return {
|
|
977
|
+
level,
|
|
978
|
+
hasBasic: true,
|
|
979
|
+
has256: level >= 2,
|
|
980
|
+
has16m: level >= 3
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
function supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
984
|
+
const noFlagForceColor = envForceColor();
|
|
985
|
+
if (noFlagForceColor !== undefined) {
|
|
986
|
+
flagForceColor = noFlagForceColor;
|
|
987
|
+
}
|
|
988
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
989
|
+
if (forceColor === 0) {
|
|
990
|
+
return 0;
|
|
991
|
+
}
|
|
992
|
+
if (sniffFlags) {
|
|
993
|
+
if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
|
|
994
|
+
return 3;
|
|
995
|
+
}
|
|
996
|
+
if (hasFlag("color=256")) {
|
|
997
|
+
return 2;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
if (haveStream && !streamIsTTY && forceColor === undefined) {
|
|
1001
|
+
return 0;
|
|
1002
|
+
}
|
|
1003
|
+
const min = forceColor || 0;
|
|
1004
|
+
if (env.TERM === "dumb") {
|
|
1005
|
+
return min;
|
|
1006
|
+
}
|
|
1007
|
+
if (process.platform === "win32") {
|
|
1008
|
+
const osRelease = os.release().split(".");
|
|
1009
|
+
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
1010
|
+
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
1011
|
+
}
|
|
1012
|
+
return 1;
|
|
1013
|
+
}
|
|
1014
|
+
if ("CI" in env) {
|
|
1015
|
+
if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE", "DRONE"].some((sign) => (sign in env)) || env.CI_NAME === "codeship") {
|
|
1016
|
+
return 1;
|
|
1017
|
+
}
|
|
1018
|
+
return min;
|
|
1019
|
+
}
|
|
1020
|
+
if ("TEAMCITY_VERSION" in env) {
|
|
1021
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
1022
|
+
}
|
|
1023
|
+
if (env.COLORTERM === "truecolor") {
|
|
1024
|
+
return 3;
|
|
1025
|
+
}
|
|
1026
|
+
if ("TERM_PROGRAM" in env) {
|
|
1027
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
1028
|
+
switch (env.TERM_PROGRAM) {
|
|
1029
|
+
case "iTerm.app":
|
|
1030
|
+
return version >= 3 ? 3 : 2;
|
|
1031
|
+
case "Apple_Terminal":
|
|
1032
|
+
return 2;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
if (/-256(color)?$/i.test(env.TERM)) {
|
|
1036
|
+
return 2;
|
|
1037
|
+
}
|
|
1038
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
1039
|
+
return 1;
|
|
1040
|
+
}
|
|
1041
|
+
if ("COLORTERM" in env) {
|
|
1042
|
+
return 1;
|
|
1043
|
+
}
|
|
1044
|
+
return min;
|
|
1045
|
+
}
|
|
1046
|
+
function getSupportLevel(stream, options = {}) {
|
|
1047
|
+
const level = supportsColor(stream, {
|
|
1048
|
+
streamIsTTY: stream && stream.isTTY,
|
|
1049
|
+
...options
|
|
1050
|
+
});
|
|
1051
|
+
return translateLevel(level);
|
|
1052
|
+
}
|
|
1053
|
+
module.exports = {
|
|
1054
|
+
supportsColor: getSupportLevel,
|
|
1055
|
+
stdout: getSupportLevel({ isTTY: tty.isatty(1) }),
|
|
1056
|
+
stderr: getSupportLevel({ isTTY: tty.isatty(2) })
|
|
1057
|
+
};
|
|
1058
|
+
});
|
|
1059
|
+
|
|
1060
|
+
// ../../node_modules/debug/src/node.js
|
|
1061
|
+
var require_node = __commonJS((exports, module) => {
|
|
1062
|
+
var tty = __require("tty");
|
|
1063
|
+
var util = __require("util");
|
|
1064
|
+
exports.init = init;
|
|
1065
|
+
exports.log = log;
|
|
1066
|
+
exports.formatArgs = formatArgs;
|
|
1067
|
+
exports.save = save;
|
|
1068
|
+
exports.load = load;
|
|
1069
|
+
exports.useColors = useColors;
|
|
1070
|
+
exports.destroy = util.deprecate(() => {}, "Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
|
|
1071
|
+
exports.colors = [6, 2, 3, 4, 5, 1];
|
|
1072
|
+
try {
|
|
1073
|
+
const supportsColor = require_supports_color();
|
|
1074
|
+
if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
|
|
1075
|
+
exports.colors = [
|
|
1076
|
+
20,
|
|
1077
|
+
21,
|
|
1078
|
+
26,
|
|
1079
|
+
27,
|
|
1080
|
+
32,
|
|
1081
|
+
33,
|
|
1082
|
+
38,
|
|
1083
|
+
39,
|
|
1084
|
+
40,
|
|
1085
|
+
41,
|
|
1086
|
+
42,
|
|
1087
|
+
43,
|
|
1088
|
+
44,
|
|
1089
|
+
45,
|
|
1090
|
+
56,
|
|
1091
|
+
57,
|
|
1092
|
+
62,
|
|
1093
|
+
63,
|
|
1094
|
+
68,
|
|
1095
|
+
69,
|
|
1096
|
+
74,
|
|
1097
|
+
75,
|
|
1098
|
+
76,
|
|
1099
|
+
77,
|
|
1100
|
+
78,
|
|
1101
|
+
79,
|
|
1102
|
+
80,
|
|
1103
|
+
81,
|
|
1104
|
+
92,
|
|
1105
|
+
93,
|
|
1106
|
+
98,
|
|
1107
|
+
99,
|
|
1108
|
+
112,
|
|
1109
|
+
113,
|
|
1110
|
+
128,
|
|
1111
|
+
129,
|
|
1112
|
+
134,
|
|
1113
|
+
135,
|
|
1114
|
+
148,
|
|
1115
|
+
149,
|
|
1116
|
+
160,
|
|
1117
|
+
161,
|
|
1118
|
+
162,
|
|
1119
|
+
163,
|
|
1120
|
+
164,
|
|
1121
|
+
165,
|
|
1122
|
+
166,
|
|
1123
|
+
167,
|
|
1124
|
+
168,
|
|
1125
|
+
169,
|
|
1126
|
+
170,
|
|
1127
|
+
171,
|
|
1128
|
+
172,
|
|
1129
|
+
173,
|
|
1130
|
+
178,
|
|
1131
|
+
179,
|
|
1132
|
+
184,
|
|
1133
|
+
185,
|
|
1134
|
+
196,
|
|
1135
|
+
197,
|
|
1136
|
+
198,
|
|
1137
|
+
199,
|
|
1138
|
+
200,
|
|
1139
|
+
201,
|
|
1140
|
+
202,
|
|
1141
|
+
203,
|
|
1142
|
+
204,
|
|
1143
|
+
205,
|
|
1144
|
+
206,
|
|
1145
|
+
207,
|
|
1146
|
+
208,
|
|
1147
|
+
209,
|
|
1148
|
+
214,
|
|
1149
|
+
215,
|
|
1150
|
+
220,
|
|
1151
|
+
221
|
|
1152
|
+
];
|
|
1153
|
+
}
|
|
1154
|
+
} catch (error) {}
|
|
1155
|
+
exports.inspectOpts = Object.keys(process.env).filter((key) => {
|
|
1156
|
+
return /^debug_/i.test(key);
|
|
1157
|
+
}).reduce((obj, key) => {
|
|
1158
|
+
const prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, (_, k) => {
|
|
1159
|
+
return k.toUpperCase();
|
|
1160
|
+
});
|
|
1161
|
+
let val = process.env[key];
|
|
1162
|
+
if (/^(yes|on|true|enabled)$/i.test(val)) {
|
|
1163
|
+
val = true;
|
|
1164
|
+
} else if (/^(no|off|false|disabled)$/i.test(val)) {
|
|
1165
|
+
val = false;
|
|
1166
|
+
} else if (val === "null") {
|
|
1167
|
+
val = null;
|
|
1168
|
+
} else {
|
|
1169
|
+
val = Number(val);
|
|
1170
|
+
}
|
|
1171
|
+
obj[prop] = val;
|
|
1172
|
+
return obj;
|
|
1173
|
+
}, {});
|
|
1174
|
+
function useColors() {
|
|
1175
|
+
return "colors" in exports.inspectOpts ? Boolean(exports.inspectOpts.colors) : tty.isatty(process.stderr.fd);
|
|
1176
|
+
}
|
|
1177
|
+
function formatArgs(args) {
|
|
1178
|
+
const { namespace: name, useColors: useColors2 } = this;
|
|
1179
|
+
if (useColors2) {
|
|
1180
|
+
const c = this.color;
|
|
1181
|
+
const colorCode = "\x1B[3" + (c < 8 ? c : "8;5;" + c);
|
|
1182
|
+
const prefix = ` ${colorCode};1m${name} \x1B[0m`;
|
|
1183
|
+
args[0] = prefix + args[0].split(`
|
|
1184
|
+
`).join(`
|
|
1185
|
+
` + prefix);
|
|
1186
|
+
args.push(colorCode + "m+" + module.exports.humanize(this.diff) + "\x1B[0m");
|
|
1187
|
+
} else {
|
|
1188
|
+
args[0] = getDate() + name + " " + args[0];
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
function getDate() {
|
|
1192
|
+
if (exports.inspectOpts.hideDate) {
|
|
1193
|
+
return "";
|
|
1194
|
+
}
|
|
1195
|
+
return new Date().toISOString() + " ";
|
|
1196
|
+
}
|
|
1197
|
+
function log(...args) {
|
|
1198
|
+
return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + `
|
|
1199
|
+
`);
|
|
1200
|
+
}
|
|
1201
|
+
function save(namespaces) {
|
|
1202
|
+
if (namespaces) {
|
|
1203
|
+
process.env.DEBUG = namespaces;
|
|
1204
|
+
} else {
|
|
1205
|
+
delete process.env.DEBUG;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
function load() {
|
|
1209
|
+
return process.env.DEBUG;
|
|
1210
|
+
}
|
|
1211
|
+
function init(debug) {
|
|
1212
|
+
debug.inspectOpts = {};
|
|
1213
|
+
const keys = Object.keys(exports.inspectOpts);
|
|
1214
|
+
for (let i = 0;i < keys.length; i++) {
|
|
1215
|
+
debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
module.exports = require_common()(exports);
|
|
1219
|
+
var { formatters } = module.exports;
|
|
1220
|
+
formatters.o = function(v) {
|
|
1221
|
+
this.inspectOpts.colors = this.useColors;
|
|
1222
|
+
return util.inspect(v, this.inspectOpts).split(`
|
|
1223
|
+
`).map((str) => str.trim()).join(" ");
|
|
1224
|
+
};
|
|
1225
|
+
formatters.O = function(v) {
|
|
1226
|
+
this.inspectOpts.colors = this.useColors;
|
|
1227
|
+
return util.inspect(v, this.inspectOpts);
|
|
1228
|
+
};
|
|
1229
|
+
});
|
|
1230
|
+
|
|
1231
|
+
// ../../node_modules/debug/src/index.js
|
|
1232
|
+
var require_src = __commonJS((exports, module) => {
|
|
1233
|
+
if (typeof process === "undefined" || process.type === "renderer" || false || process.__nwjs) {
|
|
1234
|
+
module.exports = require_browser();
|
|
1235
|
+
} else {
|
|
1236
|
+
module.exports = require_node();
|
|
1237
|
+
}
|
|
1238
|
+
});
|
|
1239
|
+
|
|
1240
|
+
// src/octal-hack.js
|
|
1241
|
+
var require_octal_hack = __commonJS((exports, module) => {
|
|
1242
|
+
module.exports = (content) => {
|
|
1243
|
+
return "\x01ACTION " + content + "\x01";
|
|
1244
|
+
};
|
|
1245
|
+
});
|
|
1246
|
+
|
|
1247
|
+
// src/index.ts
|
|
1248
|
+
var import_irc_socket_sasl = __toESM(require_irc_socket(), 1);
|
|
1249
|
+
import net from "node:net";
|
|
1250
|
+
import tls from "node:tls";
|
|
1251
|
+
|
|
1252
|
+
// ../irc2as/src/index.js
|
|
1253
|
+
var import_debug = __toESM(require_src(), 1);
|
|
1254
|
+
import events from "node:events";
|
|
1255
|
+
|
|
1256
|
+
// ../irc2as/src/as-emitter.js
|
|
1257
|
+
var EVENT_INCOMING = "incoming";
|
|
1258
|
+
var EVENT_ERROR = "error";
|
|
1259
|
+
|
|
1260
|
+
class ASEmitter {
|
|
1261
|
+
constructor(events, server) {
|
|
1262
|
+
this.server = server;
|
|
1263
|
+
this.events = events;
|
|
1264
|
+
}
|
|
1265
|
+
emitEvent(code, asObject) {
|
|
1266
|
+
if (typeof asObject === "object" && !asObject.published) {
|
|
1267
|
+
asObject.published = `${Date.now()}`;
|
|
1268
|
+
}
|
|
1269
|
+
this.events.emit(code, asObject);
|
|
1270
|
+
}
|
|
1271
|
+
__generalError(nick, content) {
|
|
1272
|
+
return {
|
|
1273
|
+
context: "irc",
|
|
1274
|
+
type: "update",
|
|
1275
|
+
actor: {
|
|
1276
|
+
type: "person",
|
|
1277
|
+
id: `${nick}@${this.server}`,
|
|
1278
|
+
name: nick
|
|
1279
|
+
},
|
|
1280
|
+
target: {
|
|
1281
|
+
type: "service",
|
|
1282
|
+
id: this.server
|
|
1283
|
+
},
|
|
1284
|
+
error: content
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
presence(nick, role, channel) {
|
|
1288
|
+
this.emitEvent(EVENT_INCOMING, {
|
|
1289
|
+
context: "irc",
|
|
1290
|
+
type: "update",
|
|
1291
|
+
actor: {
|
|
1292
|
+
type: "person",
|
|
1293
|
+
id: `${nick}@${this.server}`,
|
|
1294
|
+
name: nick
|
|
1295
|
+
},
|
|
1296
|
+
target: {
|
|
1297
|
+
type: "room",
|
|
1298
|
+
id: `${this.server}/${channel}`,
|
|
1299
|
+
name: channel
|
|
1300
|
+
},
|
|
1301
|
+
object: {
|
|
1302
|
+
type: "presence",
|
|
1303
|
+
role
|
|
1304
|
+
}
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
channelError(channel, nick, content) {
|
|
1308
|
+
this.emitEvent(EVENT_ERROR, {
|
|
1309
|
+
context: "irc",
|
|
1310
|
+
type: "update",
|
|
1311
|
+
actor: {
|
|
1312
|
+
type: "person",
|
|
1313
|
+
id: `${nick}@${this.server}`
|
|
1314
|
+
},
|
|
1315
|
+
target: {
|
|
1316
|
+
type: "room",
|
|
1317
|
+
id: `${this.server}/${channel}`
|
|
1318
|
+
},
|
|
1319
|
+
error: content
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
nickError(nick, content) {
|
|
1323
|
+
this.emitEvent(EVENT_ERROR, this.__generalError(nick, content));
|
|
1324
|
+
}
|
|
1325
|
+
notice(nick, content) {
|
|
1326
|
+
this.emitEvent(EVENT_INCOMING, {
|
|
1327
|
+
context: "irc",
|
|
1328
|
+
type: "send",
|
|
1329
|
+
actor: {
|
|
1330
|
+
type: "service",
|
|
1331
|
+
id: this.server
|
|
1332
|
+
},
|
|
1333
|
+
object: {
|
|
1334
|
+
type: "message",
|
|
1335
|
+
content
|
|
1336
|
+
},
|
|
1337
|
+
target: {
|
|
1338
|
+
type: "person",
|
|
1339
|
+
id: `${nick}@${this.server}`,
|
|
1340
|
+
name: nick
|
|
1341
|
+
}
|
|
1342
|
+
});
|
|
1343
|
+
}
|
|
1344
|
+
serviceError(nick, content) {
|
|
1345
|
+
this.emitEvent(EVENT_ERROR, this.__generalError(nick, content));
|
|
1346
|
+
}
|
|
1347
|
+
joinError(nick) {
|
|
1348
|
+
this.emitEvent(EVENT_ERROR, {
|
|
1349
|
+
context: "irc",
|
|
1350
|
+
type: "join",
|
|
1351
|
+
actor: {
|
|
1352
|
+
id: this.server,
|
|
1353
|
+
type: "service"
|
|
1354
|
+
},
|
|
1355
|
+
error: `no such channel ${nick}`,
|
|
1356
|
+
target: {
|
|
1357
|
+
id: `${nick}@${this.server}`,
|
|
1358
|
+
type: "person"
|
|
1359
|
+
}
|
|
1360
|
+
});
|
|
1361
|
+
}
|
|
1362
|
+
topicChange(channel, nick, content) {
|
|
1363
|
+
this.emitEvent(EVENT_INCOMING, {
|
|
1364
|
+
context: "irc",
|
|
1365
|
+
type: "update",
|
|
1366
|
+
actor: {
|
|
1367
|
+
type: "person",
|
|
1368
|
+
id: `${nick}@${this.server}`,
|
|
1369
|
+
name: nick
|
|
1370
|
+
},
|
|
1371
|
+
target: {
|
|
1372
|
+
type: "room",
|
|
1373
|
+
id: `${this.server}/${channel}`,
|
|
1374
|
+
name: channel
|
|
1375
|
+
},
|
|
1376
|
+
object: {
|
|
1377
|
+
type: "topic",
|
|
1378
|
+
content
|
|
1379
|
+
}
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
joinRoom(channel, nick) {
|
|
1383
|
+
this.emitEvent(EVENT_INCOMING, {
|
|
1384
|
+
context: "irc",
|
|
1385
|
+
type: "join",
|
|
1386
|
+
actor: {
|
|
1387
|
+
type: "person",
|
|
1388
|
+
id: `${nick}@${this.server}`,
|
|
1389
|
+
name: nick
|
|
1390
|
+
},
|
|
1391
|
+
target: {
|
|
1392
|
+
type: "room",
|
|
1393
|
+
id: `${this.server}/${channel}`,
|
|
1394
|
+
name: channel
|
|
1395
|
+
}
|
|
1396
|
+
});
|
|
1397
|
+
}
|
|
1398
|
+
userQuit(nick) {
|
|
1399
|
+
this.emitEvent(EVENT_INCOMING, {
|
|
1400
|
+
context: "irc",
|
|
1401
|
+
type: "leave",
|
|
1402
|
+
actor: {
|
|
1403
|
+
type: "person",
|
|
1404
|
+
id: `${nick}@${this.server}`,
|
|
1405
|
+
name: nick
|
|
1406
|
+
},
|
|
1407
|
+
target: {
|
|
1408
|
+
type: "service",
|
|
1409
|
+
id: this.server
|
|
1410
|
+
},
|
|
1411
|
+
object: {
|
|
1412
|
+
type: "message",
|
|
1413
|
+
content: "user has quit"
|
|
1414
|
+
}
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
userPart(channel, nick) {
|
|
1418
|
+
this.emitEvent(EVENT_INCOMING, {
|
|
1419
|
+
context: "irc",
|
|
1420
|
+
type: "leave",
|
|
1421
|
+
actor: {
|
|
1422
|
+
type: "person",
|
|
1423
|
+
id: `${nick}@${this.server}`,
|
|
1424
|
+
name: nick
|
|
1425
|
+
},
|
|
1426
|
+
target: {
|
|
1427
|
+
type: "room",
|
|
1428
|
+
id: `${this.server}/${channel}`,
|
|
1429
|
+
name: channel
|
|
1430
|
+
},
|
|
1431
|
+
object: {
|
|
1432
|
+
type: "message",
|
|
1433
|
+
content: "user has left the channel"
|
|
1434
|
+
}
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
privMsg(nick, target, content) {
|
|
1438
|
+
let type;
|
|
1439
|
+
let message;
|
|
1440
|
+
if (content.startsWith("+\x01ACTION ")) {
|
|
1441
|
+
type = "me";
|
|
1442
|
+
message = content.split(/^\+\u0001ACTION\s+/)[1].split(/\u0001$/)[0];
|
|
1443
|
+
} else {
|
|
1444
|
+
type = "message";
|
|
1445
|
+
message = content;
|
|
1446
|
+
}
|
|
1447
|
+
this.emitEvent(EVENT_INCOMING, {
|
|
1448
|
+
context: "irc",
|
|
1449
|
+
type: "send",
|
|
1450
|
+
actor: {
|
|
1451
|
+
type: "person",
|
|
1452
|
+
id: `${nick}@${this.server}`,
|
|
1453
|
+
name: nick
|
|
1454
|
+
},
|
|
1455
|
+
target: {
|
|
1456
|
+
type: target.startsWith("#") ? "room" : "person",
|
|
1457
|
+
id: `${this.server}/${target}`,
|
|
1458
|
+
name: target
|
|
1459
|
+
},
|
|
1460
|
+
object: {
|
|
1461
|
+
type,
|
|
1462
|
+
content: message
|
|
1463
|
+
}
|
|
1464
|
+
});
|
|
1465
|
+
}
|
|
1466
|
+
role(type, nick, target, role, channel) {
|
|
1467
|
+
this.emitEvent(EVENT_INCOMING, {
|
|
1468
|
+
context: "irc",
|
|
1469
|
+
type,
|
|
1470
|
+
actor: {
|
|
1471
|
+
type: "person",
|
|
1472
|
+
id: `${nick}@${this.server}`,
|
|
1473
|
+
name: nick
|
|
1474
|
+
},
|
|
1475
|
+
target: {
|
|
1476
|
+
type: "person",
|
|
1477
|
+
id: `${target}@${this.server}`,
|
|
1478
|
+
name: target
|
|
1479
|
+
},
|
|
1480
|
+
object: {
|
|
1481
|
+
type: "relationship",
|
|
1482
|
+
relationship: "role",
|
|
1483
|
+
subject: {
|
|
1484
|
+
type: "presence",
|
|
1485
|
+
role
|
|
1486
|
+
},
|
|
1487
|
+
object: {
|
|
1488
|
+
type: "room",
|
|
1489
|
+
id: `${this.server}/${channel}`,
|
|
1490
|
+
name: channel
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
});
|
|
1494
|
+
}
|
|
1495
|
+
nickChange(nick, content) {
|
|
1496
|
+
this.emitEvent(EVENT_INCOMING, {
|
|
1497
|
+
context: "irc",
|
|
1498
|
+
type: "update",
|
|
1499
|
+
actor: {
|
|
1500
|
+
type: "person",
|
|
1501
|
+
id: `${nick}@${this.server}`,
|
|
1502
|
+
name: nick
|
|
1503
|
+
},
|
|
1504
|
+
target: {
|
|
1505
|
+
type: "person",
|
|
1506
|
+
id: `${content}@${this.server}`,
|
|
1507
|
+
name: content
|
|
1508
|
+
},
|
|
1509
|
+
object: {
|
|
1510
|
+
type: "address"
|
|
1511
|
+
}
|
|
1512
|
+
});
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
// ../irc2as/src/index.js
|
|
1517
|
+
var log = import_debug.default("irc2as");
|
|
1518
|
+
var EVENT_INCOMING2 = "incoming";
|
|
1519
|
+
var EVENT_PONG = "pong";
|
|
1520
|
+
var EVENT_PING = "ping";
|
|
1521
|
+
var EVENT_UNPROCESSED = "unprocessed";
|
|
1522
|
+
var ERR_BAD_NICK = "432";
|
|
1523
|
+
var ERR_CHAN_PRIVS = "482";
|
|
1524
|
+
var ERR_NICK_IN_USE = "433";
|
|
1525
|
+
var ERR_TEMP_UNAVAIL = "437";
|
|
1526
|
+
var ERR_NO_CHANNEL = "403";
|
|
1527
|
+
var ERR_NOT_INVITED = "471";
|
|
1528
|
+
var ERR_BADMODE = "472";
|
|
1529
|
+
var ERR_INVITE_ONLY = "473";
|
|
1530
|
+
var ERR_BANNED = "474";
|
|
1531
|
+
var ERR_BADKEY = "475";
|
|
1532
|
+
var ERR_BADMASK = "476";
|
|
1533
|
+
var ERR_NOCHANMODES = "477";
|
|
1534
|
+
var ERR_BANLISTFULL = "478";
|
|
1535
|
+
var JOIN = "JOIN";
|
|
1536
|
+
var MODE = "MODE";
|
|
1537
|
+
var MOTD = "372";
|
|
1538
|
+
var MOTD_END = "376";
|
|
1539
|
+
var NAMES = "353";
|
|
1540
|
+
var NICK = "NICK";
|
|
1541
|
+
var NOTICE = "NOTICE";
|
|
1542
|
+
var PART = "PART";
|
|
1543
|
+
var PING = "PING";
|
|
1544
|
+
var PONG = "PONG";
|
|
1545
|
+
var PRIVMSG = "PRIVMSG";
|
|
1546
|
+
var QUIT = "QUIT";
|
|
1547
|
+
var TOPIC_CHANGE = "TOPIC";
|
|
1548
|
+
var TOPIC_IS = "332";
|
|
1549
|
+
var TOPIC_SET_BY = "333";
|
|
1550
|
+
var WHO = "352";
|
|
1551
|
+
var WHO_OLD = "354";
|
|
1552
|
+
var ROLE = {
|
|
1553
|
+
"@": "owner",
|
|
1554
|
+
"%": "admin",
|
|
1555
|
+
"*": "participant"
|
|
1556
|
+
};
|
|
1557
|
+
var MODES = {
|
|
1558
|
+
o: "owner",
|
|
1559
|
+
h: "admin",
|
|
1560
|
+
v: "participant"
|
|
1561
|
+
};
|
|
1562
|
+
function getNickFromServer(server) {
|
|
1563
|
+
return server.split(/^:/)[1].split("!")[0];
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
class IrcToActivityStreams {
|
|
1567
|
+
constructor(cfg) {
|
|
1568
|
+
const config = cfg || {};
|
|
1569
|
+
this.server = config.server;
|
|
1570
|
+
this.events = new events.EventEmitter;
|
|
1571
|
+
this.__buffer = {};
|
|
1572
|
+
this.__buffer[NAMES] = {};
|
|
1573
|
+
}
|
|
1574
|
+
input(payload) {
|
|
1575
|
+
log(payload);
|
|
1576
|
+
if (typeof payload !== "string") {
|
|
1577
|
+
log("unable to process incoming message as it was not a string.");
|
|
1578
|
+
return false;
|
|
1579
|
+
}
|
|
1580
|
+
if (payload.length < 3) {
|
|
1581
|
+
log("unable to process incoming string, length smaller than 3.");
|
|
1582
|
+
return false;
|
|
1583
|
+
}
|
|
1584
|
+
const incoming = payload.trim();
|
|
1585
|
+
const [metadata, content] = incoming.split(" :");
|
|
1586
|
+
const [server, code, pos1, pos2, pos3, ...msg] = metadata.split(" ");
|
|
1587
|
+
const channel = typeof pos1 === "string" && pos1.startsWith("#") ? pos1 : typeof pos2 === "string" && pos2.startsWith("#") ? pos2 : typeof pos3 === "string" && pos3.startsWith("#") ? pos3 : undefined;
|
|
1588
|
+
if (metadata === PING) {
|
|
1589
|
+
this.events.emit(EVENT_PING, `${Date.now()}`);
|
|
1590
|
+
return true;
|
|
1591
|
+
}
|
|
1592
|
+
log(`[${code}] server: ${server} channel: ${channel} 1: ${pos1}, 2: ${pos2}, 3: ${pos3}. content: `, content);
|
|
1593
|
+
this.__processIRCCodes(code, server, channel, pos1, pos2, pos3, content, msg, incoming);
|
|
1594
|
+
}
|
|
1595
|
+
__processIRCCodes(code, server, channel, pos1, pos2, pos3, content, msg, incoming) {
|
|
1596
|
+
const ase = new ASEmitter(this.events, this.server);
|
|
1597
|
+
let nick;
|
|
1598
|
+
let type;
|
|
1599
|
+
let role;
|
|
1600
|
+
switch (code) {
|
|
1601
|
+
case ERR_CHAN_PRIVS:
|
|
1602
|
+
case ERR_NOT_INVITED:
|
|
1603
|
+
case ERR_BADMODE:
|
|
1604
|
+
case ERR_INVITE_ONLY:
|
|
1605
|
+
case ERR_BANNED:
|
|
1606
|
+
case ERR_BADKEY:
|
|
1607
|
+
case ERR_BADMASK:
|
|
1608
|
+
case ERR_NOCHANMODES:
|
|
1609
|
+
case ERR_BANLISTFULL:
|
|
1610
|
+
ase.channelError(channel, pos1, content);
|
|
1611
|
+
break;
|
|
1612
|
+
case ERR_NICK_IN_USE:
|
|
1613
|
+
case ERR_BAD_NICK:
|
|
1614
|
+
ase.serviceError(pos2, content);
|
|
1615
|
+
break;
|
|
1616
|
+
case ERR_NO_CHANNEL:
|
|
1617
|
+
ase.joinError(pos2);
|
|
1618
|
+
break;
|
|
1619
|
+
case ERR_TEMP_UNAVAIL:
|
|
1620
|
+
ase.nickError(pos2, content);
|
|
1621
|
+
break;
|
|
1622
|
+
case JOIN:
|
|
1623
|
+
ase.joinRoom(channel, getNickFromServer(server));
|
|
1624
|
+
break;
|
|
1625
|
+
case MODE: {
|
|
1626
|
+
const user_mode = pos2 || content;
|
|
1627
|
+
if (!channel) {
|
|
1628
|
+
break;
|
|
1629
|
+
}
|
|
1630
|
+
if (!pos3) {
|
|
1631
|
+
break;
|
|
1632
|
+
}
|
|
1633
|
+
role = MODES[user_mode[1]] || "member";
|
|
1634
|
+
type = "add";
|
|
1635
|
+
if (user_mode[0] === "-") {
|
|
1636
|
+
type = "remove";
|
|
1637
|
+
}
|
|
1638
|
+
ase.role(type, getNickFromServer(server), pos3, role, channel);
|
|
1639
|
+
break;
|
|
1640
|
+
}
|
|
1641
|
+
case MOTD:
|
|
1642
|
+
if (!this.__buffer[MOTD]) {
|
|
1643
|
+
this.__buffer[MOTD] = {
|
|
1644
|
+
context: "irc",
|
|
1645
|
+
type: "update",
|
|
1646
|
+
actor: {
|
|
1647
|
+
type: "service",
|
|
1648
|
+
id: this.server,
|
|
1649
|
+
name: this.server
|
|
1650
|
+
},
|
|
1651
|
+
object: {
|
|
1652
|
+
type: "topic",
|
|
1653
|
+
content
|
|
1654
|
+
}
|
|
1655
|
+
};
|
|
1656
|
+
} else {
|
|
1657
|
+
this.__buffer[MOTD].object.content += ` ${content}`;
|
|
1658
|
+
}
|
|
1659
|
+
break;
|
|
1660
|
+
case MOTD_END:
|
|
1661
|
+
if (!this.__buffer[MOTD]) {
|
|
1662
|
+
break;
|
|
1663
|
+
}
|
|
1664
|
+
ase.emitEvent(EVENT_INCOMING2, this.__buffer[MOTD]);
|
|
1665
|
+
delete this.__buffer[MOTD];
|
|
1666
|
+
break;
|
|
1667
|
+
case NAMES:
|
|
1668
|
+
for (const entry of content.split(" ")) {
|
|
1669
|
+
role = "member";
|
|
1670
|
+
let username = entry;
|
|
1671
|
+
if (ROLE[entry[0]]) {
|
|
1672
|
+
username = entry.substr(1);
|
|
1673
|
+
role = ROLE[entry[0]];
|
|
1674
|
+
}
|
|
1675
|
+
ase.presence(username, role, channel);
|
|
1676
|
+
}
|
|
1677
|
+
break;
|
|
1678
|
+
case NICK:
|
|
1679
|
+
ase.nickChange(getNickFromServer(server), content);
|
|
1680
|
+
break;
|
|
1681
|
+
case NOTICE:
|
|
1682
|
+
ase.notice(pos1, content);
|
|
1683
|
+
break;
|
|
1684
|
+
case PART:
|
|
1685
|
+
ase.userPart(channel, getNickFromServer(server));
|
|
1686
|
+
break;
|
|
1687
|
+
case PONG:
|
|
1688
|
+
this.events.emit(EVENT_PONG, `${Date.now()}`);
|
|
1689
|
+
break;
|
|
1690
|
+
case PRIVMSG:
|
|
1691
|
+
ase.privMsg(getNickFromServer(server), pos1, content);
|
|
1692
|
+
break;
|
|
1693
|
+
case QUIT:
|
|
1694
|
+
ase.userQuit(getNickFromServer(server));
|
|
1695
|
+
break;
|
|
1696
|
+
case TOPIC_CHANGE:
|
|
1697
|
+
ase.topicChange(channel, getNickFromServer(server), content);
|
|
1698
|
+
break;
|
|
1699
|
+
case TOPIC_IS:
|
|
1700
|
+
this.__buffer[TOPIC_IS] = {
|
|
1701
|
+
context: "irc",
|
|
1702
|
+
type: "update",
|
|
1703
|
+
actor: undefined,
|
|
1704
|
+
target: {
|
|
1705
|
+
type: "room",
|
|
1706
|
+
id: `${this.server}/${channel}`,
|
|
1707
|
+
name: channel
|
|
1708
|
+
},
|
|
1709
|
+
object: {
|
|
1710
|
+
type: "topic",
|
|
1711
|
+
content
|
|
1712
|
+
}
|
|
1713
|
+
};
|
|
1714
|
+
break;
|
|
1715
|
+
case TOPIC_SET_BY:
|
|
1716
|
+
if (!this.__buffer[TOPIC_IS]) {
|
|
1717
|
+
break;
|
|
1718
|
+
}
|
|
1719
|
+
nick = pos3.split("!")[0];
|
|
1720
|
+
this.__buffer[TOPIC_IS].actor = {
|
|
1721
|
+
type: "person",
|
|
1722
|
+
id: `${nick}@${this.server}`,
|
|
1723
|
+
name: nick
|
|
1724
|
+
};
|
|
1725
|
+
this.__buffer[TOPIC_IS].published = msg[0];
|
|
1726
|
+
ase.emitEvent(EVENT_INCOMING2, this.__buffer[TOPIC_IS]);
|
|
1727
|
+
delete this.__buffer[TOPIC_IS];
|
|
1728
|
+
break;
|
|
1729
|
+
case WHO:
|
|
1730
|
+
case WHO_OLD:
|
|
1731
|
+
nick = msg[3].length <= 2 ? msg[2] : msg[3];
|
|
1732
|
+
if (nick === "undefined") {
|
|
1733
|
+
break;
|
|
1734
|
+
}
|
|
1735
|
+
role = MODES[pos2[1]] || "member";
|
|
1736
|
+
ase.presence(nick, role, channel);
|
|
1737
|
+
break;
|
|
1738
|
+
default:
|
|
1739
|
+
this.events.emit(EVENT_UNPROCESSED, incoming);
|
|
1740
|
+
break;
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
// package.json
|
|
1745
|
+
var package_default = {
|
|
1746
|
+
name: "@sockethub/platform-irc",
|
|
1747
|
+
description: "A sockethub platform module implementing IRC functionality",
|
|
1748
|
+
version: "4.0.0-alpha.7",
|
|
1749
|
+
private: false,
|
|
1750
|
+
author: "Nick Jennings <nick@silverbucket.net>",
|
|
1751
|
+
license: "LGPL-3.0+",
|
|
1752
|
+
publishConfig: {
|
|
1753
|
+
access: "public"
|
|
1754
|
+
},
|
|
1755
|
+
type: "module",
|
|
1756
|
+
main: "dist/index.js",
|
|
1757
|
+
exports: {
|
|
1758
|
+
".": {
|
|
1759
|
+
bun: "./src/index.ts",
|
|
1760
|
+
import: "./dist/index.js",
|
|
1761
|
+
default: "./dist/index.js"
|
|
1762
|
+
}
|
|
1763
|
+
},
|
|
1764
|
+
files: ["src/", "dist/"],
|
|
1765
|
+
engines: {
|
|
1766
|
+
bun: ">=1.2"
|
|
1767
|
+
},
|
|
1768
|
+
keywords: [
|
|
1769
|
+
"sockethub",
|
|
1770
|
+
"messaging",
|
|
1771
|
+
"activitystreams",
|
|
1772
|
+
"activity",
|
|
1773
|
+
"streams",
|
|
1774
|
+
"protocol",
|
|
1775
|
+
"irc"
|
|
1776
|
+
],
|
|
1777
|
+
repository: {
|
|
1778
|
+
type: "git",
|
|
1779
|
+
url: "git+https://github.com/sockethub/sockethub.git",
|
|
1780
|
+
directory: "packages/platform-irc"
|
|
1781
|
+
},
|
|
1782
|
+
homepage: "https://github.com/sockethub/sockethub/tree/master/packages/platform-irc",
|
|
1783
|
+
scripts: {
|
|
1784
|
+
build: "bun build src/index.ts --outdir dist --target node --format esm --sourcemap=external",
|
|
1785
|
+
clean: "rm -rf dist",
|
|
1786
|
+
doc: "typedoc --options typedoc.json"
|
|
1787
|
+
},
|
|
1788
|
+
dependencies: {
|
|
1789
|
+
"@sockethub/irc2as": "^4.0.0-alpha.7",
|
|
1790
|
+
"irc-socket-sasl": "^4.0.0"
|
|
1791
|
+
},
|
|
1792
|
+
devDependencies: {
|
|
1793
|
+
"@sockethub/schemas": "^3.0.0-alpha.7",
|
|
1794
|
+
"@types/bun": "latest",
|
|
1795
|
+
typedoc: "^0.28.14"
|
|
1796
|
+
},
|
|
1797
|
+
peerDependencies: {
|
|
1798
|
+
"@sockethub/server": "^5.0.0-alpha.6"
|
|
1799
|
+
},
|
|
1800
|
+
peerDependenciesMeta: {
|
|
1801
|
+
"@sockethub/server": {
|
|
1802
|
+
optional: true
|
|
1803
|
+
}
|
|
1804
|
+
},
|
|
1805
|
+
gitHead: "e69e26b98c4bce1279aae4dc356b9a0f7e7de659"
|
|
1806
|
+
};
|
|
1807
|
+
|
|
1808
|
+
// src/schema.ts
|
|
1809
|
+
var version = package_default.version;
|
|
1810
|
+
var PlatformIrcSchema = {
|
|
1811
|
+
name: "irc",
|
|
1812
|
+
version,
|
|
1813
|
+
messages: {
|
|
1814
|
+
required: ["type"],
|
|
1815
|
+
properties: {
|
|
1816
|
+
type: {
|
|
1817
|
+
enum: [
|
|
1818
|
+
"connect",
|
|
1819
|
+
"update",
|
|
1820
|
+
"join",
|
|
1821
|
+
"leave",
|
|
1822
|
+
"send",
|
|
1823
|
+
"query",
|
|
1824
|
+
"announce",
|
|
1825
|
+
"disconnect"
|
|
1826
|
+
]
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
},
|
|
1830
|
+
credentials: {
|
|
1831
|
+
required: ["object"],
|
|
1832
|
+
properties: {
|
|
1833
|
+
actor: {
|
|
1834
|
+
type: "object",
|
|
1835
|
+
required: ["id"]
|
|
1836
|
+
},
|
|
1837
|
+
object: {
|
|
1838
|
+
type: "object",
|
|
1839
|
+
required: ["type", "nick", "server"],
|
|
1840
|
+
additionalProperties: false,
|
|
1841
|
+
properties: {
|
|
1842
|
+
type: {
|
|
1843
|
+
type: "string"
|
|
1844
|
+
},
|
|
1845
|
+
nick: {
|
|
1846
|
+
type: "string"
|
|
1847
|
+
},
|
|
1848
|
+
username: {
|
|
1849
|
+
type: "string"
|
|
1850
|
+
},
|
|
1851
|
+
password: {
|
|
1852
|
+
type: "string"
|
|
1853
|
+
},
|
|
1854
|
+
server: {
|
|
1855
|
+
type: "string"
|
|
1856
|
+
},
|
|
1857
|
+
port: {
|
|
1858
|
+
type: "number"
|
|
1859
|
+
},
|
|
1860
|
+
secure: {
|
|
1861
|
+
type: "boolean"
|
|
1862
|
+
},
|
|
1863
|
+
sasl: {
|
|
1864
|
+
type: "boolean"
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
};
|
|
1871
|
+
|
|
1872
|
+
// src/index.ts
|
|
1873
|
+
class IRC {
|
|
1874
|
+
debug;
|
|
1875
|
+
credentialsHash;
|
|
1876
|
+
config = {
|
|
1877
|
+
persist: true,
|
|
1878
|
+
requireCredentials: ["connect", "update"],
|
|
1879
|
+
initialized: false,
|
|
1880
|
+
connectTimeoutMs: 30000
|
|
1881
|
+
};
|
|
1882
|
+
updateActor;
|
|
1883
|
+
sendToClient;
|
|
1884
|
+
irc2as;
|
|
1885
|
+
forceDisconnect = false;
|
|
1886
|
+
clientConnecting = false;
|
|
1887
|
+
client;
|
|
1888
|
+
jobQueue = [];
|
|
1889
|
+
channels = new Set;
|
|
1890
|
+
handledActors = new Set;
|
|
1891
|
+
constructor(session) {
|
|
1892
|
+
this.debug = session.debug;
|
|
1893
|
+
this.sendToClient = session.sendToClient;
|
|
1894
|
+
this.updateActor = session.updateActor;
|
|
1895
|
+
}
|
|
1896
|
+
get schema() {
|
|
1897
|
+
return PlatformIrcSchema;
|
|
1898
|
+
}
|
|
1899
|
+
connect(job, credentials, done) {
|
|
1900
|
+
this.getClient(job.actor.id, credentials, (err) => {
|
|
1901
|
+
if (err) {
|
|
1902
|
+
return done(err);
|
|
1903
|
+
}
|
|
1904
|
+
return done();
|
|
1905
|
+
});
|
|
1906
|
+
}
|
|
1907
|
+
join(job, done) {
|
|
1908
|
+
this.debug(`join() called for ${job.actor.id}`);
|
|
1909
|
+
this.getClient(job.actor.id, false, (err, client) => {
|
|
1910
|
+
if (err) {
|
|
1911
|
+
return done(err);
|
|
1912
|
+
}
|
|
1913
|
+
if (this.channels.has(job.target.name)) {
|
|
1914
|
+
this.debug(`channel ${job.target.name} already joined`);
|
|
1915
|
+
return done();
|
|
1916
|
+
}
|
|
1917
|
+
this.jobQueue.push(() => {
|
|
1918
|
+
this.hasJoined(job.target.name);
|
|
1919
|
+
done();
|
|
1920
|
+
});
|
|
1921
|
+
this.debug(`sending join ${job.target.name}`);
|
|
1922
|
+
client.raw(["JOIN", job.target.name]);
|
|
1923
|
+
client.raw(`PING ${job.actor.name}`);
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1926
|
+
leave(job, done) {
|
|
1927
|
+
this.debug(`leave() called for ${job.actor.name}`);
|
|
1928
|
+
this.getClient(job.actor.id, false, (err, client) => {
|
|
1929
|
+
if (err) {
|
|
1930
|
+
return done(err);
|
|
1931
|
+
}
|
|
1932
|
+
this.hasLeft(job.target.name);
|
|
1933
|
+
client.raw(["PART", job.target.name]);
|
|
1934
|
+
done();
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
send(job, done) {
|
|
1938
|
+
this.debug(`send() called for ${job.actor.id} target: ${job.target.id}`);
|
|
1939
|
+
this.getClient(job.actor.id, false, async (err, client) => {
|
|
1940
|
+
if (err) {
|
|
1941
|
+
return done(err);
|
|
1942
|
+
}
|
|
1943
|
+
if (typeof job.object.content !== "string") {
|
|
1944
|
+
return done("cannot send message with no object.content");
|
|
1945
|
+
}
|
|
1946
|
+
const match = /(\/\w+)\s*([\s\S]*)/.exec(job.object.content);
|
|
1947
|
+
if (match) {
|
|
1948
|
+
const cmd = match[1].substring(1).toUpperCase();
|
|
1949
|
+
const msg = match[2].trim();
|
|
1950
|
+
if (cmd === "ME") {
|
|
1951
|
+
job.object.type = "me";
|
|
1952
|
+
job.object.content = msg;
|
|
1953
|
+
} else if (cmd === "NOTICE") {
|
|
1954
|
+
job.object.type = "notice";
|
|
1955
|
+
job.object.content = msg;
|
|
1956
|
+
}
|
|
1957
|
+
} else {
|
|
1958
|
+
job.object.content = job.object.content.trim();
|
|
1959
|
+
}
|
|
1960
|
+
if (job.object.type === "me") {
|
|
1961
|
+
const buildCommand = await Promise.resolve().then(() => __toESM(require_octal_hack(), 1));
|
|
1962
|
+
const message = buildCommand(job.object.content);
|
|
1963
|
+
client.raw("PRIVMSG " + job.target.name + " :" + message);
|
|
1964
|
+
return done("IRC commands temporarily disabled");
|
|
1965
|
+
}
|
|
1966
|
+
if (job.object.type === "notice") {
|
|
1967
|
+
client.raw(`NOTICE ${job.target.name} :${job.object.content}`);
|
|
1968
|
+
} else if (this.isJoined(job.target.name)) {
|
|
1969
|
+
client.raw(`PRIVMSG ${job.target.name} :${job.object.content}`);
|
|
1970
|
+
} else {
|
|
1971
|
+
return done("cannot send message to a channel of which you've not first joined.");
|
|
1972
|
+
}
|
|
1973
|
+
this.jobQueue.push(done);
|
|
1974
|
+
client.raw(`PING ${job.actor.name}`);
|
|
1975
|
+
});
|
|
1976
|
+
}
|
|
1977
|
+
update(job, credentials, done) {
|
|
1978
|
+
this.debug(`update() called for ${job.actor.id}`);
|
|
1979
|
+
this.getClient(job.actor.id, false, (err, client) => {
|
|
1980
|
+
if (err) {
|
|
1981
|
+
return done(err);
|
|
1982
|
+
}
|
|
1983
|
+
if (job.object.type === "address") {
|
|
1984
|
+
this.debug(`changing nick from ${job.actor.name} to ${job.target.name}`);
|
|
1985
|
+
this.handledActors.add(job.target.id);
|
|
1986
|
+
this.jobQueue.push(async (err2) => {
|
|
1987
|
+
if (err2) {
|
|
1988
|
+
this.handledActors.delete(job.target.id);
|
|
1989
|
+
return done(err2);
|
|
1990
|
+
}
|
|
1991
|
+
credentials.object.nick = job.target.name;
|
|
1992
|
+
credentials.actor.id = `${job.target.name}@${credentials.object.server}`;
|
|
1993
|
+
credentials.actor.name = job.target.name;
|
|
1994
|
+
await this.updateActor(credentials);
|
|
1995
|
+
done();
|
|
1996
|
+
});
|
|
1997
|
+
client.raw(["NICK", job.target.name]);
|
|
1998
|
+
} else if (job.object.type === "topic") {
|
|
1999
|
+
this.debug(`changing topic in channel ${job.target.name}`);
|
|
2000
|
+
this.jobQueue.push(done);
|
|
2001
|
+
client.raw(["topic", job.target.name, job.object.content]);
|
|
2002
|
+
} else {
|
|
2003
|
+
return done(`unknown update action: ${job.object.type}`);
|
|
2004
|
+
}
|
|
2005
|
+
client.raw(`PING ${job.actor.name}`);
|
|
2006
|
+
});
|
|
2007
|
+
}
|
|
2008
|
+
query(job, done) {
|
|
2009
|
+
this.debug(`query() called for ${job.actor.id}`);
|
|
2010
|
+
this.getClient(job.actor.id, false, (err, client) => {
|
|
2011
|
+
if (err) {
|
|
2012
|
+
return done(err);
|
|
2013
|
+
}
|
|
2014
|
+
if (job.object.type === "attendance") {
|
|
2015
|
+
this.debug(`query() - sending NAMES for ${job.target.name}`);
|
|
2016
|
+
client.raw(["NAMES", job.target.name]);
|
|
2017
|
+
done();
|
|
2018
|
+
} else {
|
|
2019
|
+
done(`unknown 'type' '${job.object.type}'`);
|
|
2020
|
+
}
|
|
2021
|
+
});
|
|
2022
|
+
}
|
|
2023
|
+
disconnect(job, done) {
|
|
2024
|
+
this.debug(`disconnect called for ${job.actor.id}`);
|
|
2025
|
+
this.cleanup(done);
|
|
2026
|
+
}
|
|
2027
|
+
cleanup(done) {
|
|
2028
|
+
this.debug("cleanup() called");
|
|
2029
|
+
this.config.initialized = false;
|
|
2030
|
+
this.forceDisconnect = true;
|
|
2031
|
+
if (typeof this.client === "object") {
|
|
2032
|
+
if (typeof this.client.end === "function") {
|
|
2033
|
+
this.client.end();
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
this.client = undefined;
|
|
2037
|
+
return done();
|
|
2038
|
+
}
|
|
2039
|
+
isJoined(channel) {
|
|
2040
|
+
if (channel.indexOf("#") === 0) {
|
|
2041
|
+
return this.channels.has(channel);
|
|
2042
|
+
}
|
|
2043
|
+
return true;
|
|
2044
|
+
}
|
|
2045
|
+
hasJoined(channel) {
|
|
2046
|
+
this.debug(`joined ${channel}`);
|
|
2047
|
+
if (!this.channels.has(channel)) {
|
|
2048
|
+
this.channels.add(channel);
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
hasLeft(channel) {
|
|
2052
|
+
this.debug(`left ${channel}`);
|
|
2053
|
+
if (this.channels.has(channel)) {
|
|
2054
|
+
this.channels.delete(channel);
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
getClient(key, credentials, cb) {
|
|
2058
|
+
this.debug(`getClient called, connecting: ${this.clientConnecting}`);
|
|
2059
|
+
if (this.client) {
|
|
2060
|
+
this.handledActors.add(key);
|
|
2061
|
+
return cb(null, this.client);
|
|
2062
|
+
}
|
|
2063
|
+
if (this.clientConnecting) {
|
|
2064
|
+
setTimeout(() => {
|
|
2065
|
+
if (this.client) {
|
|
2066
|
+
this.debug(`resolving delayed getClient call for ${key}`);
|
|
2067
|
+
this.handledActors.add(key);
|
|
2068
|
+
return cb(null, this.client);
|
|
2069
|
+
}
|
|
2070
|
+
return cb("failed to get irc client, please try again.");
|
|
2071
|
+
}, this.config.connectTimeoutMs);
|
|
2072
|
+
return;
|
|
2073
|
+
}
|
|
2074
|
+
if (!credentials) {
|
|
2075
|
+
return cb("no client found, and no credentials specified. you must connect first");
|
|
2076
|
+
}
|
|
2077
|
+
this.ircConnect(credentials, (err, client) => {
|
|
2078
|
+
if (err) {
|
|
2079
|
+
this.config.initialized = false;
|
|
2080
|
+
return cb(err);
|
|
2081
|
+
}
|
|
2082
|
+
this.handledActors.add(key);
|
|
2083
|
+
this.client = client;
|
|
2084
|
+
this.registerListeners(credentials.object.server);
|
|
2085
|
+
this.config.initialized = true;
|
|
2086
|
+
return cb(null, client);
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
ircConnect(credentials, cb) {
|
|
2090
|
+
this.clientConnecting = true;
|
|
2091
|
+
const is_secure = typeof credentials.object.secure === "boolean" ? credentials.object.secure : true;
|
|
2092
|
+
const is_sasl = typeof credentials.object.sasl === "boolean" ? credentials.object.sasl : !!credentials.object.password;
|
|
2093
|
+
const module_options = {
|
|
2094
|
+
username: credentials.object.username || credentials.object.nick,
|
|
2095
|
+
nicknames: [credentials.object.nick],
|
|
2096
|
+
server: credentials.object.server || "irc.libera.chat",
|
|
2097
|
+
realname: credentials.actor.name || credentials.object.nick,
|
|
2098
|
+
port: credentials.object.port ? typeof credentials.object.port === "string" ? Number.parseInt(credentials.object.port, 10) : credentials.object.port : is_secure ? 6697 : 6667,
|
|
2099
|
+
debug: console.log
|
|
2100
|
+
};
|
|
2101
|
+
if (is_secure) {
|
|
2102
|
+
module_options.connectOptions = { rejectUnauthorized: false };
|
|
2103
|
+
}
|
|
2104
|
+
if (is_sasl) {
|
|
2105
|
+
module_options.saslPassword = credentials.object.password;
|
|
2106
|
+
module_options.capabilities = { requires: ["sasl"] };
|
|
2107
|
+
}
|
|
2108
|
+
this.debug(`attempting to connect to ${module_options.server}:${module_options.port} transport: ${is_secure ? "secure" : "clear"} sasl: ${is_sasl}`);
|
|
2109
|
+
const client = new import_irc_socket_sasl.default(module_options, is_secure ? tls : net);
|
|
2110
|
+
const forceDisconnect = (err) => {
|
|
2111
|
+
this.forceDisconnect = true;
|
|
2112
|
+
this.clientConnecting = false;
|
|
2113
|
+
if (client && typeof client.end === "function") {
|
|
2114
|
+
client.end();
|
|
2115
|
+
}
|
|
2116
|
+
if (this.client && typeof this.client.end === "function") {
|
|
2117
|
+
this.client.end();
|
|
2118
|
+
}
|
|
2119
|
+
cb(err);
|
|
2120
|
+
};
|
|
2121
|
+
client.once("error", (err) => {
|
|
2122
|
+
this.debug(`irc client 'error' occurred. `, err);
|
|
2123
|
+
forceDisconnect("error connecting to server.");
|
|
2124
|
+
});
|
|
2125
|
+
client.once("close", () => {
|
|
2126
|
+
this.debug(`irc client 'close' event fired.`);
|
|
2127
|
+
forceDisconnect("connection to server closed.");
|
|
2128
|
+
});
|
|
2129
|
+
client.once("timeout", () => {
|
|
2130
|
+
this.debug("timeout occurred, force-disconnect");
|
|
2131
|
+
forceDisconnect("connection timeout to server.");
|
|
2132
|
+
});
|
|
2133
|
+
client.connect().then((res) => {
|
|
2134
|
+
if (res.isFail()) {
|
|
2135
|
+
return cb(`unable to connect to server: ${res.fail()}`);
|
|
2136
|
+
}
|
|
2137
|
+
const capabilities = res.ok();
|
|
2138
|
+
this.clientConnecting = false;
|
|
2139
|
+
if (this.forceDisconnect) {
|
|
2140
|
+
client.end();
|
|
2141
|
+
return cb("force disconnect active, aborting connect.");
|
|
2142
|
+
}
|
|
2143
|
+
this.debug(`connected to ${module_options.server} capabilities: `, capabilities);
|
|
2144
|
+
return cb(null, client);
|
|
2145
|
+
});
|
|
2146
|
+
}
|
|
2147
|
+
completeJob(err) {
|
|
2148
|
+
this.debug(`completing job, queue count: ${this.jobQueue.length}`);
|
|
2149
|
+
const done = this.jobQueue.shift();
|
|
2150
|
+
if (typeof done === "function") {
|
|
2151
|
+
done(err);
|
|
2152
|
+
} else if (this.jobQueue.length === 0) {
|
|
2153
|
+
this.debug("WARNING: job completion event received with an empty job queue.");
|
|
2154
|
+
} else {
|
|
2155
|
+
this.debug(`WARNING: job completion found non-function in queue (${typeof done}), ${this.jobQueue.length} items remain.`);
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
registerListeners(server) {
|
|
2159
|
+
this.irc2as = new IrcToActivityStreams({ server });
|
|
2160
|
+
this.client.on("data", (data) => {
|
|
2161
|
+
this.irc2as.input(data);
|
|
2162
|
+
});
|
|
2163
|
+
this.irc2as.events.on("incoming", (asObject) => {
|
|
2164
|
+
if (typeof asObject.actor === "object" && typeof asObject.actor.name === "string" && this.handledActors.has(asObject.actor.id)) {
|
|
2165
|
+
this.completeJob();
|
|
2166
|
+
} else {
|
|
2167
|
+
this.debug(`calling sendToClient for ${asObject.actor.id}`, [
|
|
2168
|
+
...this.handledActors.keys()
|
|
2169
|
+
]);
|
|
2170
|
+
this.sendToClient(asObject);
|
|
2171
|
+
}
|
|
2172
|
+
});
|
|
2173
|
+
this.irc2as.events.on("unprocessed", (s) => {
|
|
2174
|
+
this.debug(`unprocessed irc message:> ${s}`);
|
|
2175
|
+
});
|
|
2176
|
+
this.irc2as.events.on("error", (asObject) => {
|
|
2177
|
+
this.debug(`message error response ${asObject.object.content}`);
|
|
2178
|
+
this.completeJob(asObject.object.content);
|
|
2179
|
+
});
|
|
2180
|
+
this.irc2as.events.on("pong", (timestamp) => {
|
|
2181
|
+
this.debug(`received PONG at ${timestamp}`);
|
|
2182
|
+
this.completeJob();
|
|
2183
|
+
});
|
|
2184
|
+
this.irc2as.events.on("ping", (timestamp) => {
|
|
2185
|
+
this.debug(`received PING at ${timestamp}`);
|
|
2186
|
+
this.client.raw("PONG");
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
export {
|
|
2191
|
+
IRC as default
|
|
2192
|
+
};
|
|
2193
|
+
|
|
2194
|
+
//# debugId=A97EC20DD7F97FB264756E2164756E21
|