wuzapi 1.6.9 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -977,6 +977,38 @@ switch (messageType) {
977
977
  const pollMsg = webhookPayload.event.Message.pollCreationMessageV3;
978
978
  console.log("Poll:", pollMsg.name, `${pollMsg.options.length} options`);
979
979
  break;
980
+
981
+ case MessageType.BUTTONS_RESPONSE:
982
+ const buttonResponse = webhookPayload.event.Message.buttonsResponseMessage;
983
+ console.log("Button clicked:", buttonResponse.selectedButtonId);
984
+ break;
985
+
986
+ case MessageType.LIST_RESPONSE:
987
+ const listResponse = webhookPayload.event.Message.listResponseMessage;
988
+ console.log(
989
+ "List item selected:",
990
+ listResponse.singleSelectReply.selectedRowId
991
+ );
992
+ break;
993
+
994
+ case MessageType.GROUP_INVITE:
995
+ const groupInvite = webhookPayload.event.Message.groupInviteMessage;
996
+ console.log("Group invite:", groupInvite.groupName);
997
+ break;
998
+
999
+ case MessageType.VIEW_ONCE:
1000
+ const viewOnceMsg = webhookPayload.event.Message.viewOnceMessage;
1001
+ console.log("View once message received");
1002
+ break;
1003
+
1004
+ // Handle other new message types
1005
+ case MessageType.BUTTONS:
1006
+ case MessageType.LIST:
1007
+ case MessageType.TEMPLATE:
1008
+ case MessageType.POLL:
1009
+ case MessageType.POLL_UPDATE:
1010
+ console.log(`Interactive message type: ${messageType}`);
1011
+ break;
980
1012
  }
981
1013
 
982
1014
  // Handle media intelligently
@@ -991,20 +1023,47 @@ if (hasS3Media(webhookPayload)) {
991
1023
 
992
1024
  ```typescript
993
1025
  enum MessageType {
1026
+ // Basic messages
994
1027
  TEXT = "conversation", // Simple text messages
995
1028
  EXTENDED_TEXT = "extendedTextMessage", // Rich text messages
1029
+
1030
+ // Media messages
996
1031
  IMAGE = "imageMessage", // Photos, screenshots
997
1032
  VIDEO = "videoMessage", // Video files, GIFs
998
1033
  AUDIO = "audioMessage", // Audio files, voice messages
999
1034
  DOCUMENT = "documentMessage", // PDFs, Word docs, etc.
1035
+ STICKER = "stickerMessage", // Stickers (animated/static)
1036
+
1037
+ // Contact & location
1000
1038
  CONTACT = "contactMessage", // Shared contacts
1001
1039
  LOCATION = "locationMessage", // Location pins
1002
- STICKER = "stickerMessage", // Stickers (animated/static)
1040
+
1041
+ // Interactive messages
1042
+ BUTTONS = "buttonsMessage", // Interactive buttons
1043
+ LIST = "listMessage", // List menus
1044
+ TEMPLATE = "templateMessage", // Template messages
1045
+
1046
+ // Response messages
1047
+ BUTTONS_RESPONSE = "buttonsResponseMessage", // Button click responses
1048
+ LIST_RESPONSE = "listResponseMessage", // List selection responses
1049
+
1050
+ // Group messages
1051
+ GROUP_INVITE = "groupInviteMessage", // Group invitations
1052
+
1053
+ // Poll messages
1054
+ POLL = "pollCreationMessage", // Polls (standard)
1055
+ POLL_CREATION = "pollCreationMessageV3", // Polls (v3)
1056
+ POLL_UPDATE = "pollUpdateMessage", // Poll vote updates
1057
+
1058
+ // Special messages
1059
+ VIEW_ONCE = "viewOnceMessage", // View once messages
1003
1060
  REACTION = "reactionMessage", // Message reactions (emoji)
1004
- POLL_CREATION = "pollCreationMessageV3", // Polls (groups only)
1005
1061
  EDITED = "editedMessage", // Edited messages
1062
+
1063
+ // System messages
1006
1064
  PROTOCOL = "protocolMessage", // System messages
1007
1065
  DEVICE_SENT = "deviceSentMessage", // Multi-device messages
1066
+
1008
1067
  UNKNOWN = "unknown", // Unrecognized types
1009
1068
  }
1010
1069
  ```
package/dist/client.d.ts CHANGED
@@ -8,12 +8,13 @@ export declare class WuzapiError extends Error {
8
8
  export declare class BaseClient {
9
9
  protected axios: AxiosInstance;
10
10
  protected config: WuzapiConfig;
11
+ protected defaultHeaders: Record<string, string>;
11
12
  constructor(config: WuzapiConfig);
12
13
  /**
13
14
  * Resolve the token from request options or instance config
14
15
  * Throws an error if no token is available
15
16
  */
16
- private resolveToken;
17
+ private buildHeaders;
17
18
  protected request<T>(method: "GET" | "POST" | "DELETE" | "PUT", endpoint: string, data?: unknown, options?: RequestOptions): Promise<T>;
18
19
  protected get<T>(endpoint: string, options?: RequestOptions): Promise<T>;
19
20
  protected post<T>(endpoint: string, data?: unknown, options?: RequestOptions): Promise<T>;
package/dist/client.js CHANGED
@@ -1,6 +1,485 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const axios = require("axios");
4
+ function getDefaultExportFromCjs(x) {
5
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
6
+ }
7
+ var browser = { exports: {} };
8
+ var ms;
9
+ var hasRequiredMs;
10
+ function requireMs() {
11
+ if (hasRequiredMs) return ms;
12
+ hasRequiredMs = 1;
13
+ var s = 1e3;
14
+ var m = s * 60;
15
+ var h = m * 60;
16
+ var d = h * 24;
17
+ var w = d * 7;
18
+ var y = d * 365.25;
19
+ ms = function(val, options) {
20
+ options = options || {};
21
+ var type = typeof val;
22
+ if (type === "string" && val.length > 0) {
23
+ return parse(val);
24
+ } else if (type === "number" && isFinite(val)) {
25
+ return options.long ? fmtLong(val) : fmtShort(val);
26
+ }
27
+ throw new Error(
28
+ "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
29
+ );
30
+ };
31
+ function parse(str) {
32
+ str = String(str);
33
+ if (str.length > 100) {
34
+ return;
35
+ }
36
+ var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
37
+ str
38
+ );
39
+ if (!match) {
40
+ return;
41
+ }
42
+ var n = parseFloat(match[1]);
43
+ var type = (match[2] || "ms").toLowerCase();
44
+ switch (type) {
45
+ case "years":
46
+ case "year":
47
+ case "yrs":
48
+ case "yr":
49
+ case "y":
50
+ return n * y;
51
+ case "weeks":
52
+ case "week":
53
+ case "w":
54
+ return n * w;
55
+ case "days":
56
+ case "day":
57
+ case "d":
58
+ return n * d;
59
+ case "hours":
60
+ case "hour":
61
+ case "hrs":
62
+ case "hr":
63
+ case "h":
64
+ return n * h;
65
+ case "minutes":
66
+ case "minute":
67
+ case "mins":
68
+ case "min":
69
+ case "m":
70
+ return n * m;
71
+ case "seconds":
72
+ case "second":
73
+ case "secs":
74
+ case "sec":
75
+ case "s":
76
+ return n * s;
77
+ case "milliseconds":
78
+ case "millisecond":
79
+ case "msecs":
80
+ case "msec":
81
+ case "ms":
82
+ return n;
83
+ default:
84
+ return void 0;
85
+ }
86
+ }
87
+ function fmtShort(ms2) {
88
+ var msAbs = Math.abs(ms2);
89
+ if (msAbs >= d) {
90
+ return Math.round(ms2 / d) + "d";
91
+ }
92
+ if (msAbs >= h) {
93
+ return Math.round(ms2 / h) + "h";
94
+ }
95
+ if (msAbs >= m) {
96
+ return Math.round(ms2 / m) + "m";
97
+ }
98
+ if (msAbs >= s) {
99
+ return Math.round(ms2 / s) + "s";
100
+ }
101
+ return ms2 + "ms";
102
+ }
103
+ function fmtLong(ms2) {
104
+ var msAbs = Math.abs(ms2);
105
+ if (msAbs >= d) {
106
+ return plural(ms2, msAbs, d, "day");
107
+ }
108
+ if (msAbs >= h) {
109
+ return plural(ms2, msAbs, h, "hour");
110
+ }
111
+ if (msAbs >= m) {
112
+ return plural(ms2, msAbs, m, "minute");
113
+ }
114
+ if (msAbs >= s) {
115
+ return plural(ms2, msAbs, s, "second");
116
+ }
117
+ return ms2 + " ms";
118
+ }
119
+ function plural(ms2, msAbs, n, name) {
120
+ var isPlural = msAbs >= n * 1.5;
121
+ return Math.round(ms2 / n) + " " + name + (isPlural ? "s" : "");
122
+ }
123
+ return ms;
124
+ }
125
+ var common;
126
+ var hasRequiredCommon;
127
+ function requireCommon() {
128
+ if (hasRequiredCommon) return common;
129
+ hasRequiredCommon = 1;
130
+ function setup(env) {
131
+ createDebug.debug = createDebug;
132
+ createDebug.default = createDebug;
133
+ createDebug.coerce = coerce;
134
+ createDebug.disable = disable;
135
+ createDebug.enable = enable;
136
+ createDebug.enabled = enabled;
137
+ createDebug.humanize = requireMs();
138
+ createDebug.destroy = destroy;
139
+ Object.keys(env).forEach((key) => {
140
+ createDebug[key] = env[key];
141
+ });
142
+ createDebug.names = [];
143
+ createDebug.skips = [];
144
+ createDebug.formatters = {};
145
+ function selectColor(namespace) {
146
+ let hash = 0;
147
+ for (let i = 0; i < namespace.length; i++) {
148
+ hash = (hash << 5) - hash + namespace.charCodeAt(i);
149
+ hash |= 0;
150
+ }
151
+ return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
152
+ }
153
+ createDebug.selectColor = selectColor;
154
+ function createDebug(namespace) {
155
+ let prevTime;
156
+ let enableOverride = null;
157
+ let namespacesCache;
158
+ let enabledCache;
159
+ function debug2(...args) {
160
+ if (!debug2.enabled) {
161
+ return;
162
+ }
163
+ const self = debug2;
164
+ const curr = Number(/* @__PURE__ */ new Date());
165
+ const ms2 = curr - (prevTime || curr);
166
+ self.diff = ms2;
167
+ self.prev = prevTime;
168
+ self.curr = curr;
169
+ prevTime = curr;
170
+ args[0] = createDebug.coerce(args[0]);
171
+ if (typeof args[0] !== "string") {
172
+ args.unshift("%O");
173
+ }
174
+ let index = 0;
175
+ args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
176
+ if (match === "%%") {
177
+ return "%";
178
+ }
179
+ index++;
180
+ const formatter = createDebug.formatters[format];
181
+ if (typeof formatter === "function") {
182
+ const val = args[index];
183
+ match = formatter.call(self, val);
184
+ args.splice(index, 1);
185
+ index--;
186
+ }
187
+ return match;
188
+ });
189
+ createDebug.formatArgs.call(self, args);
190
+ const logFn = self.log || createDebug.log;
191
+ logFn.apply(self, args);
192
+ }
193
+ debug2.namespace = namespace;
194
+ debug2.useColors = createDebug.useColors();
195
+ debug2.color = createDebug.selectColor(namespace);
196
+ debug2.extend = extend;
197
+ debug2.destroy = createDebug.destroy;
198
+ Object.defineProperty(debug2, "enabled", {
199
+ enumerable: true,
200
+ configurable: false,
201
+ get: () => {
202
+ if (enableOverride !== null) {
203
+ return enableOverride;
204
+ }
205
+ if (namespacesCache !== createDebug.namespaces) {
206
+ namespacesCache = createDebug.namespaces;
207
+ enabledCache = createDebug.enabled(namespace);
208
+ }
209
+ return enabledCache;
210
+ },
211
+ set: (v) => {
212
+ enableOverride = v;
213
+ }
214
+ });
215
+ if (typeof createDebug.init === "function") {
216
+ createDebug.init(debug2);
217
+ }
218
+ return debug2;
219
+ }
220
+ function extend(namespace, delimiter) {
221
+ const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace);
222
+ newDebug.log = this.log;
223
+ return newDebug;
224
+ }
225
+ function enable(namespaces) {
226
+ createDebug.save(namespaces);
227
+ createDebug.namespaces = namespaces;
228
+ createDebug.names = [];
229
+ createDebug.skips = [];
230
+ const split = (typeof namespaces === "string" ? namespaces : "").trim().replace(/\s+/g, ",").split(",").filter(Boolean);
231
+ for (const ns of split) {
232
+ if (ns[0] === "-") {
233
+ createDebug.skips.push(ns.slice(1));
234
+ } else {
235
+ createDebug.names.push(ns);
236
+ }
237
+ }
238
+ }
239
+ function matchesTemplate(search, template) {
240
+ let searchIndex = 0;
241
+ let templateIndex = 0;
242
+ let starIndex = -1;
243
+ let matchIndex = 0;
244
+ while (searchIndex < search.length) {
245
+ if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) {
246
+ if (template[templateIndex] === "*") {
247
+ starIndex = templateIndex;
248
+ matchIndex = searchIndex;
249
+ templateIndex++;
250
+ } else {
251
+ searchIndex++;
252
+ templateIndex++;
253
+ }
254
+ } else if (starIndex !== -1) {
255
+ templateIndex = starIndex + 1;
256
+ matchIndex++;
257
+ searchIndex = matchIndex;
258
+ } else {
259
+ return false;
260
+ }
261
+ }
262
+ while (templateIndex < template.length && template[templateIndex] === "*") {
263
+ templateIndex++;
264
+ }
265
+ return templateIndex === template.length;
266
+ }
267
+ function disable() {
268
+ const namespaces = [
269
+ ...createDebug.names,
270
+ ...createDebug.skips.map((namespace) => "-" + namespace)
271
+ ].join(",");
272
+ createDebug.enable("");
273
+ return namespaces;
274
+ }
275
+ function enabled(name) {
276
+ for (const skip of createDebug.skips) {
277
+ if (matchesTemplate(name, skip)) {
278
+ return false;
279
+ }
280
+ }
281
+ for (const ns of createDebug.names) {
282
+ if (matchesTemplate(name, ns)) {
283
+ return true;
284
+ }
285
+ }
286
+ return false;
287
+ }
288
+ function coerce(val) {
289
+ if (val instanceof Error) {
290
+ return val.stack || val.message;
291
+ }
292
+ return val;
293
+ }
294
+ function destroy() {
295
+ console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
296
+ }
297
+ createDebug.enable(createDebug.load());
298
+ return createDebug;
299
+ }
300
+ common = setup;
301
+ return common;
302
+ }
303
+ var hasRequiredBrowser;
304
+ function requireBrowser() {
305
+ if (hasRequiredBrowser) return browser.exports;
306
+ hasRequiredBrowser = 1;
307
+ (function(module2, exports2) {
308
+ exports2.formatArgs = formatArgs;
309
+ exports2.save = save;
310
+ exports2.load = load;
311
+ exports2.useColors = useColors;
312
+ exports2.storage = localstorage();
313
+ exports2.destroy = /* @__PURE__ */ (() => {
314
+ let warned = false;
315
+ return () => {
316
+ if (!warned) {
317
+ warned = true;
318
+ console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
319
+ }
320
+ };
321
+ })();
322
+ exports2.colors = [
323
+ "#0000CC",
324
+ "#0000FF",
325
+ "#0033CC",
326
+ "#0033FF",
327
+ "#0066CC",
328
+ "#0066FF",
329
+ "#0099CC",
330
+ "#0099FF",
331
+ "#00CC00",
332
+ "#00CC33",
333
+ "#00CC66",
334
+ "#00CC99",
335
+ "#00CCCC",
336
+ "#00CCFF",
337
+ "#3300CC",
338
+ "#3300FF",
339
+ "#3333CC",
340
+ "#3333FF",
341
+ "#3366CC",
342
+ "#3366FF",
343
+ "#3399CC",
344
+ "#3399FF",
345
+ "#33CC00",
346
+ "#33CC33",
347
+ "#33CC66",
348
+ "#33CC99",
349
+ "#33CCCC",
350
+ "#33CCFF",
351
+ "#6600CC",
352
+ "#6600FF",
353
+ "#6633CC",
354
+ "#6633FF",
355
+ "#66CC00",
356
+ "#66CC33",
357
+ "#9900CC",
358
+ "#9900FF",
359
+ "#9933CC",
360
+ "#9933FF",
361
+ "#99CC00",
362
+ "#99CC33",
363
+ "#CC0000",
364
+ "#CC0033",
365
+ "#CC0066",
366
+ "#CC0099",
367
+ "#CC00CC",
368
+ "#CC00FF",
369
+ "#CC3300",
370
+ "#CC3333",
371
+ "#CC3366",
372
+ "#CC3399",
373
+ "#CC33CC",
374
+ "#CC33FF",
375
+ "#CC6600",
376
+ "#CC6633",
377
+ "#CC9900",
378
+ "#CC9933",
379
+ "#CCCC00",
380
+ "#CCCC33",
381
+ "#FF0000",
382
+ "#FF0033",
383
+ "#FF0066",
384
+ "#FF0099",
385
+ "#FF00CC",
386
+ "#FF00FF",
387
+ "#FF3300",
388
+ "#FF3333",
389
+ "#FF3366",
390
+ "#FF3399",
391
+ "#FF33CC",
392
+ "#FF33FF",
393
+ "#FF6600",
394
+ "#FF6633",
395
+ "#FF9900",
396
+ "#FF9933",
397
+ "#FFCC00",
398
+ "#FFCC33"
399
+ ];
400
+ function useColors() {
401
+ if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) {
402
+ return true;
403
+ }
404
+ if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
405
+ return false;
406
+ }
407
+ let m;
408
+ return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
409
+ typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
410
+ // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
411
+ typeof navigator !== "undefined" && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
412
+ typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
413
+ }
414
+ function formatArgs(args) {
415
+ args[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args[0] + (this.useColors ? "%c " : " ") + "+" + module2.exports.humanize(this.diff);
416
+ if (!this.useColors) {
417
+ return;
418
+ }
419
+ const c = "color: " + this.color;
420
+ args.splice(1, 0, c, "color: inherit");
421
+ let index = 0;
422
+ let lastC = 0;
423
+ args[0].replace(/%[a-zA-Z%]/g, (match) => {
424
+ if (match === "%%") {
425
+ return;
426
+ }
427
+ index++;
428
+ if (match === "%c") {
429
+ lastC = index;
430
+ }
431
+ });
432
+ args.splice(lastC, 0, c);
433
+ }
434
+ exports2.log = console.debug || console.log || (() => {
435
+ });
436
+ function save(namespaces) {
437
+ try {
438
+ if (namespaces) {
439
+ exports2.storage.setItem("debug", namespaces);
440
+ } else {
441
+ exports2.storage.removeItem("debug");
442
+ }
443
+ } catch (error) {
444
+ }
445
+ }
446
+ function load() {
447
+ let r;
448
+ try {
449
+ r = exports2.storage.getItem("debug") || exports2.storage.getItem("DEBUG");
450
+ } catch (error) {
451
+ }
452
+ if (!r && typeof process !== "undefined" && "env" in process) {
453
+ r = process.env.DEBUG;
454
+ }
455
+ return r;
456
+ }
457
+ function localstorage() {
458
+ try {
459
+ return localStorage;
460
+ } catch (error) {
461
+ }
462
+ }
463
+ module2.exports = requireCommon()(exports2);
464
+ const { formatters } = module2.exports;
465
+ formatters.j = function(v) {
466
+ try {
467
+ return JSON.stringify(v);
468
+ } catch (error) {
469
+ return "[UnexpectedJSONParseError]: " + error.message;
470
+ }
471
+ };
472
+ })(browser, browser.exports);
473
+ return browser.exports;
474
+ }
475
+ var browserExports = requireBrowser();
476
+ const debug = /* @__PURE__ */ getDefaultExportFromCjs(browserExports);
477
+ const logger = {
478
+ request: debug("wuzapi:request"),
479
+ response: debug("wuzapi:response"),
480
+ error: debug("wuzapi:error"),
481
+ info: debug("wuzapi:info")
482
+ };
4
483
  class WuzapiError extends Error {
5
484
  code;
6
485
  details;
@@ -14,6 +493,9 @@ class WuzapiError extends Error {
14
493
  class BaseClient {
15
494
  axios;
16
495
  config;
496
+ defaultHeaders = {
497
+ "Content-Type": "application/json"
498
+ };
17
499
  constructor(config) {
18
500
  this.config = config;
19
501
  this.axios = axios.create({
@@ -44,7 +526,7 @@ class BaseClient {
44
526
  * Resolve the token from request options or instance config
45
527
  * Throws an error if no token is available
46
528
  */
47
- resolveToken(options) {
529
+ buildHeaders(options) {
48
530
  const token = options?.token || this.config.token;
49
531
  if (!token) {
50
532
  throw new WuzapiError(
@@ -52,24 +534,33 @@ class BaseClient {
52
534
  "No authentication token provided. Either set a token in the client config or provide one in the request options."
53
535
  );
54
536
  }
55
- return token;
537
+ if (options?.token) {
538
+ return {
539
+ ...this.defaultHeaders,
540
+ Token: options.token
541
+ };
542
+ }
543
+ return {
544
+ ...this.defaultHeaders,
545
+ Authorization: token
546
+ };
56
547
  }
57
548
  async request(method, endpoint, data, options) {
58
- const token = this.resolveToken(options);
549
+ const headers = this.buildHeaders(options);
59
550
  if (this.config.debug) {
60
- console.log(`[${method}] ${endpoint}`, token, data);
551
+ logger.request(`[${method}] ${endpoint}`, { headers, data });
61
552
  }
62
553
  const response = await this.axios.request({
63
554
  method,
64
555
  url: endpoint,
65
556
  data,
66
- headers: {
67
- "Content-Type": "application/json",
68
- Authorization: token
69
- }
557
+ headers
70
558
  });
71
559
  if (this.config.debug) {
72
- console.log(`[${method}] ${endpoint}`, response.status, response.data);
560
+ logger.response(`[${method}] ${endpoint}`, {
561
+ status: response.status,
562
+ data: response.data
563
+ });
73
564
  }
74
565
  if (!response.data.success) {
75
566
  throw new WuzapiError(
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sources":["../src/client.ts"],"sourcesContent":["import axios, { AxiosInstance, AxiosResponse } from \"axios\";\nimport {\n WuzapiConfig,\n WuzapiResponse,\n RequestOptions,\n} from \"./types/common.js\";\n\nexport class WuzapiError extends Error {\n public code: number;\n public details?: unknown;\n\n constructor(code: number, message: string, details?: unknown) {\n super(message);\n this.name = \"WuzapiError\";\n this.code = code;\n this.details = details;\n }\n}\n\nexport class BaseClient {\n protected axios: AxiosInstance;\n protected config: WuzapiConfig;\n\n constructor(config: WuzapiConfig) {\n this.config = config;\n this.axios = axios.create({\n baseURL: config.apiUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n // Add response interceptor for error handling\n this.axios.interceptors.response.use(\n (response: AxiosResponse) => response,\n (error) => {\n if (error.response) {\n // Server responded with error status\n const data = error.response.data;\n throw new WuzapiError(\n data.code || error.response.status,\n data.message || error.message,\n data\n );\n } else if (error.request) {\n // Request was made but no response received\n throw new WuzapiError(0, \"Network error: No response from server\");\n } else {\n // Something else happened\n throw new WuzapiError(0, error.message);\n }\n }\n );\n }\n\n /**\n * Resolve the token from request options or instance config\n * Throws an error if no token is available\n */\n private resolveToken(options?: RequestOptions): string {\n const token = options?.token || this.config.token;\n if (!token) {\n throw new WuzapiError(\n 401,\n \"No authentication token provided. Either set a token in the client config or provide one in the request options.\"\n );\n }\n return token;\n }\n\n protected async request<T>(\n method: \"GET\" | \"POST\" | \"DELETE\" | \"PUT\",\n endpoint: string,\n data?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n const token = this.resolveToken(options);\n if (this.config.debug) {\n // eslint-disable-next-line no-undef\n console.log(`[${method}] ${endpoint}`, token, data);\n }\n\n const response = await this.axios.request<WuzapiResponse<T>>({\n method,\n url: endpoint,\n data,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: token,\n },\n });\n\n if (this.config.debug) {\n // eslint-disable-next-line no-undef\n console.log(`[${method}] ${endpoint}`, response.status, response.data);\n }\n\n if (!response.data.success) {\n throw new WuzapiError(\n response.data.code,\n \"API request failed\",\n response.data\n );\n }\n\n if (response.data.code <= 200 && response.data.code >= 300) {\n throw new WuzapiError(\n response.data.code,\n response.data.error || \"API request failed\",\n response.data\n );\n }\n\n return response.data.data;\n }\n\n protected async get<T>(\n endpoint: string,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>(\"GET\", endpoint, undefined, options);\n }\n\n protected async post<T>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>(\"POST\", endpoint, data, options);\n }\n\n protected async put<T>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>(\"PUT\", endpoint, data, options);\n }\n\n protected async delete<T>(\n endpoint: string,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>(\"DELETE\", endpoint, undefined, options);\n }\n}\n"],"names":[],"mappings":";;;AAOO,MAAM,oBAAoB,MAAM;AAAA,EAC9B;AAAA,EACA;AAAA,EAEP,YAAY,MAAc,SAAiB,SAAmB;AAC5D,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AACF;AAEO,MAAM,WAAW;AAAA,EACZ;AAAA,EACA;AAAA,EAEV,YAAY,QAAsB;AAChC,SAAK,SAAS;AACd,SAAK,QAAQ,MAAM,OAAO;AAAA,MACxB,SAAS,OAAO;AAAA,MAChB,SAAS;AAAA,QACP,gBAAgB;AAAA,MAAA;AAAA,IAClB,CACD;AAGD,SAAK,MAAM,aAAa,SAAS;AAAA,MAC/B,CAAC,aAA4B;AAAA,MAC7B,CAAC,UAAU;AACT,YAAI,MAAM,UAAU;AAElB,gBAAM,OAAO,MAAM,SAAS;AAC5B,gBAAM,IAAI;AAAA,YACR,KAAK,QAAQ,MAAM,SAAS;AAAA,YAC5B,KAAK,WAAW,MAAM;AAAA,YACtB;AAAA,UAAA;AAAA,QAEJ,WAAW,MAAM,SAAS;AAExB,gBAAM,IAAI,YAAY,GAAG,wCAAwC;AAAA,QACnE,OAAO;AAEL,gBAAM,IAAI,YAAY,GAAG,MAAM,OAAO;AAAA,QACxC;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,aAAa,SAAkC;AACrD,UAAM,QAAQ,SAAS,SAAS,KAAK,OAAO;AAC5C,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAgB,QACd,QACA,UACA,MACA,SACY;AACZ,UAAM,QAAQ,KAAK,aAAa,OAAO;AACvC,QAAI,KAAK,OAAO,OAAO;AAErB,cAAQ,IAAI,IAAI,MAAM,KAAK,QAAQ,IAAI,OAAO,IAAI;AAAA,IACpD;AAEA,UAAM,WAAW,MAAM,KAAK,MAAM,QAA2B;AAAA,MAC3D;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe;AAAA,MAAA;AAAA,IACjB,CACD;AAED,QAAI,KAAK,OAAO,OAAO;AAErB,cAAQ,IAAI,IAAI,MAAM,KAAK,QAAQ,IAAI,SAAS,QAAQ,SAAS,IAAI;AAAA,IACvE;AAEA,QAAI,CAAC,SAAS,KAAK,SAAS;AAC1B,YAAM,IAAI;AAAA,QACR,SAAS,KAAK;AAAA,QACd;AAAA,QACA,SAAS;AAAA,MAAA;AAAA,IAEb;AAEA,QAAI,SAAS,KAAK,QAAQ,OAAO,SAAS,KAAK,QAAQ,KAAK;AAC1D,YAAM,IAAI;AAAA,QACR,SAAS,KAAK;AAAA,QACd,SAAS,KAAK,SAAS;AAAA,QACvB,SAAS;AAAA,MAAA;AAAA,IAEb;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA,EAEA,MAAgB,IACd,UACA,SACY;AACZ,WAAO,KAAK,QAAW,OAAO,UAAU,QAAW,OAAO;AAAA,EAC5D;AAAA,EAEA,MAAgB,KACd,UACA,MACA,SACY;AACZ,WAAO,KAAK,QAAW,QAAQ,UAAU,MAAM,OAAO;AAAA,EACxD;AAAA,EAEA,MAAgB,IACd,UACA,MACA,SACY;AACZ,WAAO,KAAK,QAAW,OAAO,UAAU,MAAM,OAAO;AAAA,EACvD;AAAA,EAEA,MAAgB,OACd,UACA,SACY;AACZ,WAAO,KAAK,QAAW,UAAU,UAAU,QAAW,OAAO;AAAA,EAC/D;AACF;;;"}
1
+ {"version":3,"file":"client.js","sources":["../node_modules/ms/index.js","../node_modules/debug/src/common.js","../node_modules/debug/src/browser.js","../src/utils/logger.ts","../src/client.ts"],"sourcesContent":["/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar w = d * 7;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} [options]\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function (val, options) {\n options = options || {};\n var type = typeof val;\n if (type === 'string' && val.length > 0) {\n return parse(val);\n } else if (type === 'number' && isFinite(val)) {\n return options.long ? fmtLong(val) : fmtShort(val);\n }\n throw new Error(\n 'val is not a non-empty string or a valid number. val=' +\n JSON.stringify(val)\n );\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n str = String(str);\n if (str.length > 100) {\n return;\n }\n var match = /^(-?(?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(\n str\n );\n if (!match) {\n return;\n }\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n case 'weeks':\n case 'week':\n case 'w':\n return n * w;\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n default:\n return undefined;\n }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtShort(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return Math.round(ms / d) + 'd';\n }\n if (msAbs >= h) {\n return Math.round(ms / h) + 'h';\n }\n if (msAbs >= m) {\n return Math.round(ms / m) + 'm';\n }\n if (msAbs >= s) {\n return Math.round(ms / s) + 's';\n }\n return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtLong(ms) {\n var msAbs = Math.abs(ms);\n if (msAbs >= d) {\n return plural(ms, msAbs, d, 'day');\n }\n if (msAbs >= h) {\n return plural(ms, msAbs, h, 'hour');\n }\n if (msAbs >= m) {\n return plural(ms, msAbs, m, 'minute');\n }\n if (msAbs >= s) {\n return plural(ms, msAbs, s, 'second');\n }\n return ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, msAbs, n, name) {\n var isPlural = msAbs >= n * 1.5;\n return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');\n}\n","\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n */\n\nfunction setup(env) {\n\tcreateDebug.debug = createDebug;\n\tcreateDebug.default = createDebug;\n\tcreateDebug.coerce = coerce;\n\tcreateDebug.disable = disable;\n\tcreateDebug.enable = enable;\n\tcreateDebug.enabled = enabled;\n\tcreateDebug.humanize = require('ms');\n\tcreateDebug.destroy = destroy;\n\n\tObject.keys(env).forEach(key => {\n\t\tcreateDebug[key] = env[key];\n\t});\n\n\t/**\n\t* The currently active debug mode names, and names to skip.\n\t*/\n\n\tcreateDebug.names = [];\n\tcreateDebug.skips = [];\n\n\t/**\n\t* Map of special \"%n\" handling functions, for the debug \"format\" argument.\n\t*\n\t* Valid key names are a single, lower or upper-case letter, i.e. \"n\" and \"N\".\n\t*/\n\tcreateDebug.formatters = {};\n\n\t/**\n\t* Selects a color for a debug namespace\n\t* @param {String} namespace The namespace string for the debug instance to be colored\n\t* @return {Number|String} An ANSI color code for the given namespace\n\t* @api private\n\t*/\n\tfunction selectColor(namespace) {\n\t\tlet hash = 0;\n\n\t\tfor (let i = 0; i < namespace.length; i++) {\n\t\t\thash = ((hash << 5) - hash) + namespace.charCodeAt(i);\n\t\t\thash |= 0; // Convert to 32bit integer\n\t\t}\n\n\t\treturn createDebug.colors[Math.abs(hash) % createDebug.colors.length];\n\t}\n\tcreateDebug.selectColor = selectColor;\n\n\t/**\n\t* Create a debugger with the given `namespace`.\n\t*\n\t* @param {String} namespace\n\t* @return {Function}\n\t* @api public\n\t*/\n\tfunction createDebug(namespace) {\n\t\tlet prevTime;\n\t\tlet enableOverride = null;\n\t\tlet namespacesCache;\n\t\tlet enabledCache;\n\n\t\tfunction debug(...args) {\n\t\t\t// Disabled?\n\t\t\tif (!debug.enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst self = debug;\n\n\t\t\t// Set `diff` timestamp\n\t\t\tconst curr = Number(new Date());\n\t\t\tconst ms = curr - (prevTime || curr);\n\t\t\tself.diff = ms;\n\t\t\tself.prev = prevTime;\n\t\t\tself.curr = curr;\n\t\t\tprevTime = curr;\n\n\t\t\targs[0] = createDebug.coerce(args[0]);\n\n\t\t\tif (typeof args[0] !== 'string') {\n\t\t\t\t// Anything else let's inspect with %O\n\t\t\t\targs.unshift('%O');\n\t\t\t}\n\n\t\t\t// Apply any `formatters` transformations\n\t\t\tlet index = 0;\n\t\t\targs[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {\n\t\t\t\t// If we encounter an escaped % then don't increase the array index\n\t\t\t\tif (match === '%%') {\n\t\t\t\t\treturn '%';\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t\tconst formatter = createDebug.formatters[format];\n\t\t\t\tif (typeof formatter === 'function') {\n\t\t\t\t\tconst val = args[index];\n\t\t\t\t\tmatch = formatter.call(self, val);\n\n\t\t\t\t\t// Now we need to remove `args[index]` since it's inlined in the `format`\n\t\t\t\t\targs.splice(index, 1);\n\t\t\t\t\tindex--;\n\t\t\t\t}\n\t\t\t\treturn match;\n\t\t\t});\n\n\t\t\t// Apply env-specific formatting (colors, etc.)\n\t\t\tcreateDebug.formatArgs.call(self, args);\n\n\t\t\tconst logFn = self.log || createDebug.log;\n\t\t\tlogFn.apply(self, args);\n\t\t}\n\n\t\tdebug.namespace = namespace;\n\t\tdebug.useColors = createDebug.useColors();\n\t\tdebug.color = createDebug.selectColor(namespace);\n\t\tdebug.extend = extend;\n\t\tdebug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.\n\n\t\tObject.defineProperty(debug, 'enabled', {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t\tget: () => {\n\t\t\t\tif (enableOverride !== null) {\n\t\t\t\t\treturn enableOverride;\n\t\t\t\t}\n\t\t\t\tif (namespacesCache !== createDebug.namespaces) {\n\t\t\t\t\tnamespacesCache = createDebug.namespaces;\n\t\t\t\t\tenabledCache = createDebug.enabled(namespace);\n\t\t\t\t}\n\n\t\t\t\treturn enabledCache;\n\t\t\t},\n\t\t\tset: v => {\n\t\t\t\tenableOverride = v;\n\t\t\t}\n\t\t});\n\n\t\t// Env-specific initialization logic for debug instances\n\t\tif (typeof createDebug.init === 'function') {\n\t\t\tcreateDebug.init(debug);\n\t\t}\n\n\t\treturn debug;\n\t}\n\n\tfunction extend(namespace, delimiter) {\n\t\tconst newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);\n\t\tnewDebug.log = this.log;\n\t\treturn newDebug;\n\t}\n\n\t/**\n\t* Enables a debug mode by namespaces. This can include modes\n\t* separated by a colon and wildcards.\n\t*\n\t* @param {String} namespaces\n\t* @api public\n\t*/\n\tfunction enable(namespaces) {\n\t\tcreateDebug.save(namespaces);\n\t\tcreateDebug.namespaces = namespaces;\n\n\t\tcreateDebug.names = [];\n\t\tcreateDebug.skips = [];\n\n\t\tconst split = (typeof namespaces === 'string' ? namespaces : '')\n\t\t\t.trim()\n\t\t\t.replace(/\\s+/g, ',')\n\t\t\t.split(',')\n\t\t\t.filter(Boolean);\n\n\t\tfor (const ns of split) {\n\t\t\tif (ns[0] === '-') {\n\t\t\t\tcreateDebug.skips.push(ns.slice(1));\n\t\t\t} else {\n\t\t\t\tcreateDebug.names.push(ns);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given string matches a namespace template, honoring\n\t * asterisks as wildcards.\n\t *\n\t * @param {String} search\n\t * @param {String} template\n\t * @return {Boolean}\n\t */\n\tfunction matchesTemplate(search, template) {\n\t\tlet searchIndex = 0;\n\t\tlet templateIndex = 0;\n\t\tlet starIndex = -1;\n\t\tlet matchIndex = 0;\n\n\t\twhile (searchIndex < search.length) {\n\t\t\tif (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {\n\t\t\t\t// Match character or proceed with wildcard\n\t\t\t\tif (template[templateIndex] === '*') {\n\t\t\t\t\tstarIndex = templateIndex;\n\t\t\t\t\tmatchIndex = searchIndex;\n\t\t\t\t\ttemplateIndex++; // Skip the '*'\n\t\t\t\t} else {\n\t\t\t\t\tsearchIndex++;\n\t\t\t\t\ttemplateIndex++;\n\t\t\t\t}\n\t\t\t} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition\n\t\t\t\t// Backtrack to the last '*' and try to match more characters\n\t\t\t\ttemplateIndex = starIndex + 1;\n\t\t\t\tmatchIndex++;\n\t\t\t\tsearchIndex = matchIndex;\n\t\t\t} else {\n\t\t\t\treturn false; // No match\n\t\t\t}\n\t\t}\n\n\t\t// Handle trailing '*' in template\n\t\twhile (templateIndex < template.length && template[templateIndex] === '*') {\n\t\t\ttemplateIndex++;\n\t\t}\n\n\t\treturn templateIndex === template.length;\n\t}\n\n\t/**\n\t* Disable debug output.\n\t*\n\t* @return {String} namespaces\n\t* @api public\n\t*/\n\tfunction disable() {\n\t\tconst namespaces = [\n\t\t\t...createDebug.names,\n\t\t\t...createDebug.skips.map(namespace => '-' + namespace)\n\t\t].join(',');\n\t\tcreateDebug.enable('');\n\t\treturn namespaces;\n\t}\n\n\t/**\n\t* Returns true if the given mode name is enabled, false otherwise.\n\t*\n\t* @param {String} name\n\t* @return {Boolean}\n\t* @api public\n\t*/\n\tfunction enabled(name) {\n\t\tfor (const skip of createDebug.skips) {\n\t\t\tif (matchesTemplate(name, skip)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfor (const ns of createDebug.names) {\n\t\t\tif (matchesTemplate(name, ns)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t* Coerce `val`.\n\t*\n\t* @param {Mixed} val\n\t* @return {Mixed}\n\t* @api private\n\t*/\n\tfunction coerce(val) {\n\t\tif (val instanceof Error) {\n\t\t\treturn val.stack || val.message;\n\t\t}\n\t\treturn val;\n\t}\n\n\t/**\n\t* XXX DO NOT USE. This is a temporary stub function.\n\t* XXX It WILL be removed in the next major release.\n\t*/\n\tfunction destroy() {\n\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t}\n\n\tcreateDebug.enable(createDebug.load());\n\n\treturn createDebug;\n}\n\nmodule.exports = setup;\n","/* eslint-env browser */\n\n/**\n * This is the web browser implementation of `debug()`.\n */\n\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = localstorage();\nexports.destroy = (() => {\n\tlet warned = false;\n\n\treturn () => {\n\t\tif (!warned) {\n\t\t\twarned = true;\n\t\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t\t}\n\t};\n})();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n\t'#0000CC',\n\t'#0000FF',\n\t'#0033CC',\n\t'#0033FF',\n\t'#0066CC',\n\t'#0066FF',\n\t'#0099CC',\n\t'#0099FF',\n\t'#00CC00',\n\t'#00CC33',\n\t'#00CC66',\n\t'#00CC99',\n\t'#00CCCC',\n\t'#00CCFF',\n\t'#3300CC',\n\t'#3300FF',\n\t'#3333CC',\n\t'#3333FF',\n\t'#3366CC',\n\t'#3366FF',\n\t'#3399CC',\n\t'#3399FF',\n\t'#33CC00',\n\t'#33CC33',\n\t'#33CC66',\n\t'#33CC99',\n\t'#33CCCC',\n\t'#33CCFF',\n\t'#6600CC',\n\t'#6600FF',\n\t'#6633CC',\n\t'#6633FF',\n\t'#66CC00',\n\t'#66CC33',\n\t'#9900CC',\n\t'#9900FF',\n\t'#9933CC',\n\t'#9933FF',\n\t'#99CC00',\n\t'#99CC33',\n\t'#CC0000',\n\t'#CC0033',\n\t'#CC0066',\n\t'#CC0099',\n\t'#CC00CC',\n\t'#CC00FF',\n\t'#CC3300',\n\t'#CC3333',\n\t'#CC3366',\n\t'#CC3399',\n\t'#CC33CC',\n\t'#CC33FF',\n\t'#CC6600',\n\t'#CC6633',\n\t'#CC9900',\n\t'#CC9933',\n\t'#CCCC00',\n\t'#CCCC33',\n\t'#FF0000',\n\t'#FF0033',\n\t'#FF0066',\n\t'#FF0099',\n\t'#FF00CC',\n\t'#FF00FF',\n\t'#FF3300',\n\t'#FF3333',\n\t'#FF3366',\n\t'#FF3399',\n\t'#FF33CC',\n\t'#FF33FF',\n\t'#FF6600',\n\t'#FF6633',\n\t'#FF9900',\n\t'#FF9933',\n\t'#FFCC00',\n\t'#FFCC33'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\n// eslint-disable-next-line complexity\nfunction useColors() {\n\t// NB: In an Electron preload script, document will be defined but not fully\n\t// initialized. Since we know we're in Chrome, we'll just detect this case\n\t// explicitly\n\tif (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n\t\treturn true;\n\t}\n\n\t// Internet Explorer and Edge do not support colors.\n\tif (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n\t\treturn false;\n\t}\n\n\tlet m;\n\n\t// Is webkit? http://stackoverflow.com/a/16459606/376773\n\t// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\t// eslint-disable-next-line no-return-assign\n\treturn (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||\n\t\t// Is firebug? http://stackoverflow.com/a/398120/376773\n\t\t(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||\n\t\t// Is firefox >= v31?\n\t\t// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/)) && parseInt(m[1], 10) >= 31) ||\n\t\t// Double check webkit in userAgent just in case we are in a worker\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/));\n}\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs(args) {\n\targs[0] = (this.useColors ? '%c' : '') +\n\t\tthis.namespace +\n\t\t(this.useColors ? ' %c' : ' ') +\n\t\targs[0] +\n\t\t(this.useColors ? '%c ' : ' ') +\n\t\t'+' + module.exports.humanize(this.diff);\n\n\tif (!this.useColors) {\n\t\treturn;\n\t}\n\n\tconst c = 'color: ' + this.color;\n\targs.splice(1, 0, c, 'color: inherit');\n\n\t// The final \"%c\" is somewhat tricky, because there could be other\n\t// arguments passed either before or after the %c, so we need to\n\t// figure out the correct index to insert the CSS into\n\tlet index = 0;\n\tlet lastC = 0;\n\targs[0].replace(/%[a-zA-Z%]/g, match => {\n\t\tif (match === '%%') {\n\t\t\treturn;\n\t\t}\n\t\tindex++;\n\t\tif (match === '%c') {\n\t\t\t// We only are interested in the *last* %c\n\t\t\t// (the user may have provided their own)\n\t\t\tlastC = index;\n\t\t}\n\t});\n\n\targs.splice(lastC, 0, c);\n}\n\n/**\n * Invokes `console.debug()` when available.\n * No-op when `console.debug` is not a \"function\".\n * If `console.debug` is not available, falls back\n * to `console.log`.\n *\n * @api public\n */\nexports.log = console.debug || console.log || (() => {});\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\nfunction save(namespaces) {\n\ttry {\n\t\tif (namespaces) {\n\t\t\texports.storage.setItem('debug', namespaces);\n\t\t} else {\n\t\t\texports.storage.removeItem('debug');\n\t\t}\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\nfunction load() {\n\tlet r;\n\ttry {\n\t\tr = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n\n\t// If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\tif (!r && typeof process !== 'undefined' && 'env' in process) {\n\t\tr = process.env.DEBUG;\n\t}\n\n\treturn r;\n}\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage() {\n\ttry {\n\t\t// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n\t\t// The Browser also has localStorage in the global context.\n\t\treturn localStorage;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\nmodule.exports = require('./common')(exports);\n\nconst {formatters} = module.exports;\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nformatters.j = function (v) {\n\ttry {\n\t\treturn JSON.stringify(v);\n\t} catch (error) {\n\t\treturn '[UnexpectedJSONParseError]: ' + error.message;\n\t}\n};\n","import debug from \"debug\";\n\n/**\n * Debug logger utility for WuzAPI\n * Uses the debug package for conditional logging\n *\n * Usage:\n * - Set DEBUG=wuzapi:* to see all logs\n * - Set DEBUG=wuzapi:request to see only request logs\n * - Set DEBUG=wuzapi:response to see only response logs\n */\nexport const logger = {\n request: debug(\"wuzapi:request\"),\n response: debug(\"wuzapi:response\"),\n error: debug(\"wuzapi:error\"),\n info: debug(\"wuzapi:info\"),\n};\n\n/**\n * Creates a logger instance with a specific namespace\n * @param namespace - The namespace for the logger (will be prefixed with 'wuzapi:')\n */\nexport const createLogger = (namespace: string): debug.Debugger => {\n return debug(`wuzapi:${namespace}`);\n};\n\nexport default createLogger;\n","import axios, { AxiosInstance, AxiosResponse } from \"axios\";\nimport {\n WuzapiConfig,\n WuzapiResponse,\n RequestOptions,\n} from \"./types/common.js\";\nimport { logger } from \"./utils/logger.js\";\n\nexport class WuzapiError extends Error {\n public code: number;\n public details?: unknown;\n\n constructor(code: number, message: string, details?: unknown) {\n super(message);\n this.name = \"WuzapiError\";\n this.code = code;\n this.details = details;\n }\n}\n\nexport class BaseClient {\n protected axios: AxiosInstance;\n protected config: WuzapiConfig;\n protected defaultHeaders: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n constructor(config: WuzapiConfig) {\n this.config = config;\n this.axios = axios.create({\n baseURL: config.apiUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n // Add response interceptor for error handling\n this.axios.interceptors.response.use(\n (response: AxiosResponse) => response,\n (error) => {\n if (error.response) {\n // Server responded with error status\n const data = error.response.data;\n throw new WuzapiError(\n data.code || error.response.status,\n data.message || error.message,\n data\n );\n } else if (error.request) {\n // Request was made but no response received\n throw new WuzapiError(0, \"Network error: No response from server\");\n } else {\n // Something else happened\n throw new WuzapiError(0, error.message);\n }\n }\n );\n }\n\n /**\n * Resolve the token from request options or instance config\n * Throws an error if no token is available\n */\n private buildHeaders(options?: RequestOptions): Record<string, string> {\n const token = options?.token || this.config.token;\n if (!token) {\n throw new WuzapiError(\n 401,\n \"No authentication token provided. Either set a token in the client config or provide one in the request options.\"\n );\n }\n if (options?.token) {\n return {\n ...this.defaultHeaders,\n Token: options.token,\n };\n }\n return {\n ...this.defaultHeaders,\n Authorization: token,\n };\n }\n\n protected async request<T>(\n method: \"GET\" | \"POST\" | \"DELETE\" | \"PUT\",\n endpoint: string,\n data?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n const headers = this.buildHeaders(options);\n if (this.config.debug) {\n logger.request(`[${method}] ${endpoint}`, { headers, data });\n }\n\n const response = await this.axios.request<WuzapiResponse<T>>({\n method,\n url: endpoint,\n data,\n headers,\n });\n\n if (this.config.debug) {\n logger.response(`[${method}] ${endpoint}`, {\n status: response.status,\n data: response.data,\n });\n }\n\n if (!response.data.success) {\n throw new WuzapiError(\n response.data.code,\n \"API request failed\",\n response.data\n );\n }\n\n if (response.data.code <= 200 && response.data.code >= 300) {\n throw new WuzapiError(\n response.data.code,\n response.data.error || \"API request failed\",\n response.data\n );\n }\n\n return response.data.data;\n }\n\n protected async get<T>(\n endpoint: string,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>(\"GET\", endpoint, undefined, options);\n }\n\n protected async post<T>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>(\"POST\", endpoint, data, options);\n }\n\n protected async put<T>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>(\"PUT\", endpoint, data, options);\n }\n\n protected async delete<T>(\n endpoint: string,\n options?: RequestOptions\n ): Promise<T> {\n return this.request<T>(\"DELETE\", endpoint, undefined, options);\n }\n}\n"],"names":["ms","require$$0","debug","exports","module"],"mappings":"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","x_google_ignoreList":[0,1,2]}
@@ -301,11 +301,20 @@ export interface WebhookGenericMessage {
301
301
  audioMessage?: WebhookAudioMessage;
302
302
  documentMessage?: WebhookDocumentMessage;
303
303
  contactMessage?: WebhookContactMessage;
304
- pollCreationMessageV3?: WebhookPollCreationMessageV3;
305
304
  locationMessage?: WebhookLocationMessage;
306
305
  stickerMessage?: WebhookStickerMessage;
307
306
  reactionMessage?: WebhookReactionMessage;
308
307
  editedMessage?: WebhookEditedMessage;
308
+ buttonsMessage?: unknown;
309
+ listMessage?: unknown;
310
+ templateMessage?: unknown;
311
+ buttonsResponseMessage?: unknown;
312
+ listResponseMessage?: unknown;
313
+ groupInviteMessage?: unknown;
314
+ pollCreationMessage?: unknown;
315
+ pollCreationMessageV3?: WebhookPollCreationMessageV3;
316
+ pollUpdateMessage?: unknown;
317
+ viewOnceMessage?: unknown;
309
318
  protocolMessage?: {
310
319
  type?: number;
311
320
  editedMessage?: WebhookGenericMessage;
@@ -329,13 +338,22 @@ export declare enum MessageType {
329
338
  AUDIO = "audioMessage",
330
339
  DOCUMENT = "documentMessage",
331
340
  CONTACT = "contactMessage",
332
- POLL_CREATION = "pollCreationMessageV3",
333
341
  LOCATION = "locationMessage",
334
342
  STICKER = "stickerMessage",
335
343
  REACTION = "reactionMessage",
336
344
  EDITED = "editedMessage",
337
345
  PROTOCOL = "protocolMessage",
338
346
  DEVICE_SENT = "deviceSentMessage",
347
+ BUTTONS = "buttonsMessage",
348
+ LIST = "listMessage",
349
+ TEMPLATE = "templateMessage",
350
+ BUTTONS_RESPONSE = "buttonsResponseMessage",
351
+ LIST_RESPONSE = "listResponseMessage",
352
+ GROUP_INVITE = "groupInviteMessage",
353
+ POLL = "pollCreationMessage",
354
+ POLL_CREATION = "pollCreationMessageV3",
355
+ POLL_UPDATE = "pollUpdateMessage",
356
+ VIEW_ONCE = "viewOnceMessage",
339
357
  UNKNOWN = "unknown"
340
358
  }
341
359
  export interface WebhookHistorySyncNotification {
@@ -0,0 +1,22 @@
1
+ import { default as debug } from 'debug';
2
+ /**
3
+ * Debug logger utility for WuzAPI
4
+ * Uses the debug package for conditional logging
5
+ *
6
+ * Usage:
7
+ * - Set DEBUG=wuzapi:* to see all logs
8
+ * - Set DEBUG=wuzapi:request to see only request logs
9
+ * - Set DEBUG=wuzapi:response to see only response logs
10
+ */
11
+ export declare const logger: {
12
+ request: debug.Debugger;
13
+ response: debug.Debugger;
14
+ error: debug.Debugger;
15
+ info: debug.Debugger;
16
+ };
17
+ /**
18
+ * Creates a logger instance with a specific namespace
19
+ * @param namespace - The namespace for the logger (will be prefixed with 'wuzapi:')
20
+ */
21
+ export declare const createLogger: (namespace: string) => debug.Debugger;
22
+ export default createLogger;
package/dist/webhook.js CHANGED
@@ -58,13 +58,22 @@ var MessageType = /* @__PURE__ */ ((MessageType2) => {
58
58
  MessageType2["AUDIO"] = "audioMessage";
59
59
  MessageType2["DOCUMENT"] = "documentMessage";
60
60
  MessageType2["CONTACT"] = "contactMessage";
61
- MessageType2["POLL_CREATION"] = "pollCreationMessageV3";
62
61
  MessageType2["LOCATION"] = "locationMessage";
63
62
  MessageType2["STICKER"] = "stickerMessage";
64
63
  MessageType2["REACTION"] = "reactionMessage";
65
64
  MessageType2["EDITED"] = "editedMessage";
66
65
  MessageType2["PROTOCOL"] = "protocolMessage";
67
66
  MessageType2["DEVICE_SENT"] = "deviceSentMessage";
67
+ MessageType2["BUTTONS"] = "buttonsMessage";
68
+ MessageType2["LIST"] = "listMessage";
69
+ MessageType2["TEMPLATE"] = "templateMessage";
70
+ MessageType2["BUTTONS_RESPONSE"] = "buttonsResponseMessage";
71
+ MessageType2["LIST_RESPONSE"] = "listResponseMessage";
72
+ MessageType2["GROUP_INVITE"] = "groupInviteMessage";
73
+ MessageType2["POLL"] = "pollCreationMessage";
74
+ MessageType2["POLL_CREATION"] = "pollCreationMessageV3";
75
+ MessageType2["POLL_UPDATE"] = "pollUpdateMessage";
76
+ MessageType2["VIEW_ONCE"] = "viewOnceMessage";
68
77
  MessageType2["UNKNOWN"] = "unknown";
69
78
  return MessageType2;
70
79
  })(MessageType || {});
@@ -95,7 +104,16 @@ function discoverMessageType(message) {
95
104
  if (message.locationMessage) return "locationMessage";
96
105
  if (message.stickerMessage) return "stickerMessage";
97
106
  if (message.reactionMessage) return "reactionMessage";
107
+ if (message.buttonsMessage) return "buttonsMessage";
108
+ if (message.listMessage) return "listMessage";
109
+ if (message.templateMessage) return "templateMessage";
110
+ if (message.buttonsResponseMessage) return "buttonsResponseMessage";
111
+ if (message.listResponseMessage) return "listResponseMessage";
112
+ if (message.groupInviteMessage) return "groupInviteMessage";
113
+ if (message.pollCreationMessage) return "pollCreationMessage";
98
114
  if (message.pollCreationMessageV3) return "pollCreationMessageV3";
115
+ if (message.pollUpdateMessage) return "pollUpdateMessage";
116
+ if (message.viewOnceMessage) return "viewOnceMessage";
99
117
  if (message.editedMessage) return "editedMessage";
100
118
  if (message.protocolMessage) return "protocolMessage";
101
119
  if (message.deviceSentMessage) return "deviceSentMessage";
@@ -1 +1 @@
1
- {"version":3,"file":"webhook.js","sources":["../src/types/webhook.ts"],"sourcesContent":["// Import types that are identical from other modules\nimport type { VerifiedName } from \"./user.js\";\n\n// Webhook endpoints types\n\n// Webhook event types (events that can be subscribed to via webhooks)\nexport enum WebhookEventType {\n MESSAGE = \"Message\",\n UNDECRYPTABLE_MESSAGE = \"UndecryptableMessage\",\n RECEIPT = \"Receipt\",\n READ_RECEIPT = \"ReadReceipt\",\n MEDIA_RETRY = \"MediaRetry\",\n GROUP_INFO = \"GroupInfo\",\n JOINED_GROUP = \"JoinedGroup\",\n PICTURE = \"Picture\",\n BLOCKLIST_CHANGE = \"BlocklistChange\",\n BLOCKLIST = \"Blocklist\",\n CONNECTED = \"Connected\",\n DISCONNECTED = \"Disconnected\",\n CONNECT_FAILURE = \"ConnectFailure\",\n KEEP_ALIVE_RESTORED = \"KeepAliveRestored\",\n KEEP_ALIVE_TIMEOUT = \"KeepAliveTimeout\",\n LOGGED_OUT = \"LoggedOut\",\n CLIENT_OUTDATED = \"ClientOutdated\",\n TEMPORARY_BAN = \"TemporaryBan\",\n STREAM_ERROR = \"StreamError\",\n STREAM_REPLACED = \"StreamReplaced\",\n PAIR_SUCCESS = \"PairSuccess\",\n PAIR_ERROR = \"PairError\",\n QR = \"QR\",\n QR_SCANNED_WITHOUT_MULTIDEVICE = \"QRScannedWithoutMultidevice\",\n PRIVACY_SETTINGS = \"PrivacySettings\",\n PUSH_NAME_SETTING = \"PushNameSetting\",\n USER_ABOUT = \"UserAbout\",\n APP_STATE = \"AppState\",\n APP_STATE_SYNC_COMPLETE = \"AppStateSyncComplete\",\n HISTORY_SYNC = \"HistorySync\",\n OFFLINE_SYNC_COMPLETED = \"OfflineSyncCompleted\",\n OFFLINE_SYNC_PREVIEW = \"OfflineSyncPreview\",\n CALL_OFFER = \"CallOffer\",\n CALL_ACCEPT = \"CallAccept\",\n CALL_TERMINATE = \"CallTerminate\",\n CALL_OFFER_NOTICE = \"CallOfferNotice\",\n CALL_RELAY_LATENCY = \"CallRelayLatency\",\n PRESENCE = \"Presence\",\n CHAT_PRESENCE = \"ChatPresence\",\n IDENTITY_CHANGE = \"IdentityChange\",\n CAT_REFRESH_ERROR = \"CATRefreshError\",\n NEWSLETTER_JOIN = \"NewsletterJoin\",\n NEWSLETTER_LEAVE = \"NewsletterLeave\",\n NEWSLETTER_MUTE_CHANGE = \"NewsletterMuteChange\",\n NEWSLETTER_LIVE_UPDATE = \"NewsletterLiveUpdate\",\n FB_MESSAGE = \"FBMessage\",\n ALL = \"All\",\n}\n\n// Helper to get all webhook event values as string array\nexport const WEBHOOK_EVENTS = Object.values(WebhookEventType);\n\n// Type for webhook event names\nexport type WebhookEvent = keyof typeof WebhookEventType;\n\nexport interface SetWebhookRequest {\n webhook: string;\n events: (WebhookEvent | string)[];\n}\n\nexport interface SetWebhookResponse {\n WebhookURL: string;\n Events: string[];\n}\n\nexport interface GetWebhookResponse {\n subscribe: string[];\n webhook: string;\n}\n\nexport interface UpdateWebhookRequest {\n webhook?: string;\n events?: (WebhookEvent | string)[];\n Active?: boolean;\n}\n\nexport interface UpdateWebhookResponse {\n WebhookURL: string;\n Events: string[];\n active: boolean;\n}\n\nexport interface DeleteWebhookResponse {\n Details: string;\n}\n\n// Webhook payload types (what your webhook endpoint receives)\n\nexport interface S3MediaInfo {\n url: string;\n key: string;\n bucket: string;\n size: number;\n mimeType: string;\n fileName: string;\n}\n\n// Base interface that all webhook payloads extend from\nexport interface WebhookPayloadBase<T = unknown> {\n event: T;\n type: string;\n token: string;\n state?: string; // Optional state field (e.g., \"Read\" or \"Delivered\" for ReadReceipt events)\n}\n\n// Standard webhook payload with optional media\nexport interface WebhookPayload<T = unknown> extends WebhookPayloadBase<T> {\n s3?: S3MediaInfo;\n base64?: string;\n mimeType?: string;\n fileName?: string;\n}\n\n// Specific webhook payload types for different media delivery modes\n\n// S3 only delivery\nexport interface S3OnlyWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n s3: S3MediaInfo;\n}\n\n// Base64 only delivery\nexport interface Base64OnlyWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n base64: string;\n mimeType: string;\n fileName: string;\n}\n\n// Both S3 and Base64 delivery\nexport interface BothMediaWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n s3: S3MediaInfo;\n base64: string;\n mimeType: string;\n fileName: string;\n}\n\n// Union type for all possible webhook payloads\nexport type AnyWebhookPayload<T = unknown> =\n | WebhookPayload<T>\n | S3OnlyWebhookPayload<T>\n | Base64OnlyWebhookPayload<T>\n | BothMediaWebhookPayload<T>;\n\n// Shared message and media interfaces for reusability across webhook events\n//\n// Note: Webhook events may have different structures than the corresponding\n// WhatsApp events in events.ts. Webhook events use flat structures with\n// string-based JIDs and ISO timestamp strings, while internal events use\n// structured JID objects and Date objects.\n\n// Common context info structures\nexport interface WebhookMessageContextInfo {\n deviceListMetadata?: WebhookDeviceListMetadata;\n deviceListMetadataVersion?: number;\n messageSecret?: string; // Encryption secret (string format for webhook)\n limitSharingV2?: {\n initiatedByMe: boolean;\n trigger: number;\n };\n}\n\nexport interface WebhookDeviceListMetadata {\n senderKeyHash?: string; // Base64 string format for webhook (vs Uint8Array in message.ts)\n senderTimestamp?: number;\n recipientKeyHash?: string; // Base64 string format for webhook\n recipientTimestamp?: number;\n senderAccountType?: number; // Webhook-specific field\n receiverAccountType?: number; // Webhook-specific field\n}\n\nexport interface WebhookContextInfo {\n disappearingMode?: {\n initiator: number;\n initiatedByMe?: boolean; // Webhook-specific field\n trigger?: number; // Webhook-specific field\n };\n ephemeralSettingTimestamp?: number;\n expiration?: number;\n forwardingScore?: number;\n isForwarded?: boolean;\n pairedMediaType?: number;\n statusSourceType?: number;\n featureEligibilities?: {\n canBeReshared?: boolean;\n };\n}\n\n// Common message types that are reused across different webhook events\nexport interface WebhookExtendedTextMessage {\n text: string;\n contextInfo?: WebhookContextInfo;\n inviteLinkGroupTypeV2?: number; // Webhook-specific field\n previewType?: number; // Webhook-specific field\n}\n\nexport interface WebhookImageMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n height: number;\n imageSourceType: number; // Webhook-specific field\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n midQualityFileSHA256: string; // Mid quality file hash (webhook-specific)\n mimetype: string; // MIME type (e.g., \"image/jpeg\")\n scanLengths: number[]; // Progressive scan lengths (webhook-specific)\n scansSidecar: string; // Progressive scan sidecar data (webhook-specific)\n firstScanLength?: number; // First scan length (webhook-specific)\n firstScanSidecar?: string; // First scan sidecar (webhook-specific)\n width: number;\n}\n\nexport interface WebhookVideoMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail\n accessibilityLabel?: string;\n caption?: string;\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n externalShareFullVideoDurationInSeconds?: number; // Webhook-specific field\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n gifAttribution?: number; // GIF attribution type (0=none, 1=giphy, 2=tenor, etc.) (webhook-specific)\n gifPlayback?: boolean; // Whether this video should be played as a GIF (webhook-specific)\n height: number;\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n mimetype: string; // MIME type (e.g., \"video/mp4\")\n seconds: number; // Video duration in seconds\n streamingSidecar?: string; // Streaming sidecar data for video streaming\n thumbnailDirectPath?: string; // Thumbnail direct path (webhook-specific)\n thumbnailEncSHA256?: string; // Thumbnail encrypted SHA256 (webhook-specific)\n thumbnailSHA256?: string; // Thumbnail SHA256 (webhook-specific)\n videoSourceType?: number; // Webhook-specific field\n width: number;\n}\n\nexport interface WebhookAudioMessage {\n URL?: string; // Uppercase for webhook\n contextInfo?: WebhookContextInfo;\n directPath?: string;\n fileEncSHA256?: string; // String format for webhook\n fileLength?: number;\n fileSHA256?: string; // String format for webhook\n mediaKey?: string; // String format for webhook\n mediaKeyTimestamp?: number;\n mimetype?: string;\n seconds?: number;\n ptt?: boolean; // Push to talk (voice message) - Note: payload uses uppercase \"PTT\"\n streamingSidecar?: string; // Streaming sidecar data for audio streaming (webhook-specific)\n waveform?: string; // Base64 encoded waveform for voice messages (webhook-specific)\n}\n\nexport interface WebhookDocumentMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n contactVcard: boolean; // Whether this is a contact vCard (webhook-specific field)\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileName: string; // Original file name\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n mimetype: string; // MIME type (e.g., \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", \"application/pdf\")\n pageCount?: number; // Number of pages in the document (webhook-specific field)\n title: string; // Document title (usually filename without extension)\n}\n\nexport interface WebhookContactMessage {\n contextInfo?: WebhookContextInfo;\n displayName: string; // Display name of the contact\n vcard: string; // vCard data in standard vCard format\n}\n\nexport interface WebhookPollCreationMessageV3 {\n contextInfo?: WebhookContextInfo;\n name: string; // Poll question/title\n options: Array<{\n optionHash: string; // Hash for the option\n optionName: string; // Display text for the option\n }>;\n pollContentType: number; // Type of poll content\n selectableOptionsCount: number; // Number of options that can be selected (0 = single choice, >0 = multiple choice)\n}\n\nexport interface WebhookLocationMessage {\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail of the location (webhook-specific field)\n contextInfo?: WebhookContextInfo;\n degreesLatitude: number; // Latitude coordinate\n degreesLongitude: number; // Longitude coordinate\n}\n\nexport interface WebhookStickerMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n firstFrameLength?: number; // First frame length for animated stickers (webhook-specific)\n firstFrameSidecar?: string; // First frame sidecar data (webhook-specific)\n height: number; // Sticker height\n isAiSticker?: boolean; // Whether this is an AI-generated sticker (webhook-specific)\n isAnimated?: boolean; // Whether this is an animated sticker (webhook-specific)\n isAvatar?: boolean; // Whether this is an avatar sticker (webhook-specific)\n isLottie?: boolean; // Whether this is a Lottie sticker (webhook-specific)\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n mimetype: string; // MIME type (typically \"image/webp\" for stickers)\n stickerSentTS?: number; // Sticker sent timestamp (webhook-specific field)\n width: number; // Sticker width\n}\n\nexport interface WebhookReactionMessage {\n key: WebhookMessageKey; // Key of the message being reacted to\n senderTimestampMS?: number; // Timestamp when reaction was sent\n text?: string; // The reaction emoji/text\n}\n\nexport interface WebhookEditedMessage {\n message?: unknown; // The edited message content\n timestampMS?: string; // Edit timestamp\n editedMessageID?: string; // ID of original message being edited\n}\n\n// Message key structure\nexport interface WebhookMessageKey {\n ID: string; // Uppercase field name for webhook (vs lowercase 'id' in message.ts)\n fromMe: boolean; // Required in webhook (vs optional in message.ts)\n participant?: string; // JID in string format\n remoteJID: string; // Uppercase JID field name for webhook (vs 'remoteJid' in message.ts)\n}\n\n// User receipt structure\nexport interface UserReceipt {\n userJID?: string;\n receiptTimestamp?: number;\n readTimestamp?: number;\n playedTimestamp?: number;\n}\n\n// Reaction structure\nexport interface WebhookReaction {\n key?: WebhookMessageKey;\n text?: string;\n senderTimestampMS?: number;\n}\n\n// Generic message wrapper for webhook payloads\nexport interface WebhookGenericMessage {\n messageContextInfo?: WebhookMessageContextInfo;\n conversation?: string; // Simple text message\n extendedTextMessage?: WebhookExtendedTextMessage;\n imageMessage?: WebhookImageMessage;\n videoMessage?: WebhookVideoMessage;\n audioMessage?: WebhookAudioMessage;\n documentMessage?: WebhookDocumentMessage;\n contactMessage?: WebhookContactMessage;\n pollCreationMessageV3?: WebhookPollCreationMessageV3;\n locationMessage?: WebhookLocationMessage;\n stickerMessage?: WebhookStickerMessage;\n reactionMessage?: WebhookReactionMessage;\n editedMessage?: WebhookEditedMessage;\n protocolMessage?: {\n type?: number;\n editedMessage?: WebhookGenericMessage; // Nested edited message in protocol messages\n key?: WebhookMessageKey; // Message key for protocol messages\n timestampMS?: number; // Edit timestamp\n historySyncNotification?: WebhookHistorySyncNotification;\n initialSecurityNotificationSettingSync?: {\n securityNotificationEnabled: boolean;\n };\n };\n deviceSentMessage?: {\n destinationJID: string;\n message: WebhookGenericMessage;\n };\n}\n\n// Message types enum for easier handling of different message types\nexport enum MessageType {\n TEXT = \"conversation\",\n EXTENDED_TEXT = \"extendedTextMessage\",\n IMAGE = \"imageMessage\",\n VIDEO = \"videoMessage\",\n AUDIO = \"audioMessage\",\n DOCUMENT = \"documentMessage\",\n CONTACT = \"contactMessage\",\n POLL_CREATION = \"pollCreationMessageV3\",\n LOCATION = \"locationMessage\",\n STICKER = \"stickerMessage\",\n REACTION = \"reactionMessage\",\n EDITED = \"editedMessage\",\n PROTOCOL = \"protocolMessage\",\n DEVICE_SENT = \"deviceSentMessage\",\n UNKNOWN = \"unknown\",\n}\n// History sync notification structure\nexport interface WebhookHistorySyncNotification {\n chunkOrder?: number;\n directPath: string;\n encHandle: string; // Webhook-specific field\n fileEncSHA256: string; // String format for webhook\n fileLength: number;\n fileSHA256: string; // String format for webhook\n mediaKey: string; // String format for webhook\n progress?: number;\n syncType: number;\n}\n\n// Using VerifiedName imported from user.ts (identical interface)\n\n// Specific webhook event data interfaces\n\n// QR webhook event data (based on observed webhook payload)\n// Note: For QR events, the event field is actually just the string \"code\"\n// We represent this as an empty interface since the real data is at payload level\nexport interface QRWebhookEvent {\n // The event field contains just the string \"code\"\n // The actual QR code data is in qrCodeBase64 at the payload level\n}\n\n// Connected webhook event data (based on observed webhook payload)\n// Note: For Connected events, the event field is an empty object {}\nexport interface ConnectedWebhookEvent {\n // The event field contains an empty object {}\n // No additional data is provided for Connected events\n}\n\n// ReadReceipt webhook event data (based on observed webhook payload)\n// Maps to Receipt event type but with webhook-specific structure\nexport interface ReadReceiptWebhookEvent {\n AddressingMode: string;\n BroadcastListOwner: string;\n Chat: string; // JID in string format (e.g., \"554198387899-1431900789@g.us\")\n IsFromMe: boolean;\n IsGroup: boolean;\n MessageIDs: string[];\n MessageSender: string;\n RecipientAlt: string;\n Sender: string; // JID in string format (e.g., \"554198387899@s.whatsapp.net\")\n SenderAlt: string;\n Timestamp: string; // ISO string timestamp\n Type: string; // Receipt type (e.g., \"read\")\n}\n\n// HistorySync webhook event data (based on observed webhook payload)\n// Contains different types of historical data - can be pastParticipants, statusV3Messages, conversations, etc.\nexport interface HistorySyncWebhookEvent {\n Data: {\n // Variant 1: Past participants data (groups and stickers)\n pastParticipants?: Array<{\n groupJID: string; // JID in string format (e.g., \"120363388053770128@g.us\")\n pastParticipants: Array<{\n leaveReason: number; // 0 = left voluntarily, 1 = kicked/removed\n leaveTS: number; // Unix timestamp\n userJID: string; // JID in string format\n }>;\n }>;\n recentStickers?: Array<{\n URL: string; // Full WhatsApp media URL\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash\n height: number;\n isLottie: boolean; // Whether it's an animated Lottie sticker\n lastStickerSentTS: number; // Unix timestamp of last usage\n mediaKey: string; // Media encryption key\n mimetype: string; // MIME type (e.g., \"image/webp\")\n weight: number; // Usage weight/frequency\n width: number;\n }>;\n\n // Variant 2: Status messages data (stories/status updates)\n statusV3Messages?: Array<{\n key: WebhookMessageKey;\n message: WebhookGenericMessage;\n messageTimestamp: number; // Unix timestamp\n participant: string; // JID in string format\n reportingTokenInfo?: {\n reportingTag: string;\n };\n }>;\n\n // Variant 3: Conversation histories data\n conversations?: Array<{\n ID: string; // JID in string format (chat identifier)\n messages: Array<{\n message: {\n key: WebhookMessageKey;\n message: WebhookGenericMessage;\n messageTimestamp: number; // Unix timestamp\n messageC2STimestamp?: number; // Client to server timestamp\n ephemeralStartTimestamp?: number; // Ephemeral message start timestamp\n originalSelfAuthorUserJIDString?: string; // Original author for messages sent by self\n status?: number; // Message status (3=delivered, 4=read, 5=played)\n userReceipt?: UserReceipt[];\n reactions?: WebhookReaction[];\n reportingTokenInfo?: {\n reportingTag: string;\n };\n };\n msgOrderID: number; // Message order ID\n }>;\n }>;\n phoneNumberToLidMappings?: Array<{\n lidJID: string; // LID JID (e.g., \"165434221441206@lid\")\n pnJID: string; // Phone number JID (e.g., \"554199392033@s.whatsapp.net\")\n }>;\n\n // Common fields for all variants\n chunkOrder?: number; // Chunk order for paginated sync\n progress?: number; // Sync progress\n syncType: number; // Sync operation type\n };\n}\n\n// Message webhook event data (based on observed webhook payload)\n// Complex structure similar to MessageEvent in events.ts but with webhook-specific format\nexport interface MessageWebhookEvent {\n Info: {\n AddressingMode: string;\n BroadcastListOwner: string;\n Category: string;\n Chat: string; // JID in string format\n DeviceSentMeta: {\n DestinationJID: string;\n Phash: string;\n } | null;\n Edit: string;\n ID: string;\n IsFromMe: boolean;\n IsGroup: boolean;\n MediaType: string;\n MsgBotInfo: {\n EditSenderTimestampMS: string; // ISO timestamp\n EditTargetID: string;\n EditType: string;\n };\n MsgMetaInfo: {\n DeprecatedLIDSession: unknown | null;\n TargetID: string;\n TargetSender: string;\n ThreadMessageID: string;\n ThreadMessageSenderJID: string;\n };\n Multicast: boolean;\n PushName: string;\n RecipientAlt: string;\n Sender: string; // JID in string format\n SenderAlt: string;\n ServerID: number;\n Timestamp: string; // ISO string timestamp\n Type: string; // Message type (e.g., \"text\")\n VerifiedName: VerifiedName | null;\n };\n IsDocumentWithCaption: boolean;\n IsEdit: boolean;\n IsEphemeral: boolean;\n IsLottieSticker: boolean;\n IsViewOnce: boolean;\n IsViewOnceV2: boolean;\n IsViewOnceV2Extension: boolean;\n Message: WebhookGenericMessage; // Using webhook-specific message structure\n NewsletterMeta: unknown | null;\n RawMessage: WebhookGenericMessage; // Using webhook-specific message structure\n RetryCount: number;\n SourceWebMsg: unknown | null;\n UnavailableRequestID: string;\n}\n\n// Typed webhook payloads for specific events\nexport type QRWebhookPayload = AnyWebhookPayload<QRWebhookEvent> & {\n qrCodeBase64: string; // QR code as base64 data URL\n};\nexport type ConnectedWebhookPayload = AnyWebhookPayload<ConnectedWebhookEvent>;\nexport type ReadReceiptWebhookPayload =\n AnyWebhookPayload<ReadReceiptWebhookEvent>;\nexport type HistorySyncWebhookPayload =\n AnyWebhookPayload<HistorySyncWebhookEvent>;\nexport type MessageWebhookPayload = AnyWebhookPayload<MessageWebhookEvent>;\n\n// Webhook event mapping types for type-safe handling\nexport interface WebhookEventMap {\n QR: QRWebhookEvent;\n Connected: ConnectedWebhookEvent;\n ReadReceipt: ReadReceiptWebhookEvent;\n HistorySync: HistorySyncWebhookEvent;\n Message: MessageWebhookEvent;\n // Add more webhook event mappings here as they are discovered\n}\n\n// Type-safe webhook handler function type\nexport type WebhookEventHandler<T extends keyof WebhookEventMap> = (\n payload: AnyWebhookPayload<WebhookEventMap[T]>\n) => void | Promise<void>;\n\n// Union type for all specific webhook payloads\nexport type SpecificWebhookPayload =\n | QRWebhookPayload\n | ConnectedWebhookPayload\n | ReadReceiptWebhookPayload\n | HistorySyncWebhookPayload\n | MessageWebhookPayload;\n\n// Type guard to check if payload is a specific webhook event type\nexport function isWebhookEventType<T extends keyof WebhookEventMap>(\n payload: WebhookPayloadBase,\n eventType: T\n): payload is AnyWebhookPayload<WebhookEventMap[T]> {\n return payload.type === eventType;\n}\n\n// Helper type guards\nexport function hasS3Media(\n payload: WebhookPayloadBase\n): payload is S3OnlyWebhookPayload | BothMediaWebhookPayload {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return !!(payload as any).s3;\n}\n\nexport function hasBase64Media(\n payload: WebhookPayloadBase\n): payload is Base64OnlyWebhookPayload | BothMediaWebhookPayload {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return !!(payload as any).base64;\n}\n\nexport function hasBothMedia(\n payload: WebhookPayloadBase\n): payload is BothMediaWebhookPayload {\n return hasS3Media(payload) && hasBase64Media(payload);\n}\n\n// Helper type guard to check if payload has token (all webhook payloads should)\nexport function isValidWebhookPayload(\n payload: unknown\n): payload is WebhookPayloadBase {\n return (\n typeof payload === \"object\" &&\n payload !== null &&\n \"event\" in payload &&\n \"type\" in payload &&\n \"token\" in payload\n );\n}\n\n/**\n * Utility function to discover the type of a GenericMessage\n * @param message - The GenericMessage to analyze\n * @returns MessageType enum value indicating the message type\n *\n * @example\n * ```typescript\n * import { discoverMessageType, MessageType } from \"wuzapi\";\n *\n * const messageType = discoverMessageType(webhookPayload.event.Message);\n *\n * switch (messageType) {\n * case MessageType.IMAGE:\n * console.log(\"Received an image message\");\n * break;\n * case MessageType.EXTENDED_TEXT:\n * console.log(\"Received a text message\");\n * break;\n * // ... handle other types\n * }\n * ```\n */\nexport function discoverMessageType(\n message: WebhookGenericMessage\n): MessageType {\n if (!message) return MessageType.UNKNOWN;\n\n // Check for each message type in order of most common to least common\n if (message.conversation) return MessageType.TEXT;\n if (message.extendedTextMessage) return MessageType.EXTENDED_TEXT;\n if (message.imageMessage) return MessageType.IMAGE;\n if (message.videoMessage) return MessageType.VIDEO;\n if (message.audioMessage) return MessageType.AUDIO;\n if (message.documentMessage) return MessageType.DOCUMENT;\n if (message.contactMessage) return MessageType.CONTACT;\n if (message.locationMessage) return MessageType.LOCATION;\n if (message.stickerMessage) return MessageType.STICKER;\n if (message.reactionMessage) return MessageType.REACTION;\n if (message.pollCreationMessageV3) return MessageType.POLL_CREATION;\n if (message.editedMessage) return MessageType.EDITED;\n if (message.protocolMessage) return MessageType.PROTOCOL;\n if (message.deviceSentMessage) return MessageType.DEVICE_SENT;\n\n return MessageType.UNKNOWN;\n}\n"],"names":["WebhookEventType","MessageType"],"mappings":"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"}
1
+ {"version":3,"file":"webhook.js","sources":["../src/types/webhook.ts"],"sourcesContent":["// Import types that are identical from other modules\nimport type { VerifiedName } from \"./user.js\";\n\n// Webhook endpoints types\n\n// Webhook event types (events that can be subscribed to via webhooks)\nexport enum WebhookEventType {\n MESSAGE = \"Message\",\n UNDECRYPTABLE_MESSAGE = \"UndecryptableMessage\",\n RECEIPT = \"Receipt\",\n READ_RECEIPT = \"ReadReceipt\",\n MEDIA_RETRY = \"MediaRetry\",\n GROUP_INFO = \"GroupInfo\",\n JOINED_GROUP = \"JoinedGroup\",\n PICTURE = \"Picture\",\n BLOCKLIST_CHANGE = \"BlocklistChange\",\n BLOCKLIST = \"Blocklist\",\n CONNECTED = \"Connected\",\n DISCONNECTED = \"Disconnected\",\n CONNECT_FAILURE = \"ConnectFailure\",\n KEEP_ALIVE_RESTORED = \"KeepAliveRestored\",\n KEEP_ALIVE_TIMEOUT = \"KeepAliveTimeout\",\n LOGGED_OUT = \"LoggedOut\",\n CLIENT_OUTDATED = \"ClientOutdated\",\n TEMPORARY_BAN = \"TemporaryBan\",\n STREAM_ERROR = \"StreamError\",\n STREAM_REPLACED = \"StreamReplaced\",\n PAIR_SUCCESS = \"PairSuccess\",\n PAIR_ERROR = \"PairError\",\n QR = \"QR\",\n QR_SCANNED_WITHOUT_MULTIDEVICE = \"QRScannedWithoutMultidevice\",\n PRIVACY_SETTINGS = \"PrivacySettings\",\n PUSH_NAME_SETTING = \"PushNameSetting\",\n USER_ABOUT = \"UserAbout\",\n APP_STATE = \"AppState\",\n APP_STATE_SYNC_COMPLETE = \"AppStateSyncComplete\",\n HISTORY_SYNC = \"HistorySync\",\n OFFLINE_SYNC_COMPLETED = \"OfflineSyncCompleted\",\n OFFLINE_SYNC_PREVIEW = \"OfflineSyncPreview\",\n CALL_OFFER = \"CallOffer\",\n CALL_ACCEPT = \"CallAccept\",\n CALL_TERMINATE = \"CallTerminate\",\n CALL_OFFER_NOTICE = \"CallOfferNotice\",\n CALL_RELAY_LATENCY = \"CallRelayLatency\",\n PRESENCE = \"Presence\",\n CHAT_PRESENCE = \"ChatPresence\",\n IDENTITY_CHANGE = \"IdentityChange\",\n CAT_REFRESH_ERROR = \"CATRefreshError\",\n NEWSLETTER_JOIN = \"NewsletterJoin\",\n NEWSLETTER_LEAVE = \"NewsletterLeave\",\n NEWSLETTER_MUTE_CHANGE = \"NewsletterMuteChange\",\n NEWSLETTER_LIVE_UPDATE = \"NewsletterLiveUpdate\",\n FB_MESSAGE = \"FBMessage\",\n ALL = \"All\",\n}\n\n// Helper to get all webhook event values as string array\nexport const WEBHOOK_EVENTS = Object.values(WebhookEventType);\n\n// Type for webhook event names\nexport type WebhookEvent = keyof typeof WebhookEventType;\n\nexport interface SetWebhookRequest {\n webhook: string;\n events: (WebhookEvent | string)[];\n}\n\nexport interface SetWebhookResponse {\n WebhookURL: string;\n Events: string[];\n}\n\nexport interface GetWebhookResponse {\n subscribe: string[];\n webhook: string;\n}\n\nexport interface UpdateWebhookRequest {\n webhook?: string;\n events?: (WebhookEvent | string)[];\n Active?: boolean;\n}\n\nexport interface UpdateWebhookResponse {\n WebhookURL: string;\n Events: string[];\n active: boolean;\n}\n\nexport interface DeleteWebhookResponse {\n Details: string;\n}\n\n// Webhook payload types (what your webhook endpoint receives)\n\nexport interface S3MediaInfo {\n url: string;\n key: string;\n bucket: string;\n size: number;\n mimeType: string;\n fileName: string;\n}\n\n// Base interface that all webhook payloads extend from\nexport interface WebhookPayloadBase<T = unknown> {\n event: T;\n type: string;\n token: string;\n state?: string; // Optional state field (e.g., \"Read\" or \"Delivered\" for ReadReceipt events)\n}\n\n// Standard webhook payload with optional media\nexport interface WebhookPayload<T = unknown> extends WebhookPayloadBase<T> {\n s3?: S3MediaInfo;\n base64?: string;\n mimeType?: string;\n fileName?: string;\n}\n\n// Specific webhook payload types for different media delivery modes\n\n// S3 only delivery\nexport interface S3OnlyWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n s3: S3MediaInfo;\n}\n\n// Base64 only delivery\nexport interface Base64OnlyWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n base64: string;\n mimeType: string;\n fileName: string;\n}\n\n// Both S3 and Base64 delivery\nexport interface BothMediaWebhookPayload<T = unknown>\n extends WebhookPayloadBase<T> {\n s3: S3MediaInfo;\n base64: string;\n mimeType: string;\n fileName: string;\n}\n\n// Union type for all possible webhook payloads\nexport type AnyWebhookPayload<T = unknown> =\n | WebhookPayload<T>\n | S3OnlyWebhookPayload<T>\n | Base64OnlyWebhookPayload<T>\n | BothMediaWebhookPayload<T>;\n\n// Shared message and media interfaces for reusability across webhook events\n//\n// Note: Webhook events may have different structures than the corresponding\n// WhatsApp events in events.ts. Webhook events use flat structures with\n// string-based JIDs and ISO timestamp strings, while internal events use\n// structured JID objects and Date objects.\n\n// Common context info structures\nexport interface WebhookMessageContextInfo {\n deviceListMetadata?: WebhookDeviceListMetadata;\n deviceListMetadataVersion?: number;\n messageSecret?: string; // Encryption secret (string format for webhook)\n limitSharingV2?: {\n initiatedByMe: boolean;\n trigger: number;\n };\n}\n\nexport interface WebhookDeviceListMetadata {\n senderKeyHash?: string; // Base64 string format for webhook (vs Uint8Array in message.ts)\n senderTimestamp?: number;\n recipientKeyHash?: string; // Base64 string format for webhook\n recipientTimestamp?: number;\n senderAccountType?: number; // Webhook-specific field\n receiverAccountType?: number; // Webhook-specific field\n}\n\nexport interface WebhookContextInfo {\n disappearingMode?: {\n initiator: number;\n initiatedByMe?: boolean; // Webhook-specific field\n trigger?: number; // Webhook-specific field\n };\n ephemeralSettingTimestamp?: number;\n expiration?: number;\n forwardingScore?: number;\n isForwarded?: boolean;\n pairedMediaType?: number;\n statusSourceType?: number;\n featureEligibilities?: {\n canBeReshared?: boolean;\n };\n}\n\n// Common message types that are reused across different webhook events\nexport interface WebhookExtendedTextMessage {\n text: string;\n contextInfo?: WebhookContextInfo;\n inviteLinkGroupTypeV2?: number; // Webhook-specific field\n previewType?: number; // Webhook-specific field\n}\n\nexport interface WebhookImageMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n height: number;\n imageSourceType: number; // Webhook-specific field\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n midQualityFileSHA256: string; // Mid quality file hash (webhook-specific)\n mimetype: string; // MIME type (e.g., \"image/jpeg\")\n scanLengths: number[]; // Progressive scan lengths (webhook-specific)\n scansSidecar: string; // Progressive scan sidecar data (webhook-specific)\n firstScanLength?: number; // First scan length (webhook-specific)\n firstScanSidecar?: string; // First scan sidecar (webhook-specific)\n width: number;\n}\n\nexport interface WebhookVideoMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail\n accessibilityLabel?: string;\n caption?: string;\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n externalShareFullVideoDurationInSeconds?: number; // Webhook-specific field\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n gifAttribution?: number; // GIF attribution type (0=none, 1=giphy, 2=tenor, etc.) (webhook-specific)\n gifPlayback?: boolean; // Whether this video should be played as a GIF (webhook-specific)\n height: number;\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n mimetype: string; // MIME type (e.g., \"video/mp4\")\n seconds: number; // Video duration in seconds\n streamingSidecar?: string; // Streaming sidecar data for video streaming\n thumbnailDirectPath?: string; // Thumbnail direct path (webhook-specific)\n thumbnailEncSHA256?: string; // Thumbnail encrypted SHA256 (webhook-specific)\n thumbnailSHA256?: string; // Thumbnail SHA256 (webhook-specific)\n videoSourceType?: number; // Webhook-specific field\n width: number;\n}\n\nexport interface WebhookAudioMessage {\n URL?: string; // Uppercase for webhook\n contextInfo?: WebhookContextInfo;\n directPath?: string;\n fileEncSHA256?: string; // String format for webhook\n fileLength?: number;\n fileSHA256?: string; // String format for webhook\n mediaKey?: string; // String format for webhook\n mediaKeyTimestamp?: number;\n mimetype?: string;\n seconds?: number;\n ptt?: boolean; // Push to talk (voice message) - Note: payload uses uppercase \"PTT\"\n streamingSidecar?: string; // Streaming sidecar data for audio streaming (webhook-specific)\n waveform?: string; // Base64 encoded waveform for voice messages (webhook-specific)\n}\n\nexport interface WebhookDocumentMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n contactVcard: boolean; // Whether this is a contact vCard (webhook-specific field)\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileName: string; // Original file name\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n mimetype: string; // MIME type (e.g., \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", \"application/pdf\")\n pageCount?: number; // Number of pages in the document (webhook-specific field)\n title: string; // Document title (usually filename without extension)\n}\n\nexport interface WebhookContactMessage {\n contextInfo?: WebhookContextInfo;\n displayName: string; // Display name of the contact\n vcard: string; // vCard data in standard vCard format\n}\n\nexport interface WebhookPollCreationMessageV3 {\n contextInfo?: WebhookContextInfo;\n name: string; // Poll question/title\n options: Array<{\n optionHash: string; // Hash for the option\n optionName: string; // Display text for the option\n }>;\n pollContentType: number; // Type of poll content\n selectableOptionsCount: number; // Number of options that can be selected (0 = single choice, >0 = multiple choice)\n}\n\nexport interface WebhookLocationMessage {\n JPEGThumbnail?: string; // Base64 encoded JPEG thumbnail of the location (webhook-specific field)\n contextInfo?: WebhookContextInfo;\n degreesLatitude: number; // Latitude coordinate\n degreesLongitude: number; // Longitude coordinate\n}\n\nexport interface WebhookStickerMessage {\n URL: string; // Full WhatsApp media URL (uppercase for webhook)\n contextInfo?: WebhookContextInfo;\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash (string format for webhook)\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash (string format for webhook)\n firstFrameLength?: number; // First frame length for animated stickers (webhook-specific)\n firstFrameSidecar?: string; // First frame sidecar data (webhook-specific)\n height: number; // Sticker height\n isAiSticker?: boolean; // Whether this is an AI-generated sticker (webhook-specific)\n isAnimated?: boolean; // Whether this is an animated sticker (webhook-specific)\n isAvatar?: boolean; // Whether this is an avatar sticker (webhook-specific)\n isLottie?: boolean; // Whether this is a Lottie sticker (webhook-specific)\n mediaKey: string; // Media encryption key (string format for webhook)\n mediaKeyTimestamp: number; // Unix timestamp\n mimetype: string; // MIME type (typically \"image/webp\" for stickers)\n stickerSentTS?: number; // Sticker sent timestamp (webhook-specific field)\n width: number; // Sticker width\n}\n\nexport interface WebhookReactionMessage {\n key: WebhookMessageKey; // Key of the message being reacted to\n senderTimestampMS?: number; // Timestamp when reaction was sent\n text?: string; // The reaction emoji/text\n}\n\nexport interface WebhookEditedMessage {\n message?: unknown; // The edited message content\n timestampMS?: string; // Edit timestamp\n editedMessageID?: string; // ID of original message being edited\n}\n\n// Message key structure\nexport interface WebhookMessageKey {\n ID: string; // Uppercase field name for webhook (vs lowercase 'id' in message.ts)\n fromMe: boolean; // Required in webhook (vs optional in message.ts)\n participant?: string; // JID in string format\n remoteJID: string; // Uppercase JID field name for webhook (vs 'remoteJid' in message.ts)\n}\n\n// User receipt structure\nexport interface UserReceipt {\n userJID?: string;\n receiptTimestamp?: number;\n readTimestamp?: number;\n playedTimestamp?: number;\n}\n\n// Reaction structure\nexport interface WebhookReaction {\n key?: WebhookMessageKey;\n text?: string;\n senderTimestampMS?: number;\n}\n\n// Generic message wrapper for webhook payloads\nexport interface WebhookGenericMessage {\n messageContextInfo?: WebhookMessageContextInfo;\n conversation?: string; // Simple text message\n extendedTextMessage?: WebhookExtendedTextMessage;\n imageMessage?: WebhookImageMessage;\n videoMessage?: WebhookVideoMessage;\n audioMessage?: WebhookAudioMessage;\n documentMessage?: WebhookDocumentMessage;\n contactMessage?: WebhookContactMessage;\n locationMessage?: WebhookLocationMessage;\n stickerMessage?: WebhookStickerMessage;\n reactionMessage?: WebhookReactionMessage;\n editedMessage?: WebhookEditedMessage;\n\n // Interactive messages\n // TODO: define proper interfaces\n buttonsMessage?: unknown;\n listMessage?: unknown;\n templateMessage?: unknown;\n\n // Response messages\n buttonsResponseMessage?: unknown;\n listResponseMessage?: unknown;\n\n // Group messages\n groupInviteMessage?: unknown;\n\n // Poll messages\n pollCreationMessage?: unknown;\n pollCreationMessageV3?: WebhookPollCreationMessageV3;\n pollUpdateMessage?: unknown;\n\n // Special messages\n viewOnceMessage?: unknown;\n\n protocolMessage?: {\n type?: number;\n editedMessage?: WebhookGenericMessage; // Nested edited message in protocol messages\n key?: WebhookMessageKey; // Message key for protocol messages\n timestampMS?: number; // Edit timestamp\n historySyncNotification?: WebhookHistorySyncNotification;\n initialSecurityNotificationSettingSync?: {\n securityNotificationEnabled: boolean;\n };\n };\n deviceSentMessage?: {\n destinationJID: string;\n message: WebhookGenericMessage;\n };\n}\n\n// Message types enum for easier handling of different message types\nexport enum MessageType {\n TEXT = \"conversation\",\n EXTENDED_TEXT = \"extendedTextMessage\",\n IMAGE = \"imageMessage\",\n VIDEO = \"videoMessage\",\n AUDIO = \"audioMessage\",\n DOCUMENT = \"documentMessage\",\n CONTACT = \"contactMessage\",\n LOCATION = \"locationMessage\",\n STICKER = \"stickerMessage\",\n REACTION = \"reactionMessage\",\n EDITED = \"editedMessage\",\n PROTOCOL = \"protocolMessage\",\n DEVICE_SENT = \"deviceSentMessage\",\n\n // Interactive messages\n BUTTONS = \"buttonsMessage\",\n LIST = \"listMessage\",\n TEMPLATE = \"templateMessage\",\n\n // Response messages\n BUTTONS_RESPONSE = \"buttonsResponseMessage\",\n LIST_RESPONSE = \"listResponseMessage\",\n\n // Group messages\n GROUP_INVITE = \"groupInviteMessage\",\n\n // Poll messages\n POLL = \"pollCreationMessage\",\n POLL_CREATION = \"pollCreationMessageV3\",\n POLL_UPDATE = \"pollUpdateMessage\",\n\n // Special messages\n VIEW_ONCE = \"viewOnceMessage\",\n\n UNKNOWN = \"unknown\",\n}\n// History sync notification structure\nexport interface WebhookHistorySyncNotification {\n chunkOrder?: number;\n directPath: string;\n encHandle: string; // Webhook-specific field\n fileEncSHA256: string; // String format for webhook\n fileLength: number;\n fileSHA256: string; // String format for webhook\n mediaKey: string; // String format for webhook\n progress?: number;\n syncType: number;\n}\n\n// Using VerifiedName imported from user.ts (identical interface)\n\n// Specific webhook event data interfaces\n\n// QR webhook event data (based on observed webhook payload)\n// Note: For QR events, the event field is actually just the string \"code\"\n// We represent this as an empty interface since the real data is at payload level\nexport interface QRWebhookEvent {\n // The event field contains just the string \"code\"\n // The actual QR code data is in qrCodeBase64 at the payload level\n}\n\n// Connected webhook event data (based on observed webhook payload)\n// Note: For Connected events, the event field is an empty object {}\nexport interface ConnectedWebhookEvent {\n // The event field contains an empty object {}\n // No additional data is provided for Connected events\n}\n\n// ReadReceipt webhook event data (based on observed webhook payload)\n// Maps to Receipt event type but with webhook-specific structure\nexport interface ReadReceiptWebhookEvent {\n AddressingMode: string;\n BroadcastListOwner: string;\n Chat: string; // JID in string format (e.g., \"554198387899-1431900789@g.us\")\n IsFromMe: boolean;\n IsGroup: boolean;\n MessageIDs: string[];\n MessageSender: string;\n RecipientAlt: string;\n Sender: string; // JID in string format (e.g., \"554198387899@s.whatsapp.net\")\n SenderAlt: string;\n Timestamp: string; // ISO string timestamp\n Type: string; // Receipt type (e.g., \"read\")\n}\n\n// HistorySync webhook event data (based on observed webhook payload)\n// Contains different types of historical data - can be pastParticipants, statusV3Messages, conversations, etc.\nexport interface HistorySyncWebhookEvent {\n Data: {\n // Variant 1: Past participants data (groups and stickers)\n pastParticipants?: Array<{\n groupJID: string; // JID in string format (e.g., \"120363388053770128@g.us\")\n pastParticipants: Array<{\n leaveReason: number; // 0 = left voluntarily, 1 = kicked/removed\n leaveTS: number; // Unix timestamp\n userJID: string; // JID in string format\n }>;\n }>;\n recentStickers?: Array<{\n URL: string; // Full WhatsApp media URL\n directPath: string; // Direct path to media\n fileEncSHA256: string; // Encrypted file SHA256 hash\n fileLength: number; // File size in bytes\n fileSHA256: string; // File SHA256 hash\n height: number;\n isLottie: boolean; // Whether it's an animated Lottie sticker\n lastStickerSentTS: number; // Unix timestamp of last usage\n mediaKey: string; // Media encryption key\n mimetype: string; // MIME type (e.g., \"image/webp\")\n weight: number; // Usage weight/frequency\n width: number;\n }>;\n\n // Variant 2: Status messages data (stories/status updates)\n statusV3Messages?: Array<{\n key: WebhookMessageKey;\n message: WebhookGenericMessage;\n messageTimestamp: number; // Unix timestamp\n participant: string; // JID in string format\n reportingTokenInfo?: {\n reportingTag: string;\n };\n }>;\n\n // Variant 3: Conversation histories data\n conversations?: Array<{\n ID: string; // JID in string format (chat identifier)\n messages: Array<{\n message: {\n key: WebhookMessageKey;\n message: WebhookGenericMessage;\n messageTimestamp: number; // Unix timestamp\n messageC2STimestamp?: number; // Client to server timestamp\n ephemeralStartTimestamp?: number; // Ephemeral message start timestamp\n originalSelfAuthorUserJIDString?: string; // Original author for messages sent by self\n status?: number; // Message status (3=delivered, 4=read, 5=played)\n userReceipt?: UserReceipt[];\n reactions?: WebhookReaction[];\n reportingTokenInfo?: {\n reportingTag: string;\n };\n };\n msgOrderID: number; // Message order ID\n }>;\n }>;\n phoneNumberToLidMappings?: Array<{\n lidJID: string; // LID JID (e.g., \"165434221441206@lid\")\n pnJID: string; // Phone number JID (e.g., \"554199392033@s.whatsapp.net\")\n }>;\n\n // Common fields for all variants\n chunkOrder?: number; // Chunk order for paginated sync\n progress?: number; // Sync progress\n syncType: number; // Sync operation type\n };\n}\n\n// Message webhook event data (based on observed webhook payload)\n// Complex structure similar to MessageEvent in events.ts but with webhook-specific format\nexport interface MessageWebhookEvent {\n Info: {\n AddressingMode: string;\n BroadcastListOwner: string;\n Category: string;\n Chat: string; // JID in string format\n DeviceSentMeta: {\n DestinationJID: string;\n Phash: string;\n } | null;\n Edit: string;\n ID: string;\n IsFromMe: boolean;\n IsGroup: boolean;\n MediaType: string;\n MsgBotInfo: {\n EditSenderTimestampMS: string; // ISO timestamp\n EditTargetID: string;\n EditType: string;\n };\n MsgMetaInfo: {\n DeprecatedLIDSession: unknown | null;\n TargetID: string;\n TargetSender: string;\n ThreadMessageID: string;\n ThreadMessageSenderJID: string;\n };\n Multicast: boolean;\n PushName: string;\n RecipientAlt: string;\n Sender: string; // JID in string format\n SenderAlt: string;\n ServerID: number;\n Timestamp: string; // ISO string timestamp\n Type: string; // Message type (e.g., \"text\")\n VerifiedName: VerifiedName | null;\n };\n IsDocumentWithCaption: boolean;\n IsEdit: boolean;\n IsEphemeral: boolean;\n IsLottieSticker: boolean;\n IsViewOnce: boolean;\n IsViewOnceV2: boolean;\n IsViewOnceV2Extension: boolean;\n Message: WebhookGenericMessage; // Using webhook-specific message structure\n NewsletterMeta: unknown | null;\n RawMessage: WebhookGenericMessage; // Using webhook-specific message structure\n RetryCount: number;\n SourceWebMsg: unknown | null;\n UnavailableRequestID: string;\n}\n\n// Typed webhook payloads for specific events\nexport type QRWebhookPayload = AnyWebhookPayload<QRWebhookEvent> & {\n qrCodeBase64: string; // QR code as base64 data URL\n};\nexport type ConnectedWebhookPayload = AnyWebhookPayload<ConnectedWebhookEvent>;\nexport type ReadReceiptWebhookPayload =\n AnyWebhookPayload<ReadReceiptWebhookEvent>;\nexport type HistorySyncWebhookPayload =\n AnyWebhookPayload<HistorySyncWebhookEvent>;\nexport type MessageWebhookPayload = AnyWebhookPayload<MessageWebhookEvent>;\n\n// Webhook event mapping types for type-safe handling\nexport interface WebhookEventMap {\n QR: QRWebhookEvent;\n Connected: ConnectedWebhookEvent;\n ReadReceipt: ReadReceiptWebhookEvent;\n HistorySync: HistorySyncWebhookEvent;\n Message: MessageWebhookEvent;\n // Add more webhook event mappings here as they are discovered\n}\n\n// Type-safe webhook handler function type\nexport type WebhookEventHandler<T extends keyof WebhookEventMap> = (\n payload: AnyWebhookPayload<WebhookEventMap[T]>\n) => void | Promise<void>;\n\n// Union type for all specific webhook payloads\nexport type SpecificWebhookPayload =\n | QRWebhookPayload\n | ConnectedWebhookPayload\n | ReadReceiptWebhookPayload\n | HistorySyncWebhookPayload\n | MessageWebhookPayload;\n\n// Type guard to check if payload is a specific webhook event type\nexport function isWebhookEventType<T extends keyof WebhookEventMap>(\n payload: WebhookPayloadBase,\n eventType: T\n): payload is AnyWebhookPayload<WebhookEventMap[T]> {\n return payload.type === eventType;\n}\n\n// Helper type guards\nexport function hasS3Media(\n payload: WebhookPayloadBase\n): payload is S3OnlyWebhookPayload | BothMediaWebhookPayload {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return !!(payload as any).s3;\n}\n\nexport function hasBase64Media(\n payload: WebhookPayloadBase\n): payload is Base64OnlyWebhookPayload | BothMediaWebhookPayload {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return !!(payload as any).base64;\n}\n\nexport function hasBothMedia(\n payload: WebhookPayloadBase\n): payload is BothMediaWebhookPayload {\n return hasS3Media(payload) && hasBase64Media(payload);\n}\n\n// Helper type guard to check if payload has token (all webhook payloads should)\nexport function isValidWebhookPayload(\n payload: unknown\n): payload is WebhookPayloadBase {\n return (\n typeof payload === \"object\" &&\n payload !== null &&\n \"event\" in payload &&\n \"type\" in payload &&\n \"token\" in payload\n );\n}\n\n/**\n * Utility function to discover the type of a GenericMessage\n * @param message - The GenericMessage to analyze\n * @returns MessageType enum value indicating the message type\n *\n * @example\n * ```typescript\n * import { discoverMessageType, MessageType } from \"wuzapi\";\n *\n * const messageType = discoverMessageType(webhookPayload.event.Message);\n *\n * switch (messageType) {\n * case MessageType.IMAGE:\n * console.log(\"Received an image message\");\n * break;\n * case MessageType.EXTENDED_TEXT:\n * console.log(\"Received a text message\");\n * break;\n * // ... handle other types\n * }\n * ```\n */\nexport function discoverMessageType(\n message: WebhookGenericMessage\n): MessageType {\n if (!message) return MessageType.UNKNOWN;\n\n // Check for each message type in order of most common to least common\n if (message.conversation) return MessageType.TEXT;\n if (message.extendedTextMessage) return MessageType.EXTENDED_TEXT;\n if (message.imageMessage) return MessageType.IMAGE;\n if (message.videoMessage) return MessageType.VIDEO;\n if (message.audioMessage) return MessageType.AUDIO;\n if (message.documentMessage) return MessageType.DOCUMENT;\n if (message.contactMessage) return MessageType.CONTACT;\n if (message.locationMessage) return MessageType.LOCATION;\n if (message.stickerMessage) return MessageType.STICKER;\n if (message.reactionMessage) return MessageType.REACTION;\n\n // Interactive messages\n if (message.buttonsMessage) return MessageType.BUTTONS;\n if (message.listMessage) return MessageType.LIST;\n if (message.templateMessage) return MessageType.TEMPLATE;\n\n // Response messages\n if (message.buttonsResponseMessage) return MessageType.BUTTONS_RESPONSE;\n if (message.listResponseMessage) return MessageType.LIST_RESPONSE;\n\n // Group messages\n if (message.groupInviteMessage) return MessageType.GROUP_INVITE;\n\n // Poll messages\n if (message.pollCreationMessage) return MessageType.POLL;\n if (message.pollCreationMessageV3) return MessageType.POLL_CREATION;\n if (message.pollUpdateMessage) return MessageType.POLL_UPDATE;\n\n // Special messages\n if (message.viewOnceMessage) return MessageType.VIEW_ONCE;\n\n // System messages\n if (message.editedMessage) return MessageType.EDITED;\n if (message.protocolMessage) return MessageType.PROTOCOL;\n if (message.deviceSentMessage) return MessageType.DEVICE_SENT;\n\n return MessageType.UNKNOWN;\n}\n"],"names":["WebhookEventType","MessageType"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wuzapi",
3
- "version": "1.6.9",
3
+ "version": "1.7.1",
4
4
  "description": "TypeScript client library for WuzAPI WhatsApp API",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -45,6 +45,7 @@
45
45
  "url": "https://github.com/gusnips/wuzapi-node.git"
46
46
  },
47
47
  "devDependencies": {
48
+ "@types/debug": "^4.1.12",
48
49
  "@types/node": "^24.3.0",
49
50
  "@typescript-eslint/eslint-plugin": "^8.41.0",
50
51
  "@typescript-eslint/parser": "^8.41.0",
@@ -54,6 +55,7 @@
54
55
  "vite-plugin-dts": "^4.5.4"
55
56
  },
56
57
  "dependencies": {
57
- "axios": "^1.11.0"
58
+ "axios": "^1.11.0",
59
+ "debug": "^4.4.1"
58
60
  }
59
61
  }