@arcaelas/whatsapp 1.2.3 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/build/{Chat.js → cjs/Chat.js} +1 -1
  2. package/build/cjs/Chat.js.map +1 -0
  3. package/build/{Contact.js → cjs/Contact.js} +6 -5
  4. package/build/cjs/Contact.js.map +1 -0
  5. package/build/{Message.js → cjs/Message.js} +5 -3
  6. package/build/cjs/Message.js.map +1 -0
  7. package/build/{WhatsApp.js → cjs/WhatsApp.js} +11 -6
  8. package/build/cjs/WhatsApp.js.map +1 -0
  9. package/build/cjs/index.js +17 -0
  10. package/build/cjs/index.js.map +1 -0
  11. package/build/cjs/package.json +1 -0
  12. package/build/{store → cjs/store}/driver/FileEngine.d.ts +1 -1
  13. package/build/{store → cjs/store}/driver/FileEngine.js +2 -2
  14. package/build/cjs/store/driver/FileEngine.js.map +1 -0
  15. package/build/{store → cjs/store}/driver/RedisEngine.d.ts +1 -1
  16. package/build/cjs/store/driver/RedisEngine.js.map +1 -0
  17. package/build/cjs/store/engine.js.map +1 -0
  18. package/build/cjs/store/index.d.ts +8 -0
  19. package/build/{store → cjs/store}/index.js +2 -2
  20. package/build/cjs/store/index.js.map +1 -0
  21. package/build/esm/Chat.d.ts +335 -0
  22. package/build/esm/Chat.js +390 -0
  23. package/build/esm/Chat.js.map +1 -0
  24. package/build/esm/Contact.d.ts +856 -0
  25. package/build/esm/Contact.js +183 -0
  26. package/build/esm/Contact.js.map +1 -0
  27. package/build/esm/Message.d.ts +580 -0
  28. package/build/esm/Message.js +459 -0
  29. package/build/esm/Message.js.map +1 -0
  30. package/build/esm/WhatsApp.d.ts +68 -0
  31. package/build/esm/WhatsApp.js +364 -0
  32. package/build/esm/WhatsApp.js.map +1 -0
  33. package/build/esm/index.d.ts +13 -0
  34. package/build/esm/index.js +10 -0
  35. package/build/esm/index.js.map +1 -0
  36. package/build/esm/package.json +1 -0
  37. package/build/esm/store/driver/FileEngine.d.ts +23 -0
  38. package/build/esm/store/driver/FileEngine.js +86 -0
  39. package/build/esm/store/driver/FileEngine.js.map +1 -0
  40. package/build/esm/store/driver/RedisEngine.d.ts +38 -0
  41. package/build/esm/store/driver/RedisEngine.js +65 -0
  42. package/build/esm/store/driver/RedisEngine.js.map +1 -0
  43. package/build/esm/store/engine.d.ts +54 -0
  44. package/build/esm/store/engine.js +6 -0
  45. package/build/{store → esm/store}/engine.js.map +1 -1
  46. package/build/esm/store/index.d.ts +8 -0
  47. package/build/esm/store/index.js +7 -0
  48. package/build/esm/store/index.js.map +1 -0
  49. package/package.json +70 -58
  50. package/API.md +0 -776
  51. package/CHANGELOG.md +0 -53
  52. package/DOC.md +0 -532
  53. package/build/Chat.js.map +0 -1
  54. package/build/Contact.js.map +0 -1
  55. package/build/Message.js.map +0 -1
  56. package/build/WhatsApp.js.map +0 -1
  57. package/build/index.js +0 -2
  58. package/build/index.js.map +0 -7
  59. package/build/store/driver/FileEngine.js.map +0 -1
  60. package/build/store/driver/RedisEngine.js.map +0 -1
  61. package/build/store/index.d.ts +0 -8
  62. package/build/store/index.js.map +0 -1
  63. package/context7.json +0 -4
  64. package/tsconfig.json +0 -27
  65. /package/build/{Chat.d.ts → cjs/Chat.d.ts} +0 -0
  66. /package/build/{Contact.d.ts → cjs/Contact.d.ts} +0 -0
  67. /package/build/{Message.d.ts → cjs/Message.d.ts} +0 -0
  68. /package/build/{WhatsApp.d.ts → cjs/WhatsApp.d.ts} +0 -0
  69. /package/build/{index.d.ts → cjs/index.d.ts} +0 -0
  70. /package/build/{store → cjs/store}/driver/RedisEngine.js +0 -0
  71. /package/build/{store → cjs/store}/engine.d.ts +0 -0
  72. /package/build/{store → cjs/store}/engine.js +0 -0
@@ -0,0 +1,364 @@
1
+ /**
2
+ * @file WhatsApp.ts
3
+ * @description Clase principal que gestiona la conexión y eventos de WhatsApp
4
+ */
5
+ import { Browsers, BufferJSON, DisconnectReason, downloadMediaMessage, fetchLatestBaileysVersion, getContentType, initAuthCreds, makeWASocket, proto, } from 'baileys';
6
+ import { EventEmitter } from 'node:events';
7
+ import pino from 'pino';
8
+ import * as QRCode from 'qrcode';
9
+ import { build_chat, chat } from './Chat';
10
+ import { build_contact, contact } from './Contact';
11
+ import { build_message_index, message } from './Message';
12
+ import { FileEngine } from './store';
13
+ /**
14
+ * @description
15
+ * Clase principal para gestionar la conexión con WhatsApp.
16
+ *
17
+ * @example
18
+ * const { event, pair, Contact, Chat, Message } = new WhatsApp({ phone: '5491112345678' });
19
+ * event.on('open', () => console.log('Conectado'));
20
+ * await pair((code) => console.log('Código:', code));
21
+ */
22
+ export class WhatsApp {
23
+ constructor(options = {}) {
24
+ this._socket = null;
25
+ /**
26
+ * @description Conecta a WhatsApp.
27
+ * - Con phone: callback recibe código de 8 dígitos (una vez)
28
+ * - Sin phone: callback recibe QR como Buffer PNG (periódicamente)
29
+ * @param callback Función que recibe el código o QR.
30
+ */
31
+ this.pair = async (callback) => {
32
+ const { version } = await fetchLatestBaileysVersion();
33
+ const stored = await this.engine.get('session/creds');
34
+ const creds = stored ? JSON.parse(stored, BufferJSON.reviver) : initAuthCreds();
35
+ let code_sent = false;
36
+ const connect = async () => {
37
+ this._socket = makeWASocket({
38
+ version,
39
+ auth: {
40
+ creds,
41
+ keys: {
42
+ get: async (type, ids) => {
43
+ const data = {};
44
+ for (const id of ids) {
45
+ const stored = await this.engine.get(`session/${type}/${id}`);
46
+ if (stored) {
47
+ let value = JSON.parse(stored, BufferJSON.reviver);
48
+ if (type === 'app-state-sync-key')
49
+ value = proto.Message.AppStateSyncKeyData.fromObject(value);
50
+ data[id] = value;
51
+ }
52
+ }
53
+ return data;
54
+ },
55
+ set: async (data) => {
56
+ for (const category in data) {
57
+ for (const id in data[category]) {
58
+ const value = data[category][id];
59
+ await this.engine.set(`session/${category}/${id}`, value ? JSON.stringify(value, BufferJSON.replacer) : null);
60
+ }
61
+ }
62
+ },
63
+ },
64
+ },
65
+ browser: Browsers.windows('Chrome'),
66
+ printQRInTerminal: false,
67
+ logger: pino({ level: 'silent' }),
68
+ syncFullHistory: false,
69
+ markOnlineOnConnect: false,
70
+ });
71
+ const socket = this._socket;
72
+ socket.ev.on('creds.update', () => this.engine.set('session/creds', JSON.stringify(creds, BufferJSON.replacer)));
73
+ socket.ev.on('connection.update', async (update) => {
74
+ const { connection, lastDisconnect, qr } = update;
75
+ if (qr && !creds.registered) {
76
+ if (this._phone && !code_sent) {
77
+ code_sent = true;
78
+ await callback(await socket.requestPairingCode(this._phone));
79
+ }
80
+ else if (!this._phone) {
81
+ await callback(await QRCode.toBuffer(qr, { type: 'png', margin: 2 }));
82
+ }
83
+ }
84
+ if (connection === 'open') {
85
+ this.event.emit('open');
86
+ }
87
+ else if (connection === 'close') {
88
+ this._socket = null;
89
+ if (lastDisconnect?.error?.output?.statusCode === DisconnectReason.loggedOut) {
90
+ this.event.emit('error', new Error('Logged out'));
91
+ return;
92
+ }
93
+ this.event.emit('close');
94
+ setTimeout(connect, 3000);
95
+ }
96
+ });
97
+ // ═══════════════════════════════════════════════════════════════════
98
+ // CONTACTS
99
+ // ═══════════════════════════════════════════════════════════════════
100
+ socket.ev.on('contacts.upsert', async (contacts) => {
101
+ for (const c of contacts) {
102
+ if (!c.id)
103
+ continue;
104
+ const existing = await this.engine.get(`contact/${c.id}/index`);
105
+ const raw = {
106
+ id: c.id,
107
+ lid: c.lid ?? null,
108
+ name: c.name ?? null,
109
+ notify: c.notify ?? null,
110
+ verifiedName: c.verifiedName ?? null,
111
+ imgUrl: c.imgUrl ?? null,
112
+ status: c.status ?? null,
113
+ };
114
+ const data = build_contact(raw);
115
+ await this.engine.set(`contact/${c.id}/index`, JSON.stringify(data, BufferJSON.replacer));
116
+ this.event.emit(existing ? 'contact:updated' : 'contact:created', new this.Contact(data));
117
+ }
118
+ });
119
+ socket.ev.on('contacts.update', async (contacts) => {
120
+ for (const c of contacts) {
121
+ if (!c.id)
122
+ continue;
123
+ const stored = await this.engine.get(`contact/${c.id}/index`);
124
+ if (!stored)
125
+ continue;
126
+ const data = JSON.parse(stored, BufferJSON.reviver);
127
+ if (c.notify)
128
+ data.raw.notify = c.notify;
129
+ if (c.name)
130
+ data.raw.name = c.name;
131
+ if (c.imgUrl)
132
+ data.raw.imgUrl = c.imgUrl;
133
+ if (c.status)
134
+ data.raw.status = c.status;
135
+ data.name = data.raw.name ?? data.raw.notify ?? data.raw.id.split('@')[0];
136
+ data.photo = data.raw.imgUrl ?? null;
137
+ data.content = data.raw.status ?? '';
138
+ await this.engine.set(`contact/${c.id}/index`, JSON.stringify(data, BufferJSON.replacer));
139
+ this.event.emit('contact:updated', new this.Contact(data));
140
+ }
141
+ });
142
+ // ═══════════════════════════════════════════════════════════════════
143
+ // CHATS
144
+ // ═══════════════════════════════════════════════════════════════════
145
+ socket.ev.on('chats.upsert', async (chats) => {
146
+ for (const ch of chats) {
147
+ const existing = await this.engine.get(`chat/${ch.id}/index`);
148
+ const raw = existing
149
+ ? JSON.parse(existing, BufferJSON.reviver).raw
150
+ : {
151
+ id: ch.id,
152
+ name: ch.name ?? null,
153
+ archived: ch.archived ?? null,
154
+ pinned: ch.pinned ?? null,
155
+ muteEndTime: ch.muteEndTime ?? null,
156
+ unreadCount: ch.unreadCount ?? null,
157
+ readOnly: ch.readOnly ?? null,
158
+ };
159
+ if (ch.name)
160
+ raw.name = ch.name;
161
+ const data = build_chat(raw);
162
+ await this.engine.set(`chat/${ch.id}/index`, JSON.stringify(data, BufferJSON.replacer));
163
+ this.event.emit(existing ? 'chat:updated' : 'chat:created', new this.Chat(data));
164
+ }
165
+ });
166
+ socket.ev.on('chats.update', async (chats) => {
167
+ for (const ch of chats) {
168
+ if (!ch.id)
169
+ continue;
170
+ const stored = await this.engine.get(`chat/${ch.id}/index`);
171
+ const data = stored ? JSON.parse(stored, BufferJSON.reviver) : build_chat({ id: ch.id, name: ch.name ?? null });
172
+ if (ch.name !== undefined) {
173
+ data.raw.name = ch.name ?? data.raw.name;
174
+ data.name = data.raw.name ?? data.raw.displayName ?? ch.id.split('@')[0];
175
+ }
176
+ let has_specific_event = false;
177
+ // Pin
178
+ if ('pinned' in ch) {
179
+ data.raw.pinned = ch.pinned ?? null;
180
+ data.pined = data.raw.pinned !== null;
181
+ this.event.emit('chat:pined', ch.id, data.raw.pinned);
182
+ has_specific_event = true;
183
+ }
184
+ // Archive
185
+ if (ch.archived !== undefined) {
186
+ data.raw.archived = ch.archived ?? false;
187
+ data.archived = data.raw.archived;
188
+ this.event.emit('chat:archived', ch.id, data.archived);
189
+ has_specific_event = true;
190
+ }
191
+ // Mute
192
+ if ('muteEndTime' in ch) {
193
+ data.raw.muteEndTime = ch.muteEndTime ?? null;
194
+ data.muted = data.raw.muteEndTime ?? false;
195
+ this.event.emit('chat:muted', ch.id, data.raw.muteEndTime);
196
+ has_specific_event = true;
197
+ }
198
+ // UnreadCount
199
+ if (ch.unreadCount !== undefined) {
200
+ data.raw.unreadCount = ch.unreadCount;
201
+ data.readed = (data.raw.unreadCount === 0 || data.raw.unreadCount === null) && !data.raw.markedAsUnread;
202
+ }
203
+ await this.engine.set(`chat/${ch.id}/index`, JSON.stringify(data, BufferJSON.replacer));
204
+ if (!has_specific_event) {
205
+ this.event.emit(stored ? 'chat:updated' : 'chat:created', new this.Chat(data));
206
+ }
207
+ }
208
+ });
209
+ socket.ev.on('chats.delete', async (ids) => {
210
+ for (const cid of ids) {
211
+ await this.Chat.cascade_delete(cid);
212
+ this.event.emit('chat:deleted', cid);
213
+ }
214
+ });
215
+ // ═══════════════════════════════════════════════════════════════════
216
+ // MESSAGES
217
+ // ═══════════════════════════════════════════════════════════════════
218
+ socket.ev.on('messages.upsert', async ({ messages }) => {
219
+ for (const msg of messages) {
220
+ if (!msg.key.remoteJid || !msg.key.id)
221
+ continue;
222
+ const cid = msg.key.remoteJid;
223
+ const mid = msg.key.id;
224
+ const content_type = getContentType(msg.message ?? {});
225
+ // Ignorar reacciones y votos de encuesta (tienen sus propios eventos)
226
+ if (content_type === 'reactionMessage' || content_type === 'pollUpdateMessage')
227
+ continue;
228
+ // ─────────────────────────────────────────────────────────────
229
+ // PROTOCOL MESSAGE (ediciones y eliminaciones)
230
+ // ─────────────────────────────────────────────────────────────
231
+ if (content_type === 'protocolMessage') {
232
+ const protocol = msg.message?.protocolMessage;
233
+ if (!protocol?.key?.id)
234
+ continue;
235
+ const target_mid = protocol.key.id;
236
+ const target_cid = protocol.key.remoteJid ?? cid;
237
+ // MESSAGE_EDIT: Merge selectivo - reemplazar solo message
238
+ if (protocol.type === proto.Message.ProtocolMessage.Type.MESSAGE_EDIT) {
239
+ const edited_msg = protocol.editedMessage;
240
+ if (!edited_msg)
241
+ continue;
242
+ // Obtener index y raw
243
+ const stored_index = await this.engine.get(`chat/${target_cid}/message/${target_mid}/index`);
244
+ const stored_raw = await this.engine.get(`chat/${target_cid}/message/${target_mid}/raw`);
245
+ if (!stored_index || !stored_raw)
246
+ continue;
247
+ const index = JSON.parse(stored_index, BufferJSON.reviver);
248
+ const raw = JSON.parse(stored_raw, BufferJSON.reviver);
249
+ raw.message = edited_msg;
250
+ index.edited = true;
251
+ index.caption = build_message_index(raw).caption;
252
+ await this.engine.set(`chat/${target_cid}/message/${target_mid}/index`, JSON.stringify(index, BufferJSON.replacer));
253
+ await this.engine.set(`chat/${target_cid}/message/${target_mid}/raw`, JSON.stringify(raw, BufferJSON.replacer));
254
+ const instance = new this.Message({ index, raw });
255
+ this.Message.notify(target_cid, target_mid);
256
+ this.event.emit('message:updated', instance);
257
+ continue;
258
+ }
259
+ // REVOKE: Eliminar del engine
260
+ if (protocol.type === proto.Message.ProtocolMessage.Type.REVOKE) {
261
+ // Eliminar del índice del chat
262
+ await this.Chat.remove_message(target_cid, target_mid);
263
+ // Eliminar archivos
264
+ await this.engine.set(`chat/${target_cid}/message/${target_mid}/index`, null);
265
+ await this.engine.set(`chat/${target_cid}/message/${target_mid}/content`, null);
266
+ await this.engine.set(`chat/${target_cid}/message/${target_mid}/raw`, null);
267
+ this.event.emit('message:deleted', target_cid, target_mid);
268
+ }
269
+ continue;
270
+ }
271
+ // ─────────────────────────────────────────────────────────────
272
+ // MENSAJE NUEVO
273
+ // ─────────────────────────────────────────────────────────────
274
+ // Construir index desde raw y guardar
275
+ const index = build_message_index(msg);
276
+ await this.engine.set(`chat/${cid}/message/${mid}/index`, JSON.stringify(index, BufferJSON.replacer));
277
+ await this.engine.set(`chat/${cid}/message/${mid}/raw`, JSON.stringify(msg, BufferJSON.replacer));
278
+ // Extraer content inline según tipo
279
+ let content = Buffer.alloc(0);
280
+ if (index.type === 'text') {
281
+ const raw_content = msg.message?.[content_type];
282
+ content = Buffer.from(typeof raw_content === 'string' ? raw_content : raw_content?.text ?? raw_content?.caption ?? '', 'utf-8');
283
+ }
284
+ else if (index.type === 'location') {
285
+ const loc = msg.message?.locationMessage ?? msg.message?.liveLocationMessage;
286
+ content = Buffer.from(JSON.stringify({ lat: loc?.degreesLatitude, lng: loc?.degreesLongitude }), 'utf-8');
287
+ }
288
+ else if (index.type === 'poll') {
289
+ const poll = msg.message?.pollCreationMessage ?? msg.message?.pollCreationMessageV2 ?? msg.message?.pollCreationMessageV3;
290
+ content = Buffer.from(JSON.stringify({ content: poll?.name ?? '', options: poll?.options?.map((o) => ({ content: o.optionName })) ?? [] }), 'utf-8');
291
+ }
292
+ else if (['image', 'video', 'audio'].includes(index.type) && this._socket) {
293
+ try {
294
+ const buffer = await downloadMediaMessage(msg, 'buffer', {});
295
+ if (Buffer.isBuffer(buffer))
296
+ content = buffer;
297
+ }
298
+ catch { /* media download may fail */ }
299
+ }
300
+ if (content.length) {
301
+ await this.engine.set(`chat/${cid}/message/${mid}/content`, content.toString('base64'));
302
+ }
303
+ // Agregar al índice del chat y emitir
304
+ await this.Chat.add_message(cid, mid, index.created_at);
305
+ const instance = new this.Message({ index, raw: msg });
306
+ if (content.length)
307
+ instance.content = async () => content;
308
+ this.Message.notify(cid, mid);
309
+ this.event.emit('message:created', instance);
310
+ }
311
+ });
312
+ socket.ev.on('messages.update', async (updates) => {
313
+ for (const { key, update } of updates) {
314
+ if (!key.remoteJid || !key.id)
315
+ continue;
316
+ const stored_index = await this.engine.get(`chat/${key.remoteJid}/message/${key.id}/index`);
317
+ const stored_raw = await this.engine.get(`chat/${key.remoteJid}/message/${key.id}/raw`);
318
+ if (!stored_index)
319
+ continue;
320
+ const index = JSON.parse(stored_index, BufferJSON.reviver);
321
+ const raw = stored_raw ? JSON.parse(stored_raw, BufferJSON.reviver) : { key };
322
+ // Edición via messages.update
323
+ if (update.message?.editedMessage?.message) {
324
+ raw.message = update.message.editedMessage.message;
325
+ index.edited = true;
326
+ index.caption = build_message_index(raw).caption;
327
+ await this.engine.set(`chat/${key.remoteJid}/message/${key.id}/index`, JSON.stringify(index, BufferJSON.replacer));
328
+ await this.engine.set(`chat/${key.remoteJid}/message/${key.id}/raw`, JSON.stringify(raw, BufferJSON.replacer));
329
+ const instance = new this.Message({ index, raw });
330
+ this.Message.notify(key.remoteJid, key.id);
331
+ this.event.emit('message:updated', instance);
332
+ continue;
333
+ }
334
+ // Status update
335
+ if (update.status !== undefined) {
336
+ raw.status = update.status;
337
+ index.status = raw.status;
338
+ await this.engine.set(`chat/${key.remoteJid}/message/${key.id}/index`, JSON.stringify(index, BufferJSON.replacer));
339
+ await this.engine.set(`chat/${key.remoteJid}/message/${key.id}/raw`, JSON.stringify(raw, BufferJSON.replacer));
340
+ }
341
+ }
342
+ });
343
+ socket.ev.on('messages.reaction', async (reactions) => {
344
+ for (const { key, reaction } of reactions) {
345
+ if (key.remoteJid && key.id)
346
+ this.event.emit('message:reacted', key.remoteJid, key.id, reaction.text ?? '');
347
+ }
348
+ });
349
+ };
350
+ await connect();
351
+ };
352
+ this._phone = options.phone?.toString();
353
+ this.engine = options.engine ?? new FileEngine(this._phone ? `.baileys/${this._phone}` : '.baileys/default');
354
+ this.event = new EventEmitter();
355
+ this.Contact = contact(this);
356
+ this.Chat = chat(this);
357
+ this.Message = message(this);
358
+ }
359
+ /** @description Retorna el socket de Baileys (null si no está conectado). */
360
+ get socket() {
361
+ return this._socket;
362
+ }
363
+ }
364
+ //# sourceMappingURL=WhatsApp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WhatsApp.js","sourceRoot":"","sources":["../../src/WhatsApp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @file index.ts
3
+ * @description Punto de entrada público de la librería @arcaelas/whatsapp
4
+ */
5
+ export { MESSAGE_STATUS } from './Message';
6
+ export type { LocationOptions, MessageType, PollOptions } from './Message';
7
+ export type { Engine } from './store';
8
+ export type { IChat, IChatRaw, IGroupParticipant } from './Chat';
9
+ export type { IContact, IContactRaw } from './Contact';
10
+ export type { IMessage, IMessageIndex } from './Message';
11
+ export type { IWhatsApp } from './WhatsApp';
12
+ export { FileEngine, RedisEngine } from './store';
13
+ export { WhatsApp } from './WhatsApp';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @file index.ts
3
+ * @description Punto de entrada público de la librería @arcaelas/whatsapp
4
+ */
5
+ // Enums
6
+ export { MESSAGE_STATUS } from './Message';
7
+ // Classes
8
+ export { FileEngine, RedisEngine } from './store';
9
+ export { WhatsApp } from './WhatsApp';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,QAAQ;AACR,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAY3C,UAAU;AACV,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @file store/driver/FileEngine.ts
3
+ * @description Engine de persistencia en sistema de archivos local
4
+ */
5
+ import type { Engine } from '../../store/engine';
6
+ /**
7
+ * @description
8
+ * Engine de persistencia en sistema de archivos.
9
+ * Almacena texto plano (JSON stringified).
10
+ *
11
+ * @example
12
+ * const engine = new FileEngine('.baileys/5491112345678');
13
+ * await engine.set('contact/123', '{"name":"John"}');
14
+ * const data = await engine.get('contact/123');
15
+ */
16
+ export declare class FileEngine implements Engine {
17
+ private readonly _base;
18
+ constructor(_base?: string);
19
+ get(key: string): Promise<string | null>;
20
+ set(key: string, value: string | null): Promise<void>;
21
+ list(prefix: string, offset?: number, limit?: number, suffix?: string): Promise<string[]>;
22
+ delete_prefix(prefix: string): Promise<number>;
23
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @file store/driver/FileEngine.ts
3
+ * @description Engine de persistencia en sistema de archivos local
4
+ */
5
+ import { mkdir, readdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
6
+ import { dirname, join } from 'node:path';
7
+ /**
8
+ * @description
9
+ * Engine de persistencia en sistema de archivos.
10
+ * Almacena texto plano (JSON stringified).
11
+ *
12
+ * @example
13
+ * const engine = new FileEngine('.baileys/5491112345678');
14
+ * await engine.set('contact/123', '{"name":"John"}');
15
+ * const data = await engine.get('contact/123');
16
+ */
17
+ export class FileEngine {
18
+ constructor(_base = '.baileys/default') {
19
+ this._base = _base;
20
+ }
21
+ async get(key) {
22
+ try {
23
+ return await readFile(join(this._base, key.replace(/@/g, '_at_')), 'utf-8');
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
29
+ async set(key, value) {
30
+ const path = join(this._base, key.replace(/@/g, '_at_'));
31
+ if (value) {
32
+ await mkdir(dirname(path), { recursive: true });
33
+ await writeFile(path, value, 'utf-8');
34
+ }
35
+ else {
36
+ try {
37
+ await rm(path, { force: true });
38
+ }
39
+ catch { /* file may already be deleted */ }
40
+ }
41
+ }
42
+ async list(prefix, offset = 0, limit = 50, suffix) {
43
+ const base = join(this._base, prefix.replace(/@/g, '_at_'));
44
+ const suffix_escaped = suffix?.replace(/@/g, '_at_');
45
+ try {
46
+ const items = [];
47
+ const entries = await readdir(base, { withFileTypes: true, recursive: true });
48
+ for (const file of entries) {
49
+ if (!file.isFile())
50
+ continue;
51
+ // Compatibilidad Node < 20: parentPath puede no existir
52
+ const parent = file.parentPath || file.path || base;
53
+ const path = join(parent, file.name);
54
+ // Filtrar por sufijo ANTES de stat() para mejor performance
55
+ if (suffix_escaped && !path.endsWith(suffix_escaped))
56
+ continue;
57
+ try {
58
+ items.push({
59
+ key: path.slice(this._base.length + 1).replace(/_at_/g, '@'),
60
+ mtime: (await stat(path)).mtimeMs,
61
+ });
62
+ }
63
+ catch { /* stat may fail for transient files */ }
64
+ }
65
+ return items
66
+ .sort((a, b) => b.mtime - a.mtime)
67
+ .slice(offset, offset + limit)
68
+ .map((f) => f.key);
69
+ }
70
+ catch {
71
+ return [];
72
+ }
73
+ }
74
+ async delete_prefix(prefix) {
75
+ const base = join(this._base, prefix.replace(/@/g, '_at_'));
76
+ try {
77
+ await rm(base, { recursive: true, force: true });
78
+ // Contar archivos eliminados no es posible con rm -rf, estimamos
79
+ return 1;
80
+ }
81
+ catch {
82
+ return 0;
83
+ }
84
+ }
85
+ }
86
+ //# sourceMappingURL=FileEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileEngine.js","sourceRoot":"","sources":["../../../../src/store/driver/FileEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @file store/driver/RedisEngine.ts
3
+ * @description Engine de persistencia con Redis
4
+ */
5
+ import type { Engine } from '../../store/engine';
6
+ /**
7
+ * @description Interface mínima del cliente Redis (compatible con ioredis y redis).
8
+ */
9
+ export interface RedisClient {
10
+ get(key: string): Promise<string | null>;
11
+ set(key: string, value: string): Promise<unknown>;
12
+ del(key: string): Promise<unknown>;
13
+ scan(cursor: number | string, ...args: unknown[]): Promise<[string, string[]]>;
14
+ }
15
+ /**
16
+ * @description
17
+ * Engine de persistencia con Redis.
18
+ * Recibe una conexión existente de ioredis o redis.
19
+ *
20
+ * @example
21
+ * import Redis from 'ioredis';
22
+ * const client = new Redis();
23
+ * const engine = new RedisEngine(client, 'wa:5491112345678');
24
+ * await engine.set('contact/123', '{"name":"John"}');
25
+ */
26
+ export declare class RedisEngine implements Engine {
27
+ private readonly _client;
28
+ private readonly _prefix;
29
+ constructor(_client: RedisClient, _prefix?: string);
30
+ get(key: string): Promise<string | null>;
31
+ set(key: string, value: string | null): Promise<void>;
32
+ /**
33
+ * @description Lista keys bajo un prefijo.
34
+ * @note Redis SCAN no garantiza orden. Los resultados no están ordenados por timestamp.
35
+ */
36
+ list(prefix: string, offset?: number, limit?: number, suffix?: string): Promise<string[]>;
37
+ delete_prefix(prefix: string): Promise<number>;
38
+ }