smule.js 1.3.1 → 1.4.0

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 CHANGED
@@ -1,3 +1,654 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
+ }) : x)(function(x) {
10
+ if (typeof require !== "undefined") return require.apply(this, arguments);
11
+ throw Error('Dynamic require of "' + x + '" is not supported');
12
+ });
13
+ var __commonJS = (cb, mod) => function __require2() {
14
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
+ // If the importer is in node compatibility mode or this is not an ESM
26
+ // file that has been converted to a CommonJS file using a Babel-
27
+ // compatible transform (i.e. "__esModule" has not been set), then set
28
+ // "default" to the CommonJS "module.exports" for node compatibility.
29
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
+ mod
31
+ ));
32
+
33
+ // node_modules/ltx/lib/escape.js
34
+ var require_escape = __commonJS({
35
+ "node_modules/ltx/lib/escape.js"(exports) {
36
+ "use strict";
37
+ var escapeXMLTable = {
38
+ "&": "&",
39
+ "<": "&lt;",
40
+ ">": "&gt;",
41
+ '"': "&quot;",
42
+ "'": "&apos;"
43
+ };
44
+ function escapeXMLReplace(match) {
45
+ return escapeXMLTable[match];
46
+ }
47
+ var unescapeXMLTable = {
48
+ "&amp;": "&",
49
+ "&lt;": "<",
50
+ "&gt;": ">",
51
+ "&quot;": '"',
52
+ "&apos;": "'"
53
+ };
54
+ function unescapeXMLReplace(match) {
55
+ if (match[1] === "#") {
56
+ const num = match[2] === "x" ? parseInt(match.slice(3), 16) : parseInt(match.slice(2), 10);
57
+ if (num === 9 || num === 10 || num === 13 || num >= 32 && num <= 55295 || num >= 57344 && num <= 65533 || num >= 65536 && num <= 1114111) {
58
+ return String.fromCodePoint(num);
59
+ }
60
+ throw new Error("Illegal XML character 0x" + num.toString(16));
61
+ }
62
+ if (unescapeXMLTable[match]) {
63
+ return unescapeXMLTable[match] || match;
64
+ }
65
+ throw new Error("Illegal XML entity " + match);
66
+ }
67
+ function escapeXML2(s) {
68
+ return s.replace(/["&'<>]/g, escapeXMLReplace);
69
+ }
70
+ function unescapeXML2(s) {
71
+ let result = "";
72
+ let start = -1;
73
+ let end = -1;
74
+ let previous = 0;
75
+ while ((start = s.indexOf("&", previous)) !== -1 && (end = s.indexOf(";", start + 1)) !== -1) {
76
+ result = result + s.slice(previous, start) + unescapeXMLReplace(s.slice(start, end + 1));
77
+ previous = end + 1;
78
+ }
79
+ if (previous === 0) return s;
80
+ result = result + s.substring(previous);
81
+ return result;
82
+ }
83
+ function escapeXMLText2(s) {
84
+ return s.replace(/[&<>]/g, escapeXMLReplace);
85
+ }
86
+ function unescapeXMLText2(s) {
87
+ return s.replace(/&(amp|#38|lt|#60|gt|#62);/g, unescapeXMLReplace);
88
+ }
89
+ exports.escapeXML = escapeXML2;
90
+ exports.escapeXMLText = escapeXMLText2;
91
+ exports.unescapeXML = unescapeXML2;
92
+ exports.unescapeXMLText = unescapeXMLText2;
93
+ }
94
+ });
95
+
96
+ // node_modules/ltx/lib/Element.js
97
+ var require_Element = __commonJS({
98
+ "node_modules/ltx/lib/Element.js"(exports, module) {
99
+ "use strict";
100
+ var escape = require_escape();
101
+ var Element5 = class _Element {
102
+ constructor(name, attrs) {
103
+ this.name = name;
104
+ this.parent = null;
105
+ this.children = [];
106
+ this.attrs = {};
107
+ this.setAttrs(attrs);
108
+ }
109
+ /* Accessors */
110
+ /**
111
+ * if (element.is('message', 'jabber:client')) ...
112
+ **/
113
+ is(name, xmlns) {
114
+ return this.getName() === name && (!xmlns || this.getNS() === xmlns);
115
+ }
116
+ /* without prefix */
117
+ getName() {
118
+ const idx = this.name.indexOf(":");
119
+ return idx >= 0 ? this.name.slice(idx + 1) : this.name;
120
+ }
121
+ /**
122
+ * retrieves the namespace of the current element, upwards recursively
123
+ **/
124
+ getNS() {
125
+ const idx = this.name.indexOf(":");
126
+ if (idx >= 0) {
127
+ const prefix = this.name.slice(0, idx);
128
+ return this.findNS(prefix);
129
+ }
130
+ return this.findNS();
131
+ }
132
+ /**
133
+ * find the namespace to the given prefix, upwards recursively
134
+ **/
135
+ findNS(prefix) {
136
+ if (!prefix) {
137
+ if (this.attrs.xmlns) {
138
+ return this.attrs.xmlns;
139
+ } else if (this.parent) {
140
+ return this.parent.findNS();
141
+ }
142
+ } else {
143
+ const attr = "xmlns:" + prefix;
144
+ if (this.attrs[attr]) {
145
+ return this.attrs[attr];
146
+ } else if (this.parent) {
147
+ return this.parent.findNS(prefix);
148
+ }
149
+ }
150
+ }
151
+ /**
152
+ * Recursiverly gets all xmlns defined, in the form of {url:prefix}
153
+ **/
154
+ getXmlns() {
155
+ let namespaces = {};
156
+ if (this.parent) {
157
+ namespaces = this.parent.getXmlns();
158
+ }
159
+ for (const attr in this.attrs) {
160
+ const m = attr.match("xmlns:?(.*)");
161
+ if (this.attrs.hasOwnProperty(attr) && m) {
162
+ namespaces[this.attrs[attr]] = m[1];
163
+ }
164
+ }
165
+ return namespaces;
166
+ }
167
+ setAttrs(attrs) {
168
+ if (typeof attrs === "string") {
169
+ this.attrs.xmlns = attrs;
170
+ } else if (attrs) {
171
+ Object.assign(this.attrs, attrs);
172
+ }
173
+ }
174
+ /**
175
+ * xmlns can be null, returns the matching attribute.
176
+ **/
177
+ getAttr(name, xmlns) {
178
+ if (!xmlns) {
179
+ return this.attrs[name];
180
+ }
181
+ const namespaces = this.getXmlns();
182
+ if (!namespaces[xmlns]) {
183
+ return null;
184
+ }
185
+ return this.attrs[[namespaces[xmlns], name].join(":")];
186
+ }
187
+ /**
188
+ * xmlns can be null
189
+ **/
190
+ getChild(name, xmlns) {
191
+ return this.getChildren(name, xmlns)[0];
192
+ }
193
+ /**
194
+ * xmlns can be null
195
+ **/
196
+ getChildren(name, xmlns) {
197
+ const result = [];
198
+ for (const child of this.children) {
199
+ if (child.getName && child.getName() === name && (!xmlns || child.getNS() === xmlns)) {
200
+ result.push(child);
201
+ }
202
+ }
203
+ return result;
204
+ }
205
+ /**
206
+ * xmlns and recursive can be null
207
+ **/
208
+ getChildByAttr(attr, val, xmlns, recursive) {
209
+ return this.getChildrenByAttr(attr, val, xmlns, recursive)[0];
210
+ }
211
+ /**
212
+ * xmlns and recursive can be null
213
+ **/
214
+ getChildrenByAttr(attr, val, xmlns, recursive) {
215
+ let result = [];
216
+ for (const child of this.children) {
217
+ if (child.attrs && child.attrs[attr] === val && (!xmlns || child.getNS() === xmlns)) {
218
+ result.push(child);
219
+ }
220
+ if (recursive && child.getChildrenByAttr) {
221
+ result.push(child.getChildrenByAttr(attr, val, xmlns, true));
222
+ }
223
+ }
224
+ if (recursive) {
225
+ result = result.flat();
226
+ }
227
+ return result;
228
+ }
229
+ getChildrenByFilter(filter, recursive) {
230
+ let result = [];
231
+ for (const child of this.children) {
232
+ if (filter(child)) {
233
+ result.push(child);
234
+ }
235
+ if (recursive && child.getChildrenByFilter) {
236
+ result.push(child.getChildrenByFilter(filter, true));
237
+ }
238
+ }
239
+ if (recursive) {
240
+ result = result.flat();
241
+ }
242
+ return result;
243
+ }
244
+ getText() {
245
+ let text = "";
246
+ for (const child of this.children) {
247
+ if (typeof child === "string" || typeof child === "number") {
248
+ text += child;
249
+ }
250
+ }
251
+ return text;
252
+ }
253
+ getChildText(name, xmlns) {
254
+ const child = this.getChild(name, xmlns);
255
+ return child ? child.getText() : null;
256
+ }
257
+ /**
258
+ * Return all direct descendents that are Elements.
259
+ * This differs from `getChildren` in that it will exclude text nodes,
260
+ * processing instructions, etc.
261
+ */
262
+ getChildElements() {
263
+ return this.getChildrenByFilter((child) => {
264
+ return child instanceof _Element;
265
+ });
266
+ }
267
+ /* Builder */
268
+ /** returns uppermost parent */
269
+ root() {
270
+ if (this.parent) {
271
+ return this.parent.root();
272
+ }
273
+ return this;
274
+ }
275
+ /** just parent or itself */
276
+ up() {
277
+ if (this.parent) {
278
+ return this.parent;
279
+ }
280
+ return this;
281
+ }
282
+ /** create child node and return it */
283
+ c(name, attrs) {
284
+ return this.cnode(new _Element(name, attrs));
285
+ }
286
+ cnode(child) {
287
+ this.children.push(child);
288
+ if (typeof child === "object") {
289
+ child.parent = this;
290
+ }
291
+ return child;
292
+ }
293
+ append(...nodes) {
294
+ for (const node of nodes) {
295
+ this.children.push(node);
296
+ if (typeof node === "object") {
297
+ node.parent = this;
298
+ }
299
+ }
300
+ }
301
+ prepend(...nodes) {
302
+ for (const node of nodes) {
303
+ this.children.unshift(node);
304
+ if (typeof node === "object") {
305
+ node.parent = this;
306
+ }
307
+ }
308
+ }
309
+ /** add text node and return element */
310
+ t(text) {
311
+ this.children.push(text);
312
+ return this;
313
+ }
314
+ /* Manipulation */
315
+ /**
316
+ * Either:
317
+ * el.remove(childEl)
318
+ * el.remove('author', 'urn:...')
319
+ */
320
+ remove(el, xmlns) {
321
+ const filter = typeof el === "string" ? (child) => {
322
+ return !(child.is && child.is(el, xmlns));
323
+ } : (child) => {
324
+ return child !== el;
325
+ };
326
+ this.children = this.children.filter(filter);
327
+ return this;
328
+ }
329
+ text(val) {
330
+ if (val && this.children.length === 1) {
331
+ this.children[0] = val;
332
+ return this;
333
+ }
334
+ return this.getText();
335
+ }
336
+ attr(attr, val) {
337
+ if (typeof val !== "undefined" || val === null) {
338
+ if (!this.attrs) {
339
+ this.attrs = {};
340
+ }
341
+ this.attrs[attr] = val;
342
+ return this;
343
+ }
344
+ return this.attrs[attr];
345
+ }
346
+ /* Serialization */
347
+ toString() {
348
+ let s = "";
349
+ this.write((c) => {
350
+ s += c;
351
+ });
352
+ return s;
353
+ }
354
+ _addChildren(writer) {
355
+ writer(">");
356
+ for (const child of this.children) {
357
+ if (child != null) {
358
+ if (child.write) {
359
+ child.write(writer);
360
+ } else if (typeof child === "string") {
361
+ writer(escape.escapeXMLText(child));
362
+ } else if (child.toString) {
363
+ writer(escape.escapeXMLText(child.toString(10)));
364
+ }
365
+ }
366
+ }
367
+ writer("</");
368
+ writer(this.name);
369
+ writer(">");
370
+ }
371
+ write(writer) {
372
+ writer("<");
373
+ writer(this.name);
374
+ for (const k in this.attrs) {
375
+ const v = this.attrs[k];
376
+ if (v != null) {
377
+ writer(" ");
378
+ writer(k);
379
+ writer('="');
380
+ writer(escape.escapeXML(typeof v === "string" ? v : v.toString(10)));
381
+ writer('"');
382
+ }
383
+ }
384
+ if (this.children.length === 0) {
385
+ writer("/>");
386
+ } else {
387
+ this._addChildren(writer);
388
+ }
389
+ }
390
+ };
391
+ Element5.prototype.tree = Element5.prototype.root;
392
+ module.exports = Element5;
393
+ }
394
+ });
395
+
396
+ // node_modules/ltx/lib/createElement.js
397
+ var require_createElement = __commonJS({
398
+ "node_modules/ltx/lib/createElement.js"(exports, module) {
399
+ "use strict";
400
+ var Element5 = require_Element();
401
+ function append(el, child) {
402
+ if (Array.isArray(child)) {
403
+ for (const c of child) append(el, c);
404
+ return;
405
+ }
406
+ if (child === "" || child == null || child === true || child === false) {
407
+ return;
408
+ }
409
+ el.cnode(child);
410
+ }
411
+ function createElement2(name, attrs, ...children) {
412
+ if (typeof attrs === "object" && attrs !== null) {
413
+ delete attrs.__source;
414
+ delete attrs.__self;
415
+ for (const [key, value] of Object.entries(attrs)) {
416
+ if (value == null) delete attrs[key];
417
+ else attrs[key] = value.toString(10);
418
+ }
419
+ }
420
+ const el = new Element5(name, attrs);
421
+ for (const child of children) {
422
+ append(el, child);
423
+ }
424
+ return el;
425
+ }
426
+ module.exports = createElement2;
427
+ }
428
+ });
429
+
430
+ // node_modules/ltx/lib/parsers/ltx.js
431
+ var require_ltx = __commonJS({
432
+ "node_modules/ltx/lib/parsers/ltx.js"(exports, module) {
433
+ "use strict";
434
+ var events = __require("events");
435
+ var escape = require_escape();
436
+ var STATE_TEXT = 0;
437
+ var STATE_IGNORE_COMMENT = 1;
438
+ var STATE_IGNORE_INSTRUCTION = 2;
439
+ var STATE_TAG_NAME = 3;
440
+ var STATE_TAG = 4;
441
+ var STATE_ATTR_NAME = 5;
442
+ var STATE_ATTR_EQ = 6;
443
+ var STATE_ATTR_QUOT = 7;
444
+ var STATE_ATTR_VALUE = 8;
445
+ var STATE_CDATA = 9;
446
+ var STATE_IGNORE_CDATA = 10;
447
+ var SaxLtx = class extends events.EventEmitter {
448
+ constructor() {
449
+ super();
450
+ let state = STATE_TEXT;
451
+ let remainder;
452
+ let parseRemainder;
453
+ let tagName;
454
+ let attrs;
455
+ let endTag;
456
+ let selfClosing;
457
+ let attrQuote;
458
+ let attrQuoteChar;
459
+ let recordStart = 0;
460
+ let attrName;
461
+ this._handleTagOpening = function _handleTagOpening(endTag2, tagName2, attrs2) {
462
+ if (!endTag2) {
463
+ this.emit("startElement", tagName2, attrs2);
464
+ if (selfClosing) {
465
+ this.emit("endElement", tagName2, true);
466
+ }
467
+ } else {
468
+ this.emit("endElement", tagName2, false);
469
+ }
470
+ };
471
+ this.write = function write(data) {
472
+ if (typeof data !== "string") {
473
+ data = data.toString();
474
+ }
475
+ let pos = 0;
476
+ if (remainder) {
477
+ data = remainder + data;
478
+ pos += !parseRemainder ? remainder.length : 0;
479
+ parseRemainder = false;
480
+ remainder = null;
481
+ }
482
+ function endRecording() {
483
+ if (typeof recordStart === "number") {
484
+ const recorded = data.slice(recordStart, pos);
485
+ recordStart = void 0;
486
+ return recorded;
487
+ }
488
+ }
489
+ for (; pos < data.length; pos++) {
490
+ switch (state) {
491
+ case STATE_TEXT: {
492
+ const lt = data.indexOf("<", pos);
493
+ if (lt !== -1 && pos !== lt) {
494
+ pos = lt;
495
+ }
496
+ break;
497
+ }
498
+ case STATE_ATTR_VALUE: {
499
+ const quot = data.indexOf(attrQuoteChar, pos);
500
+ if (quot !== -1) {
501
+ pos = quot;
502
+ }
503
+ break;
504
+ }
505
+ case STATE_IGNORE_COMMENT: {
506
+ const endcomment = data.indexOf("-->", pos);
507
+ if (endcomment !== -1) {
508
+ pos = endcomment + 2;
509
+ }
510
+ break;
511
+ }
512
+ case STATE_IGNORE_CDATA: {
513
+ const endCDATA = data.indexOf("]]>", pos);
514
+ if (endCDATA !== -1) {
515
+ pos = endCDATA + 2;
516
+ }
517
+ break;
518
+ }
519
+ }
520
+ const c = data.charCodeAt(pos);
521
+ switch (state) {
522
+ case STATE_TEXT:
523
+ if (c === 60) {
524
+ const text = endRecording();
525
+ if (text) {
526
+ this.emit("text", escape.unescapeXML(text));
527
+ }
528
+ state = STATE_TAG_NAME;
529
+ recordStart = pos + 1;
530
+ attrs = {};
531
+ }
532
+ break;
533
+ case STATE_CDATA:
534
+ if (c === 93) {
535
+ if (data.substr(pos + 1, 2) === "]>") {
536
+ const cData = endRecording();
537
+ if (cData) {
538
+ this.emit("text", cData);
539
+ }
540
+ state = STATE_TEXT;
541
+ } else if (data.length < pos + 2) {
542
+ parseRemainder = true;
543
+ pos = data.length;
544
+ }
545
+ }
546
+ break;
547
+ case STATE_TAG_NAME:
548
+ if (c === 47 && recordStart === pos) {
549
+ recordStart = pos + 1;
550
+ endTag = true;
551
+ } else if (c === 33) {
552
+ if (data.substr(pos + 1, 7) === "[CDATA[") {
553
+ recordStart = pos + 8;
554
+ state = STATE_CDATA;
555
+ } else if (data.length < pos + 8 && "[CDATA[".startsWith(data.slice(pos + 1))) {
556
+ parseRemainder = true;
557
+ pos = data.length;
558
+ } else {
559
+ recordStart = void 0;
560
+ state = STATE_IGNORE_COMMENT;
561
+ }
562
+ } else if (c === 63) {
563
+ recordStart = void 0;
564
+ state = STATE_IGNORE_INSTRUCTION;
565
+ } else if (c <= 32 || c === 47 || c === 62) {
566
+ tagName = endRecording();
567
+ pos--;
568
+ state = STATE_TAG;
569
+ }
570
+ break;
571
+ case STATE_IGNORE_COMMENT:
572
+ if (c === 62) {
573
+ const prevFirst = data.charCodeAt(pos - 1);
574
+ const prevSecond = data.charCodeAt(pos - 2);
575
+ if (prevFirst === 45 && prevSecond === 45 || prevFirst === 93 && prevSecond === 93) {
576
+ state = STATE_TEXT;
577
+ }
578
+ }
579
+ break;
580
+ case STATE_IGNORE_INSTRUCTION:
581
+ if (c === 62) {
582
+ const prev = data.charCodeAt(pos - 1);
583
+ if (prev === 63) {
584
+ state = STATE_TEXT;
585
+ }
586
+ }
587
+ break;
588
+ case STATE_TAG:
589
+ if (c === 62) {
590
+ this._handleTagOpening(endTag, tagName, attrs);
591
+ tagName = void 0;
592
+ attrs = void 0;
593
+ endTag = void 0;
594
+ selfClosing = void 0;
595
+ state = STATE_TEXT;
596
+ recordStart = pos + 1;
597
+ } else if (c === 47) {
598
+ selfClosing = true;
599
+ } else if (c > 32) {
600
+ recordStart = pos;
601
+ state = STATE_ATTR_NAME;
602
+ }
603
+ break;
604
+ case STATE_ATTR_NAME:
605
+ if (c <= 32 || c === 61) {
606
+ attrName = endRecording();
607
+ pos--;
608
+ state = STATE_ATTR_EQ;
609
+ }
610
+ break;
611
+ case STATE_ATTR_EQ:
612
+ if (c === 61) {
613
+ state = STATE_ATTR_QUOT;
614
+ }
615
+ break;
616
+ case STATE_ATTR_QUOT:
617
+ if (c === 34 || c === 39) {
618
+ attrQuote = c;
619
+ attrQuoteChar = c === 34 ? '"' : "'";
620
+ state = STATE_ATTR_VALUE;
621
+ recordStart = pos + 1;
622
+ }
623
+ break;
624
+ case STATE_ATTR_VALUE:
625
+ if (c === attrQuote) {
626
+ const value = escape.unescapeXML(endRecording());
627
+ attrs[attrName] = value;
628
+ attrName = void 0;
629
+ state = STATE_TAG;
630
+ }
631
+ break;
632
+ }
633
+ }
634
+ if (typeof recordStart === "number" && recordStart <= data.length) {
635
+ remainder = data.slice(recordStart);
636
+ recordStart = 0;
637
+ }
638
+ };
639
+ }
640
+ end(data) {
641
+ if (data) {
642
+ this.write(data);
643
+ }
644
+ this.write = function write() {
645
+ };
646
+ }
647
+ };
648
+ module.exports = SaxLtx;
649
+ }
650
+ });
651
+
1
652
  // src/types/smule-requests.ts
2
653
  import { randomUUID } from "crypto";
3
654
  var Device = class {
@@ -664,7 +1315,7 @@ var SmuleUtil;
664
1315
  import axios from "axios";
665
1316
 
666
1317
  // src/smule-live-chat.ts
667
- import { client, xml } from "@xmpp/client";
1318
+ import { client, xml as xml2 } from "@xmpp/client";
668
1319
 
669
1320
  // src/smule-urls.ts
670
1321
  var SmuleUrls;
@@ -1297,22 +1948,117 @@ var SmuleUrls;
1297
1948
  ]);
1298
1949
  })(SmuleUrls || (SmuleUrls = {}));
1299
1950
 
1951
+ // node_modules/@xmpp/xml/index.js
1952
+ var import_Element2 = __toESM(require_Element(), 1);
1953
+ var import_createElement = __toESM(require_createElement(), 1);
1954
+ var import_escape = __toESM(require_escape(), 1);
1955
+
1956
+ // node_modules/@xmpp/xml/lib/Parser.js
1957
+ var import_ltx = __toESM(require_ltx(), 1);
1958
+ var import_Element = __toESM(require_Element(), 1);
1959
+
1960
+ // node_modules/@xmpp/events/index.js
1961
+ import { EventEmitter } from "events";
1962
+
1963
+ // node_modules/@xmpp/xml/lib/XMLError.js
1964
+ var XMLError = class extends Error {
1965
+ constructor(...args) {
1966
+ super(...args);
1967
+ this.name = "XMLError";
1968
+ }
1969
+ };
1970
+
1971
+ // node_modules/@xmpp/xml/lib/Parser.js
1972
+ var Parser = class extends EventEmitter {
1973
+ constructor() {
1974
+ super();
1975
+ const parser = new import_ltx.default();
1976
+ this.root = null;
1977
+ this.cursor = null;
1978
+ parser.on("startElement", this.onStartElement.bind(this));
1979
+ parser.on("endElement", this.onEndElement.bind(this));
1980
+ parser.on("text", this.onText.bind(this));
1981
+ this.parser = parser;
1982
+ }
1983
+ onStartElement(name, attrs) {
1984
+ const element = new import_Element.default(name, attrs);
1985
+ const { root, cursor } = this;
1986
+ if (!root) {
1987
+ this.root = element;
1988
+ this.emit("start", element);
1989
+ } else if (cursor !== root) {
1990
+ cursor.append(element);
1991
+ }
1992
+ this.cursor = element;
1993
+ }
1994
+ onEndElement(name) {
1995
+ const { root, cursor } = this;
1996
+ if (name !== cursor.name) {
1997
+ this.emit("error", new XMLError(`${cursor.name} must be closed.`));
1998
+ return;
1999
+ }
2000
+ if (cursor === root) {
2001
+ this.emit("end", root);
2002
+ return;
2003
+ }
2004
+ if (!cursor.parent) {
2005
+ cursor.parent = root;
2006
+ this.emit("element", cursor);
2007
+ this.cursor = root;
2008
+ return;
2009
+ }
2010
+ this.cursor = cursor.parent;
2011
+ }
2012
+ onText(str) {
2013
+ const { cursor } = this;
2014
+ if (!cursor) {
2015
+ this.emit("error", new XMLError(`${str} must be a child.`));
2016
+ return;
2017
+ }
2018
+ cursor.t(str);
2019
+ }
2020
+ write(data) {
2021
+ this.parser.write(data);
2022
+ }
2023
+ end(data) {
2024
+ if (data) {
2025
+ this.parser.write(data);
2026
+ }
2027
+ }
2028
+ };
2029
+ Parser.XMLError = XMLError;
2030
+ var Parser_default = Parser;
2031
+
2032
+ // node_modules/@xmpp/xml/index.js
2033
+ function xml(...args) {
2034
+ return (0, import_createElement.default)(...args);
2035
+ }
2036
+ Object.assign(xml, {
2037
+ Element: import_Element2.default,
2038
+ createElement: import_createElement.default,
2039
+ Parser: Parser_default,
2040
+ escapeXML: import_escape.escapeXML,
2041
+ unescapeXML: import_escape.unescapeXML,
2042
+ escapeXMLText: import_escape.escapeXMLText,
2043
+ unescapeXMLText: import_escape.unescapeXMLText,
2044
+ XMLError,
2045
+ xml
2046
+ });
2047
+
1300
2048
  // src/smule-live-chat.ts
1301
- import "@xmpp/xml";
1302
- import EventEmitter from "events";
2049
+ import EventEmitter2 from "events";
1303
2050
  import "@xmpp/jid";
2051
+ import { randomUUID as randomUUID2 } from "crypto";
1304
2052
  var SmuleLiveChat = class {
1305
- events = new EventEmitter();
2053
+ events = new EventEmitter2();
1306
2054
  state = "closed";
1307
2055
  client;
1308
2056
  jid;
1309
- ongoingIq = false;
1310
- iqHasMore = false;
1311
- lastIqId = "0";
2057
+ iqs = {};
1312
2058
  roomJID = null;
1313
2059
  roomUsers = [];
1314
2060
  chat = { messages: [] };
1315
- constructor(userId, session, host = SmuleUrls.userChat, roomJID) {
2061
+ constructor(userId, session, host = SmuleUrls.cfireChat, roomJID) {
1316
2062
  this.client = client({
1317
2063
  service: "xmpp://" + host,
1318
2064
  domain: host,
@@ -1344,22 +2090,25 @@ var SmuleLiveChat = class {
1344
2090
  this.jid = await this.client.start();
1345
2091
  this._log("Connected as:", this.jid.getLocal() + "@" + this.jid.getDomain());
1346
2092
  this.client.send(
1347
- xml(
2093
+ xml2(
1348
2094
  "presence",
1349
2095
  { to: this.roomJID + "/" + this.jid.getLocal() },
1350
- xml(
2096
+ xml2(
1351
2097
  "x",
1352
2098
  { xmlns: "http://jabber.org/protocol/muc" },
1353
- xml(
2099
+ xml2(
1354
2100
  "password"
1355
2101
  ),
1356
- xml(
2102
+ xml2(
1357
2103
  "history",
1358
2104
  { maxstanzas: "1" }
1359
2105
  )
1360
2106
  )
1361
2107
  )
1362
2108
  );
2109
+ this.sendIqQuery("http://jabber.org/protocol/disco#info", (el) => {
2110
+ console.log("reply from disco", el);
2111
+ });
1363
2112
  }
1364
2113
  /**
1365
2114
  * Disconnects the client from the XMPP server.
@@ -1371,83 +2120,41 @@ var SmuleLiveChat = class {
1371
2120
  */
1372
2121
  async disconnect() {
1373
2122
  try {
2123
+ await this.client.send(xml2("presence", { type: "unavailable" }));
1374
2124
  await this.client.stop();
1375
2125
  } catch {
1376
2126
  }
1377
2127
  }
1378
- /**
1379
- * Send a chat state to the server. This is used to
1380
- * signal whether you are currently active or not.
1381
- *
1382
- * active -> You're active
1383
- *
1384
- * composing -> Typing
1385
- *
1386
- * paused -> Just stopped typing
1387
- *
1388
- * inactive -> You're inactive
1389
- *
1390
- * gone -> You're hidden / disconnected / You've left the chat
1391
- *
1392
- * @param state One of `active`, `composing`, `paused`, `inactive`, or `gone`.
1393
- * Default is `active`
1394
- */
1395
- async sendChatState(to, state = "active") {
1396
- if (typeof to != "string" && "accountId" in to) to = this.getJIDFromUserId(to.accountId);
1397
- await this.client.send(
1398
- xml(
1399
- "message",
1400
- { to: to.toString(), type: "chat" },
1401
- xml(
1402
- "chatstate",
1403
- { xmlns: "http://jabber.org/protocol/chatstates" },
1404
- state
1405
- )
2128
+ sendIq(data, callback, iqType = "get") {
2129
+ const id = randomUUID2();
2130
+ this.iqs[id] = callback;
2131
+ this.client.send(
2132
+ xml2(
2133
+ "iq",
2134
+ { from: this.jid.toString(), to: this.roomJID, type: iqType, id },
2135
+ data
1406
2136
  )
1407
2137
  );
1408
2138
  }
1409
- /**
1410
- * Loads the entire message history
1411
- * @param limit The maximum number of messages to fetch. Default is 50.
1412
- * @remarks This currently recurses until it loads ALL archived messages.
1413
- * This means that it will take a long time to load all messages.
1414
- * @remarks Filtering by a specific JID may not work yet
1415
- */
1416
- async loadMessageHistory(limit = 50, before = null, after = null, jid) {
1417
- this._log("Loading live chat history...");
1418
- this.ongoingIq = true;
1419
- await this.client.send(
1420
- xml(
1421
- "iq",
1422
- { from: this.jid.toString(), to: this.roomJID, type: "get", id: "meow" },
1423
- xml(
1424
- "query",
1425
- { xmlns: "http://jabber.org/protocol/muc#history" }
1426
- )
1427
- )
2139
+ sendIqQuery(xmlns, callback, iqType = "get") {
2140
+ this.sendIq(
2141
+ xml2("query", { xmlns }),
2142
+ callback,
2143
+ iqType
1428
2144
  );
1429
- while (this.ongoingIq) await new Promise((resolve) => setTimeout(resolve, 100));
1430
2145
  }
1431
2146
  /**
1432
- * Send a text message
1433
- * @param jid The JID to send the message to
2147
+ * Send a text message to the livestream
1434
2148
  * @param message The message body
1435
2149
  */
1436
- async sendTextMessage(jid, message) {
1437
- if (typeof jid != "string" && "accountId" in jid) jid = this.getJIDFromUserId(jid.accountId);
2150
+ async sendTextMessage(message) {
1438
2151
  await this.client.send(
1439
- xml(
2152
+ xml2(
1440
2153
  "message",
1441
- { to: jid.toString(), type: "groupchat" },
1442
- xml("body", {}, message)
2154
+ { to: this.roomJID, type: "groupchat" },
2155
+ xml2("body", {}, message)
1443
2156
  )
1444
2157
  );
1445
- const data = {
1446
- sender: parseInt(this.jid.getLocal()),
1447
- content: message
1448
- };
1449
- this.chat[this.getUserIdFromJID(jid.toString())].messages.push(data);
1450
- this.events.emit("message", data);
1451
2158
  }
1452
2159
  /**
1453
2160
  * Read-only jid to prevent any bugs
@@ -1560,6 +2267,23 @@ var SmuleLiveChat = class {
1560
2267
  this._log("Got host left!", data2);
1561
2268
  this.events.emit("host-left", data2);
1562
2269
  }
2270
+ child = el.getChild("song-listen");
2271
+ if (child) {
2272
+ const data2 = {
2273
+ arrKey: child.getChild("arrangement-key").getText(),
2274
+ hostSessionId: child.getChild("host-session-id").getText()
2275
+ };
2276
+ this._log("Got song listen!", data2);
2277
+ this.events.emit("song-listen", data2);
2278
+ }
2279
+ child = el.getChild("campfire-ended");
2280
+ if (child) {
2281
+ const data2 = {
2282
+ reason: child.getChild("reason").getText()
2283
+ };
2284
+ this._log("Got stop livestream!", data2);
2285
+ this.events.emit("stop-livestream", data2);
2286
+ }
1563
2287
  child = el.getChild("result");
1564
2288
  if (!child) return;
1565
2289
  child = child.getChild("forwarded");
@@ -1583,15 +2307,17 @@ var SmuleLiveChat = class {
1583
2307
  if (child) {
1584
2308
  child = child.getChild("item");
1585
2309
  if (child) {
1586
- if (!el.getAttr("jid")) return;
1587
- const data = {
1588
- user: this.getUserIdFromJID(el.getAttr("jid")),
1589
- role: child.getAttr("role"),
1590
- affiliation: child.getAttr("affiliation")
1591
- };
1592
- this._log("Got presence!", data);
1593
- this.roomUsers.push(data);
1594
- this.events.emit("presence", data);
2310
+ if (!el.getAttr("jid")) {
2311
+ } else {
2312
+ const data = {
2313
+ user: this.getUserIdFromJID(el.getAttr("jid")),
2314
+ role: child.getAttr("role"),
2315
+ affiliation: child.getAttr("affiliation")
2316
+ };
2317
+ this._log("Got presence!", data);
2318
+ this.roomUsers.push(data);
2319
+ this.events.emit("presence", data);
2320
+ }
1595
2321
  }
1596
2322
  }
1597
2323
  }
@@ -1688,22 +2414,11 @@ var SmuleLiveChat = class {
1688
2414
  this.parsePresence(el);
1689
2415
  } else {
1690
2416
  if (el.is("iq")) {
1691
- let child = el.getChild("fin");
1692
- if (child) {
1693
- if (child.getAttr("complete") == "false") {
1694
- this.iqHasMore = true;
1695
- child = child.getChild("set");
1696
- if (child) {
1697
- child = child.getChild("last");
1698
- if (child) {
1699
- this.lastIqId = child.getText();
1700
- }
1701
- }
1702
- } else {
1703
- this.iqHasMore = false;
1704
- }
2417
+ const id = el.getAttr("id");
2418
+ if (id) {
2419
+ this.iqs[id](el);
2420
+ delete this.iqs[id];
1705
2421
  }
1706
- this.ongoingIq = false;
1707
2422
  }
1708
2423
  this._log("Stanza!", el.toString());
1709
2424
  }
@@ -2136,21 +2851,17 @@ var SmuleMIDI;
2136
2851
  })(SmuleMIDI || (SmuleMIDI = {}));
2137
2852
 
2138
2853
  // src/smule-chat.ts
2139
- import { client as client2, xml as xml2 } from "@xmpp/client";
2140
- import "@xmpp/xml";
2141
- import EventEmitter2 from "events";
2854
+ import { client as client2, xml as xml3 } from "@xmpp/client";
2855
+ import EventEmitter3 from "events";
2142
2856
  import "@xmpp/jid";
2857
+ import { randomUUID as randomUUID3 } from "crypto";
2143
2858
  var SmuleChat = class {
2144
- events = new EventEmitter2();
2859
+ events = new EventEmitter3();
2145
2860
  state = "closed";
2146
2861
  client;
2147
2862
  jid;
2148
- ongoingIq = false;
2149
- iqHasMore = false;
2150
- lastIqId = "0";
2151
- isLive = false;
2863
+ iqs = {};
2152
2864
  roomJID = null;
2153
- roomUsers = [];
2154
2865
  chats = {};
2155
2866
  constructor(userId, session, host = SmuleUrls.userChat, roomJID) {
2156
2867
  this.client = client2({
@@ -2161,7 +2872,6 @@ var SmuleChat = class {
2161
2872
  username: userId + "",
2162
2873
  password: session
2163
2874
  });
2164
- this.isLive = host != SmuleUrls.userChat || !!roomJID;
2165
2875
  this.roomJID = roomJID;
2166
2876
  this.client.on("close", (el) => this.onClose(el));
2167
2877
  this.client.on("closing", () => this.onClosing());
@@ -2184,27 +2894,7 @@ var SmuleChat = class {
2184
2894
  async connect() {
2185
2895
  this.jid = await this.client.start();
2186
2896
  this._log("Connected as:", this.jid.getLocal() + "@" + this.jid.getDomain());
2187
- if (!this.isLive && !this.roomJID) {
2188
- this.client.send(xml2("presence", {}));
2189
- } else {
2190
- this.client.send(
2191
- xml2(
2192
- "presence",
2193
- { to: this.roomJID + "/" + this.jid.getLocal() },
2194
- xml2(
2195
- "x",
2196
- { xmlns: "http://jabber.org/protocol/muc" },
2197
- xml2(
2198
- "password"
2199
- ),
2200
- xml2(
2201
- "history",
2202
- { maxstanzas: "1" }
2203
- )
2204
- )
2205
- )
2206
- );
2207
- }
2897
+ this.client.send(xml3("presence", {}));
2208
2898
  }
2209
2899
  /**
2210
2900
  * Disconnects the client from the XMPP server.
@@ -2216,10 +2906,29 @@ var SmuleChat = class {
2216
2906
  */
2217
2907
  async disconnect() {
2218
2908
  try {
2909
+ await this.client.send(xml3("presence", { type: "unavailable" }));
2219
2910
  await this.client.stop();
2220
2911
  } catch {
2221
2912
  }
2222
2913
  }
2914
+ sendIq(data, callback, iqType = "get") {
2915
+ const id = randomUUID3();
2916
+ this.iqs[id] = callback;
2917
+ this.client.send(
2918
+ xml3(
2919
+ "iq",
2920
+ { from: this.jid.toString(), to: this.roomJID, type: iqType, id },
2921
+ data
2922
+ )
2923
+ );
2924
+ }
2925
+ sendIqQuery(xmlns, callback, iqType = "get") {
2926
+ this.sendIq(
2927
+ xml3("query", { xmlns }),
2928
+ callback,
2929
+ iqType
2930
+ );
2931
+ }
2223
2932
  /**
2224
2933
  * Send a chat state to the server. This is used to
2225
2934
  * signal whether you are currently active or not.
@@ -2240,10 +2949,10 @@ var SmuleChat = class {
2240
2949
  async sendChatState(to, state = "active") {
2241
2950
  if (typeof to != "string" && "accountId" in to) to = this.getJIDFromUserId(to.accountId);
2242
2951
  await this.client.send(
2243
- xml2(
2952
+ xml3(
2244
2953
  "message",
2245
2954
  { to: to.toString(), type: "chat" },
2246
- xml2(
2955
+ xml3(
2247
2956
  "chatstate",
2248
2957
  { xmlns: "http://jabber.org/protocol/chatstates" },
2249
2958
  state
@@ -2259,50 +2968,29 @@ var SmuleChat = class {
2259
2968
  * @remarks Filtering by a specific JID may not work yet
2260
2969
  */
2261
2970
  async loadMessageHistory(limit = 50, before = null, after = null, jid) {
2262
- if (!this.isLive) {
2263
- if (this.ongoingIq) this._log("Waiting for previous iq to finish...");
2264
- while (this.ongoingIq) await new Promise((resolve) => setTimeout(resolve, 100));
2265
- if (jid)
2266
- this._log(`Loading ${limit} messages with ${jid}...`);
2267
- else
2268
- this._log(`Loading ${limit} messages from history...`);
2269
- if (!before && !after && !jid) this.chats = {};
2270
- this.ongoingIq = true;
2271
- await this.client.send(
2272
- xml2(
2273
- "iq",
2274
- { type: "set", id: "mam-query" },
2275
- xml2(
2276
- "query",
2277
- { xmlns: "urn:xmpp:mam:2" },
2278
- xml2(
2279
- "set",
2280
- { xmlns: "http://jabber.org/protocol/rsm" },
2281
- xml2("max", {}, limit.toString()),
2282
- before ? xml2("before", {}, before.toString()) : null,
2283
- after ? xml2("after", {}, after.toString()) : null
2284
- ),
2285
- jid ? xml2("with", {}, jid.toString()) : null
2286
- )
2287
- )
2288
- );
2289
- while (this.ongoingIq) await new Promise((resolve) => setTimeout(resolve, 100));
2290
- if (this.iqHasMore) await this.loadMessageHistory(limit, null, this.lastIqId, jid);
2291
- } else {
2292
- this._log("Loading live chat history...");
2293
- this.ongoingIq = true;
2294
- await this.client.send(
2295
- xml2(
2296
- "iq",
2297
- { from: this.jid.toString(), to: this.roomJID, type: "get", id: "meow" },
2298
- xml2(
2299
- "query",
2300
- { xmlns: "http://jabber.org/protocol/muc#history" }
2301
- )
2302
- )
2303
- );
2304
- while (this.ongoingIq) await new Promise((resolve) => setTimeout(resolve, 100));
2305
- }
2971
+ if (jid)
2972
+ this._log(`Loading ${limit} messages with ${jid}...`);
2973
+ else
2974
+ this._log(`Loading ${limit} messages from history...`);
2975
+ if (!before && !after && !jid) this.chats = {};
2976
+ this.sendIq(
2977
+ xml3(
2978
+ "query",
2979
+ { xmlns: "urn:xmpp:mam:2" },
2980
+ xml3(
2981
+ "set",
2982
+ { xmlns: "http://jabber.org/protocol/rsm" },
2983
+ xml3("max", {}, limit.toString()),
2984
+ before ? xml3("before", {}, before.toString()) : null,
2985
+ after ? xml3("after", {}, after.toString()) : null
2986
+ ),
2987
+ jid ? xml3("with", {}, jid.toString()) : null
2988
+ ),
2989
+ (el) => {
2990
+ this._log("Finished loading history!", el.toString());
2991
+ },
2992
+ "set"
2993
+ );
2306
2994
  }
2307
2995
  /**
2308
2996
  * Send a text message
@@ -2312,18 +3000,12 @@ var SmuleChat = class {
2312
3000
  async sendTextMessage(jid, message) {
2313
3001
  if (typeof jid != "string" && "accountId" in jid) jid = this.getJIDFromUserId(jid.accountId);
2314
3002
  await this.client.send(
2315
- xml2(
3003
+ xml3(
2316
3004
  "message",
2317
- { to: jid.toString(), type: this.isLive ? "groupchat" : "chat" },
2318
- xml2("body", {}, message)
3005
+ { to: jid.toString(), type: "chat" },
3006
+ xml3("body", {}, message)
2319
3007
  )
2320
3008
  );
2321
- let data = {
2322
- sender: parseInt(this.jid.getLocal()),
2323
- content: message
2324
- };
2325
- this.chats[this.getUserIdFromJID(jid.toString())].messages.push(data);
2326
- this.events.emit("message", data);
2327
3009
  }
2328
3010
  /**
2329
3011
  * Send a performance / recording
@@ -2333,19 +3015,19 @@ var SmuleChat = class {
2333
3015
  async sendPerformanceMessage(jid, performanceKey) {
2334
3016
  if (typeof jid != "string" && "accountId" in jid) jid = this.getJIDFromUserId(jid.accountId);
2335
3017
  await this.client.send(
2336
- xml2(
3018
+ xml3(
2337
3019
  "message",
2338
3020
  { to: jid.toString(), type: "chat" },
2339
- xml2(
3021
+ xml3(
2340
3022
  "performance",
2341
3023
  { xmlns: "urn:x-smule:xmpp" },
2342
- xml2(
3024
+ xml3(
2343
3025
  "key",
2344
3026
  {},
2345
3027
  performanceKey
2346
3028
  )
2347
3029
  ),
2348
- xml2("body", {}, "")
3030
+ xml3("body", {}, "")
2349
3031
  )
2350
3032
  );
2351
3033
  }
@@ -2356,29 +3038,10 @@ var SmuleChat = class {
2356
3038
  async sendReadReceipt(jid) {
2357
3039
  if (typeof jid != "string" && "accountId" in jid) jid = this.getJIDFromUserId(jid.accountId);
2358
3040
  await this.client.send(
2359
- xml2(
3041
+ xml3(
2360
3042
  "message",
2361
3043
  { to: jid.toString(), type: "chat" },
2362
- xml2("received", { xmlns: "urn:xmpp:receipts" })
2363
- )
2364
- );
2365
- }
2366
- //TODO - Most definitely not required
2367
- async archiveMessage(jid, message) {
2368
- if (typeof jid != "string" && "accountId" in jid) jid = this.getJIDFromUserId(jid.accountId);
2369
- await this.client.send(
2370
- xml2(
2371
- "iq",
2372
- { type: "set" },
2373
- xml2(
2374
- "archive",
2375
- { xmlns: "urn:xmpp:mam:2" },
2376
- xml2(
2377
- "item",
2378
- { with: jid, id: Math.random().toString(16).substring(2, 8) },
2379
- xml2("body", {}, message)
2380
- )
2381
- )
3044
+ xml3("received", { xmlns: "urn:xmpp:receipts" })
2382
3045
  )
2383
3046
  );
2384
3047
  }
@@ -2396,7 +3059,6 @@ var SmuleChat = class {
2396
3059
  */
2397
3060
  getUserIdFromJID(jid) {
2398
3061
  if (!(typeof jid == "string")) return parseInt(jid.getLocal());
2399
- if (jid.includes("/")) return parseInt(jid.split("/")[1]);
2400
3062
  return parseInt(jid.split("@")[0]);
2401
3063
  }
2402
3064
  /**
@@ -2406,7 +3068,6 @@ var SmuleChat = class {
2406
3068
  */
2407
3069
  getJIDFromUserId(userId) {
2408
3070
  if (typeof userId != "string" && typeof userId != "number" && "accountId" in userId) userId = userId.accountId;
2409
- if (this.isLive) return this.roomJID + "/" + userId;
2410
3071
  return userId + "@" + this.jid.getDomain();
2411
3072
  }
2412
3073
  //* Processes all message-like elements
@@ -2431,7 +3092,6 @@ var SmuleChat = class {
2431
3092
  }
2432
3093
  child = el.getChild("body");
2433
3094
  const perfChild = el.getChild("performance");
2434
- const perfStartChild = el.getChild("performance-start");
2435
3095
  if (child && (child.getText().trim().length > 0 || perfChild)) {
2436
3096
  this._log("Got message!", child.getText());
2437
3097
  let performanceKey2 = void 0;
@@ -2462,7 +3122,8 @@ var SmuleChat = class {
2462
3122
  content: child.getText(),
2463
3123
  sender: this.getUserIdFromJID(child.parent.getAttr("from")),
2464
3124
  id: child.parent.getAttr("id"),
2465
- performanceKey
3125
+ performanceKey,
3126
+ systemMessage: !!child.parent.getChild("smule-system-msg")
2466
3127
  };
2467
3128
  let chat = this.jid.getLocal().includes(data.sender + "") ? this.getUserIdFromJID(child.parent.getAttr("to")) : data.sender;
2468
3129
  this.events.emit("history", data);
@@ -2471,25 +3132,6 @@ var SmuleChat = class {
2471
3132
  }
2472
3133
  parsePresence(el) {
2473
3134
  if (el.children.length < 1) return;
2474
- if (this.isLive) {
2475
- let child = el.getChildByAttr("xmlns", "http://jabber.org/protocol/muc#user");
2476
- if (child) {
2477
- child = child.getChild("item");
2478
- if (child) {
2479
- if (!el.getAttr("jid")) return;
2480
- let user = this.getUserIdFromJID(el.getAttr("jid"));
2481
- let role = child.getAttr("role");
2482
- let affiliation = child.getAttr("affiliation");
2483
- let data = {
2484
- user,
2485
- role,
2486
- affiliation
2487
- };
2488
- this.roomUsers.push(data);
2489
- this.events.emit("presence", data);
2490
- }
2491
- }
2492
- }
2493
3135
  }
2494
3136
  /**
2495
3137
  * Fetches the chats currently loaded
@@ -2507,9 +3149,6 @@ var SmuleChat = class {
2507
3149
  if (!(user in this.chats)) this.chats[user] = { messages: [] };
2508
3150
  return this.chats[user];
2509
3151
  }
2510
- fetchUsers() {
2511
- return this.roomUsers;
2512
- }
2513
3152
  //#region Internal events
2514
3153
  onClose(el) {
2515
3154
  this._log("Closed!:", el);
@@ -2593,22 +3232,11 @@ var SmuleChat = class {
2593
3232
  this.parsePresence(el);
2594
3233
  } else {
2595
3234
  if (el.is("iq")) {
2596
- let child = el.getChild("fin");
2597
- if (child) {
2598
- if (child.getAttr("complete") == "false") {
2599
- this.iqHasMore = true;
2600
- child = child.getChild("set");
2601
- if (child) {
2602
- child = child.getChild("last");
2603
- if (child) {
2604
- this.lastIqId = child.getText();
2605
- }
2606
- }
2607
- } else {
2608
- this.iqHasMore = false;
2609
- }
3235
+ const id = el.getAttr("id");
3236
+ if (id) {
3237
+ this.iqs[id](el);
3238
+ delete this.iqs[id];
2610
3239
  }
2611
- this.ongoingIq = false;
2612
3240
  }
2613
3241
  this._log("Stanza!", el.toString());
2614
3242
  }
@@ -2616,13 +3244,13 @@ var SmuleChat = class {
2616
3244
  //#endregion Internal events
2617
3245
  //#region Logging
2618
3246
  _log(...args) {
2619
- console.log(this.isLive ? "[SmuleLiveChat]" : "[SmuleChat]", ...args);
3247
+ console.log("[SmuleChat]", ...args);
2620
3248
  }
2621
3249
  _warn(...args) {
2622
- console.warn(this.isLive ? "[SmuleLiveChat]" : "[SmuleChat]", ...args);
3250
+ console.warn("[SmuleChat]", ...args);
2623
3251
  }
2624
3252
  _error(...args) {
2625
- console.error(this.isLive ? "[SmuleLiveChat]" : "[SmuleChat]", ...args);
3253
+ console.error("[SmuleChat]", ...args);
2626
3254
  }
2627
3255
  //#endregion Logging
2628
3256
  };
@@ -2631,7 +3259,7 @@ var SmuleChat = class {
2631
3259
  import { readFileSync } from "fs";
2632
3260
  import * as crypto from "crypto";
2633
3261
  import "@xmpp/jid";
2634
- var APP_VERSION = "12.0.9";
3262
+ var APP_VERSION = "12.6.9";
2635
3263
  var SmuleDigest;
2636
3264
  ((SmuleDigest2) => {
2637
3265
  const SALT = `c2250918de500e32c37842f2d25d4d8210992a0ae96a7f36c4c9703cc675d02b92968bc4fa7feada`;
@@ -3175,13 +3803,37 @@ var Smule = class {
3175
3803
  * Creates a new spark chat
3176
3804
  * @param address The JID address of the chat partner
3177
3805
  * @param type Whether the JID address is an individual or a group
3178
- * @returns idk
3179
3806
  */
3180
3807
  create: async (address, type = "ACCT") => {
3181
3808
  const req = await this.internal._createRequest(SmuleUrls.SparkChatUpdate, { add: [{ name: address, type }], remove: [] });
3809
+ this.internal._handleNon200(req);
3810
+ },
3811
+ /**
3812
+ * Deletes an existing spark chat
3813
+ * @param address The JID address of the chat partner
3814
+ * @param type Whether the JID address is an individual or a group
3815
+ */
3816
+ delete: async (address, type = "ACCT") => {
3817
+ const req = await this.internal._createRequest(SmuleUrls.SparkChatUpdate, { remove: [{ name: address, type }], add: [] });
3818
+ this.internal._handleNon200(req);
3819
+ },
3820
+ /**
3821
+ * Fetches your existing chats
3822
+ * @param type Whether an individual or a group
3823
+ * @returns Your inbox and your message requests
3824
+ */
3825
+ fetchInboxes: async (type = "ACCT") => {
3826
+ const req = await this.internal._createRequest(SmuleUrls.SparkChatList, { type, limit: 200 });
3182
3827
  if (!this.internal._handleNon200(req)) return;
3183
3828
  return this.internal._getResponseData(req);
3184
3829
  },
3830
+ /**
3831
+ * Marks you as offline to your chats
3832
+ */
3833
+ markOffline: async () => {
3834
+ const req = await this.internal._createRequest(SmuleUrls.SparkChatOffline, {});
3835
+ this.internal._handleNon200(req);
3836
+ },
3185
3837
  /**
3186
3838
  * Creates a connection to the XMPP chat server
3187
3839
  */
@@ -4352,9 +5004,9 @@ var Smule = class {
4352
5004
  * @param to The user to send the message to
4353
5005
  * @param message The message body
4354
5006
  */
4355
- sendTextMessage: async (to, message) => {
5007
+ sendTextMessage: async (message) => {
4356
5008
  if (!this.liveChatSession) return;
4357
- await this.liveChatSession.sendTextMessage(to, message);
5009
+ await this.liveChatSession.sendTextMessage(message);
4358
5010
  },
4359
5011
  /**
4360
5012
  * Fetch all loaded chats
@@ -4367,27 +5019,47 @@ var Smule = class {
4367
5019
  fetchUsers: () => {
4368
5020
  if (!this.liveChatSession) return;
4369
5021
  return this.liveChatSession.fetchUsers();
4370
- },
4371
- /**
4372
- * Loads the entire message history
4373
- * @param limit How many messages
4374
- * @param before Messages before this
4375
- * @param after Messages after this
4376
- * @param user The chat partner
4377
- *
4378
- * @remarks This currently recurses until it loads ALL archived messages.
4379
- * This means that it will take a long time to load all messages.
4380
- * @remarks Filtering by a specific user may not work yet
4381
- */
4382
- loadMessageHistory: async (limit = 50, before = null, after = null, user) => {
4383
- if (!this.liveChatSession) return;
4384
- await this.liveChatSession.loadMessageHistory(limit, before, after, user);
4385
5022
  }
4386
5023
  },
5024
+ /**
5025
+ * Fetches ("syncs") a livestream (campfire) so you can connect to it
5026
+ *
5027
+ * @param campfireId The campfire's id
5028
+ * @returns Data regarding the campfire and the streaming details
5029
+ */
4387
5030
  fetch: async (campfireId) => {
4388
5031
  const req = await this.internal._createRequest(SmuleUrls.CfireSync, { campfireId });
4389
5032
  if (!this.internal._handleNon200(req)) return;
4390
5033
  return this.internal._getResponseData(req);
5034
+ },
5035
+ /**
5036
+ * Fetches gifts that have been sent to a live
5037
+ *
5038
+ * @param campfireId The campfire's id
5039
+ * @param cursor The starting point
5040
+ * @param limit How many results
5041
+ * @returns A list of gifts data
5042
+ */
5043
+ fetchRecentGifts: async (campfireId, cursor = "start", limit = 10) => {
5044
+ const req = await this.internal._createRequest(SmuleUrls.GiftRecentTransactions, { campfireId, cursor, limit, animationVersion: "V2", extraGiftTypes: ["SYSTEM"], previewVersion: "PNG", type: "CFIRE" });
5045
+ if (!this.internal._handleNon200(req)) return;
5046
+ return this.internal._getResponseData(req);
5047
+ },
5048
+ /**
5049
+ * Sign up as available to sing
5050
+ * @param campfireId The livestream's id
5051
+ */
5052
+ joinToSing: async (campfireId) => {
5053
+ const req = await this.internal._createRequest(SmuleUrls.CfireSignupAdd, { campfireId, message: "I'm available to sing" });
5054
+ this.internal._handleNon200(req);
5055
+ },
5056
+ /**
5057
+ * Revoke your availability to sing
5058
+ * @param campfireId The livestream's id
5059
+ */
5060
+ revokeJoinToSing: async (campfireId) => {
5061
+ const req = await this.internal._createRequest(SmuleUrls.CfireSignupRemove, { campfireId });
5062
+ this.internal._handleNon200(req);
4391
5063
  }
4392
5064
  };
4393
5065
  groups = {