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.cjs CHANGED
@@ -4,6 +4,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __getProtoOf = Object.getPrototypeOf;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __commonJS = (cb, mod) => function __require() {
8
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
+ };
7
10
  var __export = (target, all) => {
8
11
  for (var name in all)
9
12
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -26,6 +29,625 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
29
  ));
27
30
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
31
 
32
+ // node_modules/ltx/lib/escape.js
33
+ var require_escape = __commonJS({
34
+ "node_modules/ltx/lib/escape.js"(exports2) {
35
+ "use strict";
36
+ var escapeXMLTable = {
37
+ "&": "&",
38
+ "<": "&lt;",
39
+ ">": "&gt;",
40
+ '"': "&quot;",
41
+ "'": "&apos;"
42
+ };
43
+ function escapeXMLReplace(match) {
44
+ return escapeXMLTable[match];
45
+ }
46
+ var unescapeXMLTable = {
47
+ "&amp;": "&",
48
+ "&lt;": "<",
49
+ "&gt;": ">",
50
+ "&quot;": '"',
51
+ "&apos;": "'"
52
+ };
53
+ function unescapeXMLReplace(match) {
54
+ if (match[1] === "#") {
55
+ const num = match[2] === "x" ? parseInt(match.slice(3), 16) : parseInt(match.slice(2), 10);
56
+ if (num === 9 || num === 10 || num === 13 || num >= 32 && num <= 55295 || num >= 57344 && num <= 65533 || num >= 65536 && num <= 1114111) {
57
+ return String.fromCodePoint(num);
58
+ }
59
+ throw new Error("Illegal XML character 0x" + num.toString(16));
60
+ }
61
+ if (unescapeXMLTable[match]) {
62
+ return unescapeXMLTable[match] || match;
63
+ }
64
+ throw new Error("Illegal XML entity " + match);
65
+ }
66
+ function escapeXML2(s) {
67
+ return s.replace(/["&'<>]/g, escapeXMLReplace);
68
+ }
69
+ function unescapeXML2(s) {
70
+ let result = "";
71
+ let start = -1;
72
+ let end = -1;
73
+ let previous = 0;
74
+ while ((start = s.indexOf("&", previous)) !== -1 && (end = s.indexOf(";", start + 1)) !== -1) {
75
+ result = result + s.slice(previous, start) + unescapeXMLReplace(s.slice(start, end + 1));
76
+ previous = end + 1;
77
+ }
78
+ if (previous === 0) return s;
79
+ result = result + s.substring(previous);
80
+ return result;
81
+ }
82
+ function escapeXMLText2(s) {
83
+ return s.replace(/[&<>]/g, escapeXMLReplace);
84
+ }
85
+ function unescapeXMLText2(s) {
86
+ return s.replace(/&(amp|#38|lt|#60|gt|#62);/g, unescapeXMLReplace);
87
+ }
88
+ exports2.escapeXML = escapeXML2;
89
+ exports2.escapeXMLText = escapeXMLText2;
90
+ exports2.unescapeXML = unescapeXML2;
91
+ exports2.unescapeXMLText = unescapeXMLText2;
92
+ }
93
+ });
94
+
95
+ // node_modules/ltx/lib/Element.js
96
+ var require_Element = __commonJS({
97
+ "node_modules/ltx/lib/Element.js"(exports2, module2) {
98
+ "use strict";
99
+ var escape = require_escape();
100
+ var Element5 = class _Element {
101
+ constructor(name, attrs) {
102
+ this.name = name;
103
+ this.parent = null;
104
+ this.children = [];
105
+ this.attrs = {};
106
+ this.setAttrs(attrs);
107
+ }
108
+ /* Accessors */
109
+ /**
110
+ * if (element.is('message', 'jabber:client')) ...
111
+ **/
112
+ is(name, xmlns) {
113
+ return this.getName() === name && (!xmlns || this.getNS() === xmlns);
114
+ }
115
+ /* without prefix */
116
+ getName() {
117
+ const idx = this.name.indexOf(":");
118
+ return idx >= 0 ? this.name.slice(idx + 1) : this.name;
119
+ }
120
+ /**
121
+ * retrieves the namespace of the current element, upwards recursively
122
+ **/
123
+ getNS() {
124
+ const idx = this.name.indexOf(":");
125
+ if (idx >= 0) {
126
+ const prefix = this.name.slice(0, idx);
127
+ return this.findNS(prefix);
128
+ }
129
+ return this.findNS();
130
+ }
131
+ /**
132
+ * find the namespace to the given prefix, upwards recursively
133
+ **/
134
+ findNS(prefix) {
135
+ if (!prefix) {
136
+ if (this.attrs.xmlns) {
137
+ return this.attrs.xmlns;
138
+ } else if (this.parent) {
139
+ return this.parent.findNS();
140
+ }
141
+ } else {
142
+ const attr = "xmlns:" + prefix;
143
+ if (this.attrs[attr]) {
144
+ return this.attrs[attr];
145
+ } else if (this.parent) {
146
+ return this.parent.findNS(prefix);
147
+ }
148
+ }
149
+ }
150
+ /**
151
+ * Recursiverly gets all xmlns defined, in the form of {url:prefix}
152
+ **/
153
+ getXmlns() {
154
+ let namespaces = {};
155
+ if (this.parent) {
156
+ namespaces = this.parent.getXmlns();
157
+ }
158
+ for (const attr in this.attrs) {
159
+ const m = attr.match("xmlns:?(.*)");
160
+ if (this.attrs.hasOwnProperty(attr) && m) {
161
+ namespaces[this.attrs[attr]] = m[1];
162
+ }
163
+ }
164
+ return namespaces;
165
+ }
166
+ setAttrs(attrs) {
167
+ if (typeof attrs === "string") {
168
+ this.attrs.xmlns = attrs;
169
+ } else if (attrs) {
170
+ Object.assign(this.attrs, attrs);
171
+ }
172
+ }
173
+ /**
174
+ * xmlns can be null, returns the matching attribute.
175
+ **/
176
+ getAttr(name, xmlns) {
177
+ if (!xmlns) {
178
+ return this.attrs[name];
179
+ }
180
+ const namespaces = this.getXmlns();
181
+ if (!namespaces[xmlns]) {
182
+ return null;
183
+ }
184
+ return this.attrs[[namespaces[xmlns], name].join(":")];
185
+ }
186
+ /**
187
+ * xmlns can be null
188
+ **/
189
+ getChild(name, xmlns) {
190
+ return this.getChildren(name, xmlns)[0];
191
+ }
192
+ /**
193
+ * xmlns can be null
194
+ **/
195
+ getChildren(name, xmlns) {
196
+ const result = [];
197
+ for (const child of this.children) {
198
+ if (child.getName && child.getName() === name && (!xmlns || child.getNS() === xmlns)) {
199
+ result.push(child);
200
+ }
201
+ }
202
+ return result;
203
+ }
204
+ /**
205
+ * xmlns and recursive can be null
206
+ **/
207
+ getChildByAttr(attr, val, xmlns, recursive) {
208
+ return this.getChildrenByAttr(attr, val, xmlns, recursive)[0];
209
+ }
210
+ /**
211
+ * xmlns and recursive can be null
212
+ **/
213
+ getChildrenByAttr(attr, val, xmlns, recursive) {
214
+ let result = [];
215
+ for (const child of this.children) {
216
+ if (child.attrs && child.attrs[attr] === val && (!xmlns || child.getNS() === xmlns)) {
217
+ result.push(child);
218
+ }
219
+ if (recursive && child.getChildrenByAttr) {
220
+ result.push(child.getChildrenByAttr(attr, val, xmlns, true));
221
+ }
222
+ }
223
+ if (recursive) {
224
+ result = result.flat();
225
+ }
226
+ return result;
227
+ }
228
+ getChildrenByFilter(filter, recursive) {
229
+ let result = [];
230
+ for (const child of this.children) {
231
+ if (filter(child)) {
232
+ result.push(child);
233
+ }
234
+ if (recursive && child.getChildrenByFilter) {
235
+ result.push(child.getChildrenByFilter(filter, true));
236
+ }
237
+ }
238
+ if (recursive) {
239
+ result = result.flat();
240
+ }
241
+ return result;
242
+ }
243
+ getText() {
244
+ let text = "";
245
+ for (const child of this.children) {
246
+ if (typeof child === "string" || typeof child === "number") {
247
+ text += child;
248
+ }
249
+ }
250
+ return text;
251
+ }
252
+ getChildText(name, xmlns) {
253
+ const child = this.getChild(name, xmlns);
254
+ return child ? child.getText() : null;
255
+ }
256
+ /**
257
+ * Return all direct descendents that are Elements.
258
+ * This differs from `getChildren` in that it will exclude text nodes,
259
+ * processing instructions, etc.
260
+ */
261
+ getChildElements() {
262
+ return this.getChildrenByFilter((child) => {
263
+ return child instanceof _Element;
264
+ });
265
+ }
266
+ /* Builder */
267
+ /** returns uppermost parent */
268
+ root() {
269
+ if (this.parent) {
270
+ return this.parent.root();
271
+ }
272
+ return this;
273
+ }
274
+ /** just parent or itself */
275
+ up() {
276
+ if (this.parent) {
277
+ return this.parent;
278
+ }
279
+ return this;
280
+ }
281
+ /** create child node and return it */
282
+ c(name, attrs) {
283
+ return this.cnode(new _Element(name, attrs));
284
+ }
285
+ cnode(child) {
286
+ this.children.push(child);
287
+ if (typeof child === "object") {
288
+ child.parent = this;
289
+ }
290
+ return child;
291
+ }
292
+ append(...nodes) {
293
+ for (const node of nodes) {
294
+ this.children.push(node);
295
+ if (typeof node === "object") {
296
+ node.parent = this;
297
+ }
298
+ }
299
+ }
300
+ prepend(...nodes) {
301
+ for (const node of nodes) {
302
+ this.children.unshift(node);
303
+ if (typeof node === "object") {
304
+ node.parent = this;
305
+ }
306
+ }
307
+ }
308
+ /** add text node and return element */
309
+ t(text) {
310
+ this.children.push(text);
311
+ return this;
312
+ }
313
+ /* Manipulation */
314
+ /**
315
+ * Either:
316
+ * el.remove(childEl)
317
+ * el.remove('author', 'urn:...')
318
+ */
319
+ remove(el, xmlns) {
320
+ const filter = typeof el === "string" ? (child) => {
321
+ return !(child.is && child.is(el, xmlns));
322
+ } : (child) => {
323
+ return child !== el;
324
+ };
325
+ this.children = this.children.filter(filter);
326
+ return this;
327
+ }
328
+ text(val) {
329
+ if (val && this.children.length === 1) {
330
+ this.children[0] = val;
331
+ return this;
332
+ }
333
+ return this.getText();
334
+ }
335
+ attr(attr, val) {
336
+ if (typeof val !== "undefined" || val === null) {
337
+ if (!this.attrs) {
338
+ this.attrs = {};
339
+ }
340
+ this.attrs[attr] = val;
341
+ return this;
342
+ }
343
+ return this.attrs[attr];
344
+ }
345
+ /* Serialization */
346
+ toString() {
347
+ let s = "";
348
+ this.write((c) => {
349
+ s += c;
350
+ });
351
+ return s;
352
+ }
353
+ _addChildren(writer) {
354
+ writer(">");
355
+ for (const child of this.children) {
356
+ if (child != null) {
357
+ if (child.write) {
358
+ child.write(writer);
359
+ } else if (typeof child === "string") {
360
+ writer(escape.escapeXMLText(child));
361
+ } else if (child.toString) {
362
+ writer(escape.escapeXMLText(child.toString(10)));
363
+ }
364
+ }
365
+ }
366
+ writer("</");
367
+ writer(this.name);
368
+ writer(">");
369
+ }
370
+ write(writer) {
371
+ writer("<");
372
+ writer(this.name);
373
+ for (const k in this.attrs) {
374
+ const v = this.attrs[k];
375
+ if (v != null) {
376
+ writer(" ");
377
+ writer(k);
378
+ writer('="');
379
+ writer(escape.escapeXML(typeof v === "string" ? v : v.toString(10)));
380
+ writer('"');
381
+ }
382
+ }
383
+ if (this.children.length === 0) {
384
+ writer("/>");
385
+ } else {
386
+ this._addChildren(writer);
387
+ }
388
+ }
389
+ };
390
+ Element5.prototype.tree = Element5.prototype.root;
391
+ module2.exports = Element5;
392
+ }
393
+ });
394
+
395
+ // node_modules/ltx/lib/createElement.js
396
+ var require_createElement = __commonJS({
397
+ "node_modules/ltx/lib/createElement.js"(exports2, module2) {
398
+ "use strict";
399
+ var Element5 = require_Element();
400
+ function append(el, child) {
401
+ if (Array.isArray(child)) {
402
+ for (const c of child) append(el, c);
403
+ return;
404
+ }
405
+ if (child === "" || child == null || child === true || child === false) {
406
+ return;
407
+ }
408
+ el.cnode(child);
409
+ }
410
+ function createElement2(name, attrs, ...children) {
411
+ if (typeof attrs === "object" && attrs !== null) {
412
+ delete attrs.__source;
413
+ delete attrs.__self;
414
+ for (const [key, value] of Object.entries(attrs)) {
415
+ if (value == null) delete attrs[key];
416
+ else attrs[key] = value.toString(10);
417
+ }
418
+ }
419
+ const el = new Element5(name, attrs);
420
+ for (const child of children) {
421
+ append(el, child);
422
+ }
423
+ return el;
424
+ }
425
+ module2.exports = createElement2;
426
+ }
427
+ });
428
+
429
+ // node_modules/ltx/lib/parsers/ltx.js
430
+ var require_ltx = __commonJS({
431
+ "node_modules/ltx/lib/parsers/ltx.js"(exports2, module2) {
432
+ "use strict";
433
+ var events = require("events");
434
+ var escape = require_escape();
435
+ var STATE_TEXT = 0;
436
+ var STATE_IGNORE_COMMENT = 1;
437
+ var STATE_IGNORE_INSTRUCTION = 2;
438
+ var STATE_TAG_NAME = 3;
439
+ var STATE_TAG = 4;
440
+ var STATE_ATTR_NAME = 5;
441
+ var STATE_ATTR_EQ = 6;
442
+ var STATE_ATTR_QUOT = 7;
443
+ var STATE_ATTR_VALUE = 8;
444
+ var STATE_CDATA = 9;
445
+ var STATE_IGNORE_CDATA = 10;
446
+ var SaxLtx = class extends events.EventEmitter {
447
+ constructor() {
448
+ super();
449
+ let state = STATE_TEXT;
450
+ let remainder;
451
+ let parseRemainder;
452
+ let tagName;
453
+ let attrs;
454
+ let endTag;
455
+ let selfClosing;
456
+ let attrQuote;
457
+ let attrQuoteChar;
458
+ let recordStart = 0;
459
+ let attrName;
460
+ this._handleTagOpening = function _handleTagOpening(endTag2, tagName2, attrs2) {
461
+ if (!endTag2) {
462
+ this.emit("startElement", tagName2, attrs2);
463
+ if (selfClosing) {
464
+ this.emit("endElement", tagName2, true);
465
+ }
466
+ } else {
467
+ this.emit("endElement", tagName2, false);
468
+ }
469
+ };
470
+ this.write = function write(data) {
471
+ if (typeof data !== "string") {
472
+ data = data.toString();
473
+ }
474
+ let pos = 0;
475
+ if (remainder) {
476
+ data = remainder + data;
477
+ pos += !parseRemainder ? remainder.length : 0;
478
+ parseRemainder = false;
479
+ remainder = null;
480
+ }
481
+ function endRecording() {
482
+ if (typeof recordStart === "number") {
483
+ const recorded = data.slice(recordStart, pos);
484
+ recordStart = void 0;
485
+ return recorded;
486
+ }
487
+ }
488
+ for (; pos < data.length; pos++) {
489
+ switch (state) {
490
+ case STATE_TEXT: {
491
+ const lt = data.indexOf("<", pos);
492
+ if (lt !== -1 && pos !== lt) {
493
+ pos = lt;
494
+ }
495
+ break;
496
+ }
497
+ case STATE_ATTR_VALUE: {
498
+ const quot = data.indexOf(attrQuoteChar, pos);
499
+ if (quot !== -1) {
500
+ pos = quot;
501
+ }
502
+ break;
503
+ }
504
+ case STATE_IGNORE_COMMENT: {
505
+ const endcomment = data.indexOf("-->", pos);
506
+ if (endcomment !== -1) {
507
+ pos = endcomment + 2;
508
+ }
509
+ break;
510
+ }
511
+ case STATE_IGNORE_CDATA: {
512
+ const endCDATA = data.indexOf("]]>", pos);
513
+ if (endCDATA !== -1) {
514
+ pos = endCDATA + 2;
515
+ }
516
+ break;
517
+ }
518
+ }
519
+ const c = data.charCodeAt(pos);
520
+ switch (state) {
521
+ case STATE_TEXT:
522
+ if (c === 60) {
523
+ const text = endRecording();
524
+ if (text) {
525
+ this.emit("text", escape.unescapeXML(text));
526
+ }
527
+ state = STATE_TAG_NAME;
528
+ recordStart = pos + 1;
529
+ attrs = {};
530
+ }
531
+ break;
532
+ case STATE_CDATA:
533
+ if (c === 93) {
534
+ if (data.substr(pos + 1, 2) === "]>") {
535
+ const cData = endRecording();
536
+ if (cData) {
537
+ this.emit("text", cData);
538
+ }
539
+ state = STATE_TEXT;
540
+ } else if (data.length < pos + 2) {
541
+ parseRemainder = true;
542
+ pos = data.length;
543
+ }
544
+ }
545
+ break;
546
+ case STATE_TAG_NAME:
547
+ if (c === 47 && recordStart === pos) {
548
+ recordStart = pos + 1;
549
+ endTag = true;
550
+ } else if (c === 33) {
551
+ if (data.substr(pos + 1, 7) === "[CDATA[") {
552
+ recordStart = pos + 8;
553
+ state = STATE_CDATA;
554
+ } else if (data.length < pos + 8 && "[CDATA[".startsWith(data.slice(pos + 1))) {
555
+ parseRemainder = true;
556
+ pos = data.length;
557
+ } else {
558
+ recordStart = void 0;
559
+ state = STATE_IGNORE_COMMENT;
560
+ }
561
+ } else if (c === 63) {
562
+ recordStart = void 0;
563
+ state = STATE_IGNORE_INSTRUCTION;
564
+ } else if (c <= 32 || c === 47 || c === 62) {
565
+ tagName = endRecording();
566
+ pos--;
567
+ state = STATE_TAG;
568
+ }
569
+ break;
570
+ case STATE_IGNORE_COMMENT:
571
+ if (c === 62) {
572
+ const prevFirst = data.charCodeAt(pos - 1);
573
+ const prevSecond = data.charCodeAt(pos - 2);
574
+ if (prevFirst === 45 && prevSecond === 45 || prevFirst === 93 && prevSecond === 93) {
575
+ state = STATE_TEXT;
576
+ }
577
+ }
578
+ break;
579
+ case STATE_IGNORE_INSTRUCTION:
580
+ if (c === 62) {
581
+ const prev = data.charCodeAt(pos - 1);
582
+ if (prev === 63) {
583
+ state = STATE_TEXT;
584
+ }
585
+ }
586
+ break;
587
+ case STATE_TAG:
588
+ if (c === 62) {
589
+ this._handleTagOpening(endTag, tagName, attrs);
590
+ tagName = void 0;
591
+ attrs = void 0;
592
+ endTag = void 0;
593
+ selfClosing = void 0;
594
+ state = STATE_TEXT;
595
+ recordStart = pos + 1;
596
+ } else if (c === 47) {
597
+ selfClosing = true;
598
+ } else if (c > 32) {
599
+ recordStart = pos;
600
+ state = STATE_ATTR_NAME;
601
+ }
602
+ break;
603
+ case STATE_ATTR_NAME:
604
+ if (c <= 32 || c === 61) {
605
+ attrName = endRecording();
606
+ pos--;
607
+ state = STATE_ATTR_EQ;
608
+ }
609
+ break;
610
+ case STATE_ATTR_EQ:
611
+ if (c === 61) {
612
+ state = STATE_ATTR_QUOT;
613
+ }
614
+ break;
615
+ case STATE_ATTR_QUOT:
616
+ if (c === 34 || c === 39) {
617
+ attrQuote = c;
618
+ attrQuoteChar = c === 34 ? '"' : "'";
619
+ state = STATE_ATTR_VALUE;
620
+ recordStart = pos + 1;
621
+ }
622
+ break;
623
+ case STATE_ATTR_VALUE:
624
+ if (c === attrQuote) {
625
+ const value = escape.unescapeXML(endRecording());
626
+ attrs[attrName] = value;
627
+ attrName = void 0;
628
+ state = STATE_TAG;
629
+ }
630
+ break;
631
+ }
632
+ }
633
+ if (typeof recordStart === "number" && recordStart <= data.length) {
634
+ remainder = data.slice(recordStart);
635
+ recordStart = 0;
636
+ }
637
+ };
638
+ }
639
+ end(data) {
640
+ if (data) {
641
+ this.write(data);
642
+ }
643
+ this.write = function write() {
644
+ };
645
+ }
646
+ };
647
+ module2.exports = SaxLtx;
648
+ }
649
+ });
650
+
29
651
  // src/index.ts
30
652
  var index_exports = {};
31
653
  __export(index_exports, {
@@ -1360,22 +1982,117 @@ var SmuleUrls;
1360
1982
  ]);
1361
1983
  })(SmuleUrls || (SmuleUrls = {}));
1362
1984
 
1985
+ // node_modules/@xmpp/xml/index.js
1986
+ var import_Element2 = __toESM(require_Element(), 1);
1987
+ var import_createElement = __toESM(require_createElement(), 1);
1988
+ var import_escape = __toESM(require_escape(), 1);
1989
+
1990
+ // node_modules/@xmpp/xml/lib/Parser.js
1991
+ var import_ltx = __toESM(require_ltx(), 1);
1992
+ var import_Element = __toESM(require_Element(), 1);
1993
+
1994
+ // node_modules/@xmpp/events/index.js
1995
+ var import_events = require("events");
1996
+
1997
+ // node_modules/@xmpp/xml/lib/XMLError.js
1998
+ var XMLError = class extends Error {
1999
+ constructor(...args) {
2000
+ super(...args);
2001
+ this.name = "XMLError";
2002
+ }
2003
+ };
2004
+
2005
+ // node_modules/@xmpp/xml/lib/Parser.js
2006
+ var Parser = class extends import_events.EventEmitter {
2007
+ constructor() {
2008
+ super();
2009
+ const parser = new import_ltx.default();
2010
+ this.root = null;
2011
+ this.cursor = null;
2012
+ parser.on("startElement", this.onStartElement.bind(this));
2013
+ parser.on("endElement", this.onEndElement.bind(this));
2014
+ parser.on("text", this.onText.bind(this));
2015
+ this.parser = parser;
2016
+ }
2017
+ onStartElement(name, attrs) {
2018
+ const element = new import_Element.default(name, attrs);
2019
+ const { root, cursor } = this;
2020
+ if (!root) {
2021
+ this.root = element;
2022
+ this.emit("start", element);
2023
+ } else if (cursor !== root) {
2024
+ cursor.append(element);
2025
+ }
2026
+ this.cursor = element;
2027
+ }
2028
+ onEndElement(name) {
2029
+ const { root, cursor } = this;
2030
+ if (name !== cursor.name) {
2031
+ this.emit("error", new XMLError(`${cursor.name} must be closed.`));
2032
+ return;
2033
+ }
2034
+ if (cursor === root) {
2035
+ this.emit("end", root);
2036
+ return;
2037
+ }
2038
+ if (!cursor.parent) {
2039
+ cursor.parent = root;
2040
+ this.emit("element", cursor);
2041
+ this.cursor = root;
2042
+ return;
2043
+ }
2044
+ this.cursor = cursor.parent;
2045
+ }
2046
+ onText(str) {
2047
+ const { cursor } = this;
2048
+ if (!cursor) {
2049
+ this.emit("error", new XMLError(`${str} must be a child.`));
2050
+ return;
2051
+ }
2052
+ cursor.t(str);
2053
+ }
2054
+ write(data) {
2055
+ this.parser.write(data);
2056
+ }
2057
+ end(data) {
2058
+ if (data) {
2059
+ this.parser.write(data);
2060
+ }
2061
+ }
2062
+ };
2063
+ Parser.XMLError = XMLError;
2064
+ var Parser_default = Parser;
2065
+
2066
+ // node_modules/@xmpp/xml/index.js
2067
+ function xml(...args) {
2068
+ return (0, import_createElement.default)(...args);
2069
+ }
2070
+ Object.assign(xml, {
2071
+ Element: import_Element2.default,
2072
+ createElement: import_createElement.default,
2073
+ Parser: Parser_default,
2074
+ escapeXML: import_escape.escapeXML,
2075
+ unescapeXML: import_escape.unescapeXML,
2076
+ escapeXMLText: import_escape.escapeXMLText,
2077
+ unescapeXMLText: import_escape.unescapeXMLText,
2078
+ XMLError,
2079
+ xml
2080
+ });
2081
+
1363
2082
  // src/smule-live-chat.ts
1364
- var import_xml = require("@xmpp/xml");
1365
- var import_events = __toESM(require("events"), 1);
2083
+ var import_events3 = __toESM(require("events"), 1);
1366
2084
  var import_jid = require("@xmpp/jid");
2085
+ var import_crypto2 = require("crypto");
1367
2086
  var SmuleLiveChat = class {
1368
- events = new import_events.default();
2087
+ events = new import_events3.default();
1369
2088
  state = "closed";
1370
2089
  client;
1371
2090
  jid;
1372
- ongoingIq = false;
1373
- iqHasMore = false;
1374
- lastIqId = "0";
2091
+ iqs = {};
1375
2092
  roomJID = null;
1376
2093
  roomUsers = [];
1377
2094
  chat = { messages: [] };
1378
- constructor(userId, session, host = SmuleUrls.userChat, roomJID) {
2095
+ constructor(userId, session, host = SmuleUrls.cfireChat, roomJID) {
1379
2096
  this.client = (0, import_client.client)({
1380
2097
  service: "xmpp://" + host,
1381
2098
  domain: host,
@@ -1423,6 +2140,9 @@ var SmuleLiveChat = class {
1423
2140
  )
1424
2141
  )
1425
2142
  );
2143
+ this.sendIqQuery("http://jabber.org/protocol/disco#info", (el) => {
2144
+ console.log("reply from disco", el);
2145
+ });
1426
2146
  }
1427
2147
  /**
1428
2148
  * Disconnects the client from the XMPP server.
@@ -1434,83 +2154,41 @@ var SmuleLiveChat = class {
1434
2154
  */
1435
2155
  async disconnect() {
1436
2156
  try {
2157
+ await this.client.send((0, import_client.xml)("presence", { type: "unavailable" }));
1437
2158
  await this.client.stop();
1438
2159
  } catch {
1439
2160
  }
1440
2161
  }
1441
- /**
1442
- * Send a chat state to the server. This is used to
1443
- * signal whether you are currently active or not.
1444
- *
1445
- * active -> You're active
1446
- *
1447
- * composing -> Typing
1448
- *
1449
- * paused -> Just stopped typing
1450
- *
1451
- * inactive -> You're inactive
1452
- *
1453
- * gone -> You're hidden / disconnected / You've left the chat
1454
- *
1455
- * @param state One of `active`, `composing`, `paused`, `inactive`, or `gone`.
1456
- * Default is `active`
1457
- */
1458
- async sendChatState(to, state = "active") {
1459
- if (typeof to != "string" && "accountId" in to) to = this.getJIDFromUserId(to.accountId);
1460
- await this.client.send(
2162
+ sendIq(data, callback, iqType = "get") {
2163
+ const id = (0, import_crypto2.randomUUID)();
2164
+ this.iqs[id] = callback;
2165
+ this.client.send(
1461
2166
  (0, import_client.xml)(
1462
- "message",
1463
- { to: to.toString(), type: "chat" },
1464
- (0, import_client.xml)(
1465
- "chatstate",
1466
- { xmlns: "http://jabber.org/protocol/chatstates" },
1467
- state
1468
- )
2167
+ "iq",
2168
+ { from: this.jid.toString(), to: this.roomJID, type: iqType, id },
2169
+ data
1469
2170
  )
1470
2171
  );
1471
2172
  }
1472
- /**
1473
- * Loads the entire message history
1474
- * @param limit The maximum number of messages to fetch. Default is 50.
1475
- * @remarks This currently recurses until it loads ALL archived messages.
1476
- * This means that it will take a long time to load all messages.
1477
- * @remarks Filtering by a specific JID may not work yet
1478
- */
1479
- async loadMessageHistory(limit = 50, before = null, after = null, jid) {
1480
- this._log("Loading live chat history...");
1481
- this.ongoingIq = true;
1482
- await this.client.send(
1483
- (0, import_client.xml)(
1484
- "iq",
1485
- { from: this.jid.toString(), to: this.roomJID, type: "get", id: "meow" },
1486
- (0, import_client.xml)(
1487
- "query",
1488
- { xmlns: "http://jabber.org/protocol/muc#history" }
1489
- )
1490
- )
2173
+ sendIqQuery(xmlns, callback, iqType = "get") {
2174
+ this.sendIq(
2175
+ (0, import_client.xml)("query", { xmlns }),
2176
+ callback,
2177
+ iqType
1491
2178
  );
1492
- while (this.ongoingIq) await new Promise((resolve) => setTimeout(resolve, 100));
1493
2179
  }
1494
2180
  /**
1495
- * Send a text message
1496
- * @param jid The JID to send the message to
2181
+ * Send a text message to the livestream
1497
2182
  * @param message The message body
1498
2183
  */
1499
- async sendTextMessage(jid, message) {
1500
- if (typeof jid != "string" && "accountId" in jid) jid = this.getJIDFromUserId(jid.accountId);
2184
+ async sendTextMessage(message) {
1501
2185
  await this.client.send(
1502
2186
  (0, import_client.xml)(
1503
2187
  "message",
1504
- { to: jid.toString(), type: "groupchat" },
2188
+ { to: this.roomJID, type: "groupchat" },
1505
2189
  (0, import_client.xml)("body", {}, message)
1506
2190
  )
1507
2191
  );
1508
- const data = {
1509
- sender: parseInt(this.jid.getLocal()),
1510
- content: message
1511
- };
1512
- this.chat[this.getUserIdFromJID(jid.toString())].messages.push(data);
1513
- this.events.emit("message", data);
1514
2192
  }
1515
2193
  /**
1516
2194
  * Read-only jid to prevent any bugs
@@ -1623,6 +2301,23 @@ var SmuleLiveChat = class {
1623
2301
  this._log("Got host left!", data2);
1624
2302
  this.events.emit("host-left", data2);
1625
2303
  }
2304
+ child = el.getChild("song-listen");
2305
+ if (child) {
2306
+ const data2 = {
2307
+ arrKey: child.getChild("arrangement-key").getText(),
2308
+ hostSessionId: child.getChild("host-session-id").getText()
2309
+ };
2310
+ this._log("Got song listen!", data2);
2311
+ this.events.emit("song-listen", data2);
2312
+ }
2313
+ child = el.getChild("campfire-ended");
2314
+ if (child) {
2315
+ const data2 = {
2316
+ reason: child.getChild("reason").getText()
2317
+ };
2318
+ this._log("Got stop livestream!", data2);
2319
+ this.events.emit("stop-livestream", data2);
2320
+ }
1626
2321
  child = el.getChild("result");
1627
2322
  if (!child) return;
1628
2323
  child = child.getChild("forwarded");
@@ -1646,15 +2341,17 @@ var SmuleLiveChat = class {
1646
2341
  if (child) {
1647
2342
  child = child.getChild("item");
1648
2343
  if (child) {
1649
- if (!el.getAttr("jid")) return;
1650
- const data = {
1651
- user: this.getUserIdFromJID(el.getAttr("jid")),
1652
- role: child.getAttr("role"),
1653
- affiliation: child.getAttr("affiliation")
1654
- };
1655
- this._log("Got presence!", data);
1656
- this.roomUsers.push(data);
1657
- this.events.emit("presence", data);
2344
+ if (!el.getAttr("jid")) {
2345
+ } else {
2346
+ const data = {
2347
+ user: this.getUserIdFromJID(el.getAttr("jid")),
2348
+ role: child.getAttr("role"),
2349
+ affiliation: child.getAttr("affiliation")
2350
+ };
2351
+ this._log("Got presence!", data);
2352
+ this.roomUsers.push(data);
2353
+ this.events.emit("presence", data);
2354
+ }
1658
2355
  }
1659
2356
  }
1660
2357
  }
@@ -1751,22 +2448,11 @@ var SmuleLiveChat = class {
1751
2448
  this.parsePresence(el);
1752
2449
  } else {
1753
2450
  if (el.is("iq")) {
1754
- let child = el.getChild("fin");
1755
- if (child) {
1756
- if (child.getAttr("complete") == "false") {
1757
- this.iqHasMore = true;
1758
- child = child.getChild("set");
1759
- if (child) {
1760
- child = child.getChild("last");
1761
- if (child) {
1762
- this.lastIqId = child.getText();
1763
- }
1764
- }
1765
- } else {
1766
- this.iqHasMore = false;
1767
- }
2451
+ const id = el.getAttr("id");
2452
+ if (id) {
2453
+ this.iqs[id](el);
2454
+ delete this.iqs[id];
1768
2455
  }
1769
- this.ongoingIq = false;
1770
2456
  }
1771
2457
  this._log("Stanza!", el.toString());
1772
2458
  }
@@ -2200,20 +2886,16 @@ var SmuleMIDI;
2200
2886
 
2201
2887
  // src/smule-chat.ts
2202
2888
  var import_client2 = require("@xmpp/client");
2203
- var import_xml2 = require("@xmpp/xml");
2204
- var import_events2 = __toESM(require("events"), 1);
2889
+ var import_events4 = __toESM(require("events"), 1);
2205
2890
  var import_jid2 = require("@xmpp/jid");
2891
+ var import_crypto3 = require("crypto");
2206
2892
  var SmuleChat = class {
2207
- events = new import_events2.default();
2893
+ events = new import_events4.default();
2208
2894
  state = "closed";
2209
2895
  client;
2210
2896
  jid;
2211
- ongoingIq = false;
2212
- iqHasMore = false;
2213
- lastIqId = "0";
2214
- isLive = false;
2897
+ iqs = {};
2215
2898
  roomJID = null;
2216
- roomUsers = [];
2217
2899
  chats = {};
2218
2900
  constructor(userId, session, host = SmuleUrls.userChat, roomJID) {
2219
2901
  this.client = (0, import_client2.client)({
@@ -2224,7 +2906,6 @@ var SmuleChat = class {
2224
2906
  username: userId + "",
2225
2907
  password: session
2226
2908
  });
2227
- this.isLive = host != SmuleUrls.userChat || !!roomJID;
2228
2909
  this.roomJID = roomJID;
2229
2910
  this.client.on("close", (el) => this.onClose(el));
2230
2911
  this.client.on("closing", () => this.onClosing());
@@ -2247,27 +2928,7 @@ var SmuleChat = class {
2247
2928
  async connect() {
2248
2929
  this.jid = await this.client.start();
2249
2930
  this._log("Connected as:", this.jid.getLocal() + "@" + this.jid.getDomain());
2250
- if (!this.isLive && !this.roomJID) {
2251
- this.client.send((0, import_client2.xml)("presence", {}));
2252
- } else {
2253
- this.client.send(
2254
- (0, import_client2.xml)(
2255
- "presence",
2256
- { to: this.roomJID + "/" + this.jid.getLocal() },
2257
- (0, import_client2.xml)(
2258
- "x",
2259
- { xmlns: "http://jabber.org/protocol/muc" },
2260
- (0, import_client2.xml)(
2261
- "password"
2262
- ),
2263
- (0, import_client2.xml)(
2264
- "history",
2265
- { maxstanzas: "1" }
2266
- )
2267
- )
2268
- )
2269
- );
2270
- }
2931
+ this.client.send((0, import_client2.xml)("presence", {}));
2271
2932
  }
2272
2933
  /**
2273
2934
  * Disconnects the client from the XMPP server.
@@ -2279,10 +2940,29 @@ var SmuleChat = class {
2279
2940
  */
2280
2941
  async disconnect() {
2281
2942
  try {
2943
+ await this.client.send((0, import_client2.xml)("presence", { type: "unavailable" }));
2282
2944
  await this.client.stop();
2283
2945
  } catch {
2284
2946
  }
2285
2947
  }
2948
+ sendIq(data, callback, iqType = "get") {
2949
+ const id = (0, import_crypto3.randomUUID)();
2950
+ this.iqs[id] = callback;
2951
+ this.client.send(
2952
+ (0, import_client2.xml)(
2953
+ "iq",
2954
+ { from: this.jid.toString(), to: this.roomJID, type: iqType, id },
2955
+ data
2956
+ )
2957
+ );
2958
+ }
2959
+ sendIqQuery(xmlns, callback, iqType = "get") {
2960
+ this.sendIq(
2961
+ (0, import_client2.xml)("query", { xmlns }),
2962
+ callback,
2963
+ iqType
2964
+ );
2965
+ }
2286
2966
  /**
2287
2967
  * Send a chat state to the server. This is used to
2288
2968
  * signal whether you are currently active or not.
@@ -2322,50 +3002,29 @@ var SmuleChat = class {
2322
3002
  * @remarks Filtering by a specific JID may not work yet
2323
3003
  */
2324
3004
  async loadMessageHistory(limit = 50, before = null, after = null, jid) {
2325
- if (!this.isLive) {
2326
- if (this.ongoingIq) this._log("Waiting for previous iq to finish...");
2327
- while (this.ongoingIq) await new Promise((resolve) => setTimeout(resolve, 100));
2328
- if (jid)
2329
- this._log(`Loading ${limit} messages with ${jid}...`);
2330
- else
2331
- this._log(`Loading ${limit} messages from history...`);
2332
- if (!before && !after && !jid) this.chats = {};
2333
- this.ongoingIq = true;
2334
- await this.client.send(
2335
- (0, import_client2.xml)(
2336
- "iq",
2337
- { type: "set", id: "mam-query" },
2338
- (0, import_client2.xml)(
2339
- "query",
2340
- { xmlns: "urn:xmpp:mam:2" },
2341
- (0, import_client2.xml)(
2342
- "set",
2343
- { xmlns: "http://jabber.org/protocol/rsm" },
2344
- (0, import_client2.xml)("max", {}, limit.toString()),
2345
- before ? (0, import_client2.xml)("before", {}, before.toString()) : null,
2346
- after ? (0, import_client2.xml)("after", {}, after.toString()) : null
2347
- ),
2348
- jid ? (0, import_client2.xml)("with", {}, jid.toString()) : null
2349
- )
2350
- )
2351
- );
2352
- while (this.ongoingIq) await new Promise((resolve) => setTimeout(resolve, 100));
2353
- if (this.iqHasMore) await this.loadMessageHistory(limit, null, this.lastIqId, jid);
2354
- } else {
2355
- this._log("Loading live chat history...");
2356
- this.ongoingIq = true;
2357
- await this.client.send(
3005
+ if (jid)
3006
+ this._log(`Loading ${limit} messages with ${jid}...`);
3007
+ else
3008
+ this._log(`Loading ${limit} messages from history...`);
3009
+ if (!before && !after && !jid) this.chats = {};
3010
+ this.sendIq(
3011
+ (0, import_client2.xml)(
3012
+ "query",
3013
+ { xmlns: "urn:xmpp:mam:2" },
2358
3014
  (0, import_client2.xml)(
2359
- "iq",
2360
- { from: this.jid.toString(), to: this.roomJID, type: "get", id: "meow" },
2361
- (0, import_client2.xml)(
2362
- "query",
2363
- { xmlns: "http://jabber.org/protocol/muc#history" }
2364
- )
2365
- )
2366
- );
2367
- while (this.ongoingIq) await new Promise((resolve) => setTimeout(resolve, 100));
2368
- }
3015
+ "set",
3016
+ { xmlns: "http://jabber.org/protocol/rsm" },
3017
+ (0, import_client2.xml)("max", {}, limit.toString()),
3018
+ before ? (0, import_client2.xml)("before", {}, before.toString()) : null,
3019
+ after ? (0, import_client2.xml)("after", {}, after.toString()) : null
3020
+ ),
3021
+ jid ? (0, import_client2.xml)("with", {}, jid.toString()) : null
3022
+ ),
3023
+ (el) => {
3024
+ this._log("Finished loading history!", el.toString());
3025
+ },
3026
+ "set"
3027
+ );
2369
3028
  }
2370
3029
  /**
2371
3030
  * Send a text message
@@ -2377,16 +3036,10 @@ var SmuleChat = class {
2377
3036
  await this.client.send(
2378
3037
  (0, import_client2.xml)(
2379
3038
  "message",
2380
- { to: jid.toString(), type: this.isLive ? "groupchat" : "chat" },
3039
+ { to: jid.toString(), type: "chat" },
2381
3040
  (0, import_client2.xml)("body", {}, message)
2382
3041
  )
2383
3042
  );
2384
- let data = {
2385
- sender: parseInt(this.jid.getLocal()),
2386
- content: message
2387
- };
2388
- this.chats[this.getUserIdFromJID(jid.toString())].messages.push(data);
2389
- this.events.emit("message", data);
2390
3043
  }
2391
3044
  /**
2392
3045
  * Send a performance / recording
@@ -2426,25 +3079,6 @@ var SmuleChat = class {
2426
3079
  )
2427
3080
  );
2428
3081
  }
2429
- //TODO - Most definitely not required
2430
- async archiveMessage(jid, message) {
2431
- if (typeof jid != "string" && "accountId" in jid) jid = this.getJIDFromUserId(jid.accountId);
2432
- await this.client.send(
2433
- (0, import_client2.xml)(
2434
- "iq",
2435
- { type: "set" },
2436
- (0, import_client2.xml)(
2437
- "archive",
2438
- { xmlns: "urn:xmpp:mam:2" },
2439
- (0, import_client2.xml)(
2440
- "item",
2441
- { with: jid, id: Math.random().toString(16).substring(2, 8) },
2442
- (0, import_client2.xml)("body", {}, message)
2443
- )
2444
- )
2445
- )
2446
- );
2447
- }
2448
3082
  /**
2449
3083
  * Read-only jid to prevent any bugs
2450
3084
  * @returns user's JID
@@ -2459,7 +3093,6 @@ var SmuleChat = class {
2459
3093
  */
2460
3094
  getUserIdFromJID(jid) {
2461
3095
  if (!(typeof jid == "string")) return parseInt(jid.getLocal());
2462
- if (jid.includes("/")) return parseInt(jid.split("/")[1]);
2463
3096
  return parseInt(jid.split("@")[0]);
2464
3097
  }
2465
3098
  /**
@@ -2469,7 +3102,6 @@ var SmuleChat = class {
2469
3102
  */
2470
3103
  getJIDFromUserId(userId) {
2471
3104
  if (typeof userId != "string" && typeof userId != "number" && "accountId" in userId) userId = userId.accountId;
2472
- if (this.isLive) return this.roomJID + "/" + userId;
2473
3105
  return userId + "@" + this.jid.getDomain();
2474
3106
  }
2475
3107
  //* Processes all message-like elements
@@ -2494,7 +3126,6 @@ var SmuleChat = class {
2494
3126
  }
2495
3127
  child = el.getChild("body");
2496
3128
  const perfChild = el.getChild("performance");
2497
- const perfStartChild = el.getChild("performance-start");
2498
3129
  if (child && (child.getText().trim().length > 0 || perfChild)) {
2499
3130
  this._log("Got message!", child.getText());
2500
3131
  let performanceKey2 = void 0;
@@ -2525,7 +3156,8 @@ var SmuleChat = class {
2525
3156
  content: child.getText(),
2526
3157
  sender: this.getUserIdFromJID(child.parent.getAttr("from")),
2527
3158
  id: child.parent.getAttr("id"),
2528
- performanceKey
3159
+ performanceKey,
3160
+ systemMessage: !!child.parent.getChild("smule-system-msg")
2529
3161
  };
2530
3162
  let chat = this.jid.getLocal().includes(data.sender + "") ? this.getUserIdFromJID(child.parent.getAttr("to")) : data.sender;
2531
3163
  this.events.emit("history", data);
@@ -2534,25 +3166,6 @@ var SmuleChat = class {
2534
3166
  }
2535
3167
  parsePresence(el) {
2536
3168
  if (el.children.length < 1) return;
2537
- if (this.isLive) {
2538
- let child = el.getChildByAttr("xmlns", "http://jabber.org/protocol/muc#user");
2539
- if (child) {
2540
- child = child.getChild("item");
2541
- if (child) {
2542
- if (!el.getAttr("jid")) return;
2543
- let user = this.getUserIdFromJID(el.getAttr("jid"));
2544
- let role = child.getAttr("role");
2545
- let affiliation = child.getAttr("affiliation");
2546
- let data = {
2547
- user,
2548
- role,
2549
- affiliation
2550
- };
2551
- this.roomUsers.push(data);
2552
- this.events.emit("presence", data);
2553
- }
2554
- }
2555
- }
2556
3169
  }
2557
3170
  /**
2558
3171
  * Fetches the chats currently loaded
@@ -2570,9 +3183,6 @@ var SmuleChat = class {
2570
3183
  if (!(user in this.chats)) this.chats[user] = { messages: [] };
2571
3184
  return this.chats[user];
2572
3185
  }
2573
- fetchUsers() {
2574
- return this.roomUsers;
2575
- }
2576
3186
  //#region Internal events
2577
3187
  onClose(el) {
2578
3188
  this._log("Closed!:", el);
@@ -2656,22 +3266,11 @@ var SmuleChat = class {
2656
3266
  this.parsePresence(el);
2657
3267
  } else {
2658
3268
  if (el.is("iq")) {
2659
- let child = el.getChild("fin");
2660
- if (child) {
2661
- if (child.getAttr("complete") == "false") {
2662
- this.iqHasMore = true;
2663
- child = child.getChild("set");
2664
- if (child) {
2665
- child = child.getChild("last");
2666
- if (child) {
2667
- this.lastIqId = child.getText();
2668
- }
2669
- }
2670
- } else {
2671
- this.iqHasMore = false;
2672
- }
3269
+ const id = el.getAttr("id");
3270
+ if (id) {
3271
+ this.iqs[id](el);
3272
+ delete this.iqs[id];
2673
3273
  }
2674
- this.ongoingIq = false;
2675
3274
  }
2676
3275
  this._log("Stanza!", el.toString());
2677
3276
  }
@@ -2679,13 +3278,13 @@ var SmuleChat = class {
2679
3278
  //#endregion Internal events
2680
3279
  //#region Logging
2681
3280
  _log(...args) {
2682
- console.log(this.isLive ? "[SmuleLiveChat]" : "[SmuleChat]", ...args);
3281
+ console.log("[SmuleChat]", ...args);
2683
3282
  }
2684
3283
  _warn(...args) {
2685
- console.warn(this.isLive ? "[SmuleLiveChat]" : "[SmuleChat]", ...args);
3284
+ console.warn("[SmuleChat]", ...args);
2686
3285
  }
2687
3286
  _error(...args) {
2688
- console.error(this.isLive ? "[SmuleLiveChat]" : "[SmuleChat]", ...args);
3287
+ console.error("[SmuleChat]", ...args);
2689
3288
  }
2690
3289
  //#endregion Logging
2691
3290
  };
@@ -2694,7 +3293,7 @@ var SmuleChat = class {
2694
3293
  var import_fs = require("fs");
2695
3294
  var crypto = __toESM(require("crypto"), 1);
2696
3295
  var import_jid3 = require("@xmpp/jid");
2697
- var APP_VERSION = "12.0.9";
3296
+ var APP_VERSION = "12.6.9";
2698
3297
  var SmuleDigest;
2699
3298
  ((SmuleDigest2) => {
2700
3299
  const SALT = `c2250918de500e32c37842f2d25d4d8210992a0ae96a7f36c4c9703cc675d02b92968bc4fa7feada`;
@@ -3238,13 +3837,37 @@ var Smule = class {
3238
3837
  * Creates a new spark chat
3239
3838
  * @param address The JID address of the chat partner
3240
3839
  * @param type Whether the JID address is an individual or a group
3241
- * @returns idk
3242
3840
  */
3243
3841
  create: async (address, type = "ACCT") => {
3244
3842
  const req = await this.internal._createRequest(SmuleUrls.SparkChatUpdate, { add: [{ name: address, type }], remove: [] });
3843
+ this.internal._handleNon200(req);
3844
+ },
3845
+ /**
3846
+ * Deletes an existing spark chat
3847
+ * @param address The JID address of the chat partner
3848
+ * @param type Whether the JID address is an individual or a group
3849
+ */
3850
+ delete: async (address, type = "ACCT") => {
3851
+ const req = await this.internal._createRequest(SmuleUrls.SparkChatUpdate, { remove: [{ name: address, type }], add: [] });
3852
+ this.internal._handleNon200(req);
3853
+ },
3854
+ /**
3855
+ * Fetches your existing chats
3856
+ * @param type Whether an individual or a group
3857
+ * @returns Your inbox and your message requests
3858
+ */
3859
+ fetchInboxes: async (type = "ACCT") => {
3860
+ const req = await this.internal._createRequest(SmuleUrls.SparkChatList, { type, limit: 200 });
3245
3861
  if (!this.internal._handleNon200(req)) return;
3246
3862
  return this.internal._getResponseData(req);
3247
3863
  },
3864
+ /**
3865
+ * Marks you as offline to your chats
3866
+ */
3867
+ markOffline: async () => {
3868
+ const req = await this.internal._createRequest(SmuleUrls.SparkChatOffline, {});
3869
+ this.internal._handleNon200(req);
3870
+ },
3248
3871
  /**
3249
3872
  * Creates a connection to the XMPP chat server
3250
3873
  */
@@ -4415,9 +5038,9 @@ var Smule = class {
4415
5038
  * @param to The user to send the message to
4416
5039
  * @param message The message body
4417
5040
  */
4418
- sendTextMessage: async (to, message) => {
5041
+ sendTextMessage: async (message) => {
4419
5042
  if (!this.liveChatSession) return;
4420
- await this.liveChatSession.sendTextMessage(to, message);
5043
+ await this.liveChatSession.sendTextMessage(message);
4421
5044
  },
4422
5045
  /**
4423
5046
  * Fetch all loaded chats
@@ -4430,27 +5053,47 @@ var Smule = class {
4430
5053
  fetchUsers: () => {
4431
5054
  if (!this.liveChatSession) return;
4432
5055
  return this.liveChatSession.fetchUsers();
4433
- },
4434
- /**
4435
- * Loads the entire message history
4436
- * @param limit How many messages
4437
- * @param before Messages before this
4438
- * @param after Messages after this
4439
- * @param user The chat partner
4440
- *
4441
- * @remarks This currently recurses until it loads ALL archived messages.
4442
- * This means that it will take a long time to load all messages.
4443
- * @remarks Filtering by a specific user may not work yet
4444
- */
4445
- loadMessageHistory: async (limit = 50, before = null, after = null, user) => {
4446
- if (!this.liveChatSession) return;
4447
- await this.liveChatSession.loadMessageHistory(limit, before, after, user);
4448
5056
  }
4449
5057
  },
5058
+ /**
5059
+ * Fetches ("syncs") a livestream (campfire) so you can connect to it
5060
+ *
5061
+ * @param campfireId The campfire's id
5062
+ * @returns Data regarding the campfire and the streaming details
5063
+ */
4450
5064
  fetch: async (campfireId) => {
4451
5065
  const req = await this.internal._createRequest(SmuleUrls.CfireSync, { campfireId });
4452
5066
  if (!this.internal._handleNon200(req)) return;
4453
5067
  return this.internal._getResponseData(req);
5068
+ },
5069
+ /**
5070
+ * Fetches gifts that have been sent to a live
5071
+ *
5072
+ * @param campfireId The campfire's id
5073
+ * @param cursor The starting point
5074
+ * @param limit How many results
5075
+ * @returns A list of gifts data
5076
+ */
5077
+ fetchRecentGifts: async (campfireId, cursor = "start", limit = 10) => {
5078
+ const req = await this.internal._createRequest(SmuleUrls.GiftRecentTransactions, { campfireId, cursor, limit, animationVersion: "V2", extraGiftTypes: ["SYSTEM"], previewVersion: "PNG", type: "CFIRE" });
5079
+ if (!this.internal._handleNon200(req)) return;
5080
+ return this.internal._getResponseData(req);
5081
+ },
5082
+ /**
5083
+ * Sign up as available to sing
5084
+ * @param campfireId The livestream's id
5085
+ */
5086
+ joinToSing: async (campfireId) => {
5087
+ const req = await this.internal._createRequest(SmuleUrls.CfireSignupAdd, { campfireId, message: "I'm available to sing" });
5088
+ this.internal._handleNon200(req);
5089
+ },
5090
+ /**
5091
+ * Revoke your availability to sing
5092
+ * @param campfireId The livestream's id
5093
+ */
5094
+ revokeJoinToSing: async (campfireId) => {
5095
+ const req = await this.internal._createRequest(SmuleUrls.CfireSignupRemove, { campfireId });
5096
+ this.internal._handleNon200(req);
4454
5097
  }
4455
5098
  };
4456
5099
  groups = {