wa-multi-mongodb 3.8.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/LICENSE +21 -0
- package/dist/Defaults/index.d.ts +21 -0
- package/dist/Defaults/index.d.ts.map +1 -0
- package/dist/Defaults/index.js +31 -0
- package/dist/Error/index.d.ts +5 -0
- package/dist/Error/index.d.ts.map +1 -0
- package/dist/Error/index.js +14 -0
- package/dist/Messaging/index.d.ts +25 -0
- package/dist/Messaging/index.d.ts.map +1 -0
- package/dist/Messaging/index.js +335 -0
- package/dist/Profile/index.d.ts +9 -0
- package/dist/Profile/index.d.ts.map +1 -0
- package/dist/Profile/index.js +34 -0
- package/dist/Socket/index.d.ts +68 -0
- package/dist/Socket/index.d.ts.map +1 -0
- package/dist/Socket/index.js +527 -0
- package/dist/Types/index.d.ts +70 -0
- package/dist/Types/index.d.ts.map +1 -0
- package/dist/Types/index.js +2 -0
- package/dist/Types/profile.d.ts +5 -0
- package/dist/Types/profile.d.ts.map +1 -0
- package/dist/Types/profile.js +2 -0
- package/dist/Utils/create-delay.d.ts +17 -0
- package/dist/Utils/create-delay.d.ts.map +1 -0
- package/dist/Utils/create-delay.js +38 -0
- package/dist/Utils/error.d.ts +4 -0
- package/dist/Utils/error.d.ts.map +1 -0
- package/dist/Utils/error.js +8 -0
- package/dist/Utils/index.d.ts +4 -0
- package/dist/Utils/index.d.ts.map +1 -0
- package/dist/Utils/index.js +21 -0
- package/dist/Utils/is-exist.d.ts +6 -0
- package/dist/Utils/is-exist.d.ts.map +1 -0
- package/dist/Utils/is-exist.js +53 -0
- package/dist/Utils/message-status.d.ts +4 -0
- package/dist/Utils/message-status.d.ts.map +1 -0
- package/dist/Utils/message-status.js +18 -0
- package/dist/Utils/mongo-auth-state.d.ts +15 -0
- package/dist/Utils/mongo-auth-state.d.ts.map +1 -0
- package/dist/Utils/mongo-auth-state.js +109 -0
- package/dist/Utils/phone-to-jid.d.ts +5 -0
- package/dist/Utils/phone-to-jid.d.ts.map +1 -0
- package/dist/Utils/phone-to-jid.js +30 -0
- package/dist/Utils/save-media.d.ts +6 -0
- package/dist/Utils/save-media.d.ts.map +1 -0
- package/dist/Utils/save-media.js +55 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/package.json +37 -0
- package/readme.md +423 -0
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.reconnect = exports.setCredentialsDir = exports.setMongoDBNames = exports.loadSessionsFromMongo = exports.onPairingCode = exports.onMessageUpdate = exports.onConnecting = exports.onDisconnected = exports.onConnected = exports.onQRUpdated = exports.onMessageReceived = exports.loadSessionsFromStorage = exports.getSession = exports.getAllSessionSync = exports.getAllSession = exports.deleteSession = exports.startWhatsapp = exports.startSessionWithPairingCode = exports.startSession = exports.setMongoURI = void 0;
|
|
49
|
+
exports.setMongoCollection = setMongoCollection;
|
|
50
|
+
const baileys_1 = __importStar(require("baileys"));
|
|
51
|
+
const path_1 = __importDefault(require("path"));
|
|
52
|
+
const fs_1 = __importDefault(require("fs"));
|
|
53
|
+
const Defaults_1 = require("../Defaults");
|
|
54
|
+
const save_media_1 = require("../Utils/save-media");
|
|
55
|
+
const Error_1 = require("../Error");
|
|
56
|
+
const message_status_1 = require("../Utils/message-status");
|
|
57
|
+
const mongodb_1 = require("mongodb");
|
|
58
|
+
const mongo_auth_state_1 = require("../Utils/mongo-auth-state");
|
|
59
|
+
const create_delay_1 = require("../Utils/create-delay");
|
|
60
|
+
const sessions = new Map();
|
|
61
|
+
const callback = new Map();
|
|
62
|
+
const retryCount = new Map();
|
|
63
|
+
const P = require("pino")({
|
|
64
|
+
level: "silent",
|
|
65
|
+
});
|
|
66
|
+
// Tambahkan variabel global untuk koneksi MongoDB dan collection
|
|
67
|
+
let mongoClient;
|
|
68
|
+
let authCollection = null;
|
|
69
|
+
let mongoURI = process.env.MONGODB_URI || "mongodb://localhost:27017";
|
|
70
|
+
/**
|
|
71
|
+
* Set MongoDB URI for connection
|
|
72
|
+
* This function will be used to configure MongoDB connection with just the URI
|
|
73
|
+
*
|
|
74
|
+
* @param uri MongoDB connection URI
|
|
75
|
+
*/
|
|
76
|
+
const setMongoURI = (uri) => __awaiter(void 0, void 0, void 0, function* () {
|
|
77
|
+
mongoURI = uri;
|
|
78
|
+
// Reset MongoDB client and collection to ensure they are recreated with new URI
|
|
79
|
+
if (mongoClient) {
|
|
80
|
+
try {
|
|
81
|
+
yield mongoClient.close();
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
console.error("Error closing existing MongoDB connection:", error);
|
|
85
|
+
}
|
|
86
|
+
mongoClient = undefined;
|
|
87
|
+
authCollection = null;
|
|
88
|
+
}
|
|
89
|
+
console.log("MongoDB URI configured successfully");
|
|
90
|
+
});
|
|
91
|
+
exports.setMongoURI = setMongoURI;
|
|
92
|
+
function setMongoCollection(collection) {
|
|
93
|
+
authCollection = collection;
|
|
94
|
+
}
|
|
95
|
+
function initMongo() {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
+
if (!authCollection) {
|
|
98
|
+
if (!mongoClient) {
|
|
99
|
+
mongoClient = new mongodb_1.MongoClient(mongoURI);
|
|
100
|
+
yield mongoClient.connect();
|
|
101
|
+
}
|
|
102
|
+
// Gunakan variabel dari CREDENTIALS
|
|
103
|
+
const dbName = Defaults_1.CREDENTIALS.MONGO_DB_NAME;
|
|
104
|
+
const collectionName = Defaults_1.CREDENTIALS.MONGO_COLLECTION_NAME;
|
|
105
|
+
authCollection = mongoClient.db(dbName).collection(collectionName);
|
|
106
|
+
// console.log(`MongoDB initialized with database "${dbName}" and collection "${collectionName}"`);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const startSession = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (sessionId = "mysession", options = { printQR: true }) {
|
|
111
|
+
if (isSessionExistAndRunning(sessionId))
|
|
112
|
+
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionAlreadyExist(sessionId));
|
|
113
|
+
yield initMongo();
|
|
114
|
+
const { version } = yield (0, baileys_1.fetchLatestBaileysVersion)();
|
|
115
|
+
const startSocket = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
116
|
+
const { state, saveCreds } = yield (0, mongo_auth_state_1.useMongoAuthState)(sessionId, authCollection);
|
|
117
|
+
const sock = (0, baileys_1.default)({
|
|
118
|
+
version,
|
|
119
|
+
printQRInTerminal: options.printQR,
|
|
120
|
+
auth: state,
|
|
121
|
+
logger: P,
|
|
122
|
+
markOnlineOnConnect: false,
|
|
123
|
+
browser: baileys_1.Browsers.ubuntu("Chrome"),
|
|
124
|
+
});
|
|
125
|
+
sessions.set(sessionId, Object.assign({}, sock));
|
|
126
|
+
try {
|
|
127
|
+
sock.ev.process((events) => __awaiter(void 0, void 0, void 0, function* () {
|
|
128
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
129
|
+
if (events["connection.update"]) {
|
|
130
|
+
const update = events["connection.update"];
|
|
131
|
+
const { connection, lastDisconnect } = update;
|
|
132
|
+
if (update.qr) {
|
|
133
|
+
(_a = callback.get(Defaults_1.CALLBACK_KEY.ON_QR)) === null || _a === void 0 ? void 0 : _a({
|
|
134
|
+
sessionId,
|
|
135
|
+
qr: update.qr,
|
|
136
|
+
});
|
|
137
|
+
(_b = options.onQRUpdated) === null || _b === void 0 ? void 0 : _b.call(options, update.qr);
|
|
138
|
+
}
|
|
139
|
+
if (connection == "connecting") {
|
|
140
|
+
(_c = callback.get(Defaults_1.CALLBACK_KEY.ON_CONNECTING)) === null || _c === void 0 ? void 0 : _c(sessionId);
|
|
141
|
+
(_d = options.onConnecting) === null || _d === void 0 ? void 0 : _d.call(options);
|
|
142
|
+
}
|
|
143
|
+
if (connection === "close") {
|
|
144
|
+
const code = (_f = (_e = lastDisconnect === null || lastDisconnect === void 0 ? void 0 : lastDisconnect.error) === null || _e === void 0 ? void 0 : _e.output) === null || _f === void 0 ? void 0 : _f.statusCode;
|
|
145
|
+
let retryAttempt = (_g = retryCount.get(sessionId)) !== null && _g !== void 0 ? _g : 0;
|
|
146
|
+
let shouldRetry;
|
|
147
|
+
if (code != baileys_1.DisconnectReason.loggedOut && retryAttempt < 10) {
|
|
148
|
+
shouldRetry = true;
|
|
149
|
+
}
|
|
150
|
+
if (shouldRetry) {
|
|
151
|
+
retryAttempt++;
|
|
152
|
+
retryCount.set(sessionId, retryAttempt);
|
|
153
|
+
startSocket();
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
retryCount.delete(sessionId);
|
|
157
|
+
(0, exports.deleteSession)(sessionId);
|
|
158
|
+
(_h = callback.get(Defaults_1.CALLBACK_KEY.ON_DISCONNECTED)) === null || _h === void 0 ? void 0 : _h(sessionId);
|
|
159
|
+
(_j = options.onDisconnected) === null || _j === void 0 ? void 0 : _j.call(options);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (connection == "open") {
|
|
163
|
+
retryCount.delete(sessionId);
|
|
164
|
+
(_k = callback.get(Defaults_1.CALLBACK_KEY.ON_CONNECTED)) === null || _k === void 0 ? void 0 : _k(sessionId);
|
|
165
|
+
(_l = options.onConnected) === null || _l === void 0 ? void 0 : _l.call(options);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (events["creds.update"]) {
|
|
169
|
+
yield saveCreds();
|
|
170
|
+
}
|
|
171
|
+
if (events["messages.update"]) {
|
|
172
|
+
const msg = events["messages.update"][0];
|
|
173
|
+
const data = Object.assign({ sessionId: sessionId, messageStatus: (0, message_status_1.parseMessageStatusCodeToReadable)(msg.update.status) }, msg);
|
|
174
|
+
(_m = callback.get(Defaults_1.CALLBACK_KEY.ON_MESSAGE_UPDATED)) === null || _m === void 0 ? void 0 : _m(sessionId, data);
|
|
175
|
+
(_o = options.onMessageUpdated) === null || _o === void 0 ? void 0 : _o.call(options, data);
|
|
176
|
+
}
|
|
177
|
+
if (events["messages.upsert"]) {
|
|
178
|
+
const msg = (_p = events["messages.upsert"]
|
|
179
|
+
.messages) === null || _p === void 0 ? void 0 : _p[0];
|
|
180
|
+
msg.sessionId = sessionId;
|
|
181
|
+
msg.saveImage = (path) => (0, save_media_1.saveImageHandler)(msg, path);
|
|
182
|
+
msg.saveVideo = (path) => (0, save_media_1.saveVideoHandler)(msg, path);
|
|
183
|
+
msg.saveDocument = (path) => (0, save_media_1.saveDocumentHandler)(msg, path);
|
|
184
|
+
msg.saveAudio = (path) => (0, save_media_1.saveAudioHandler)(msg, path);
|
|
185
|
+
(_q = callback.get(Defaults_1.CALLBACK_KEY.ON_MESSAGE_RECEIVED)) === null || _q === void 0 ? void 0 : _q(Object.assign({}, msg));
|
|
186
|
+
(_r = options.onMessageReceived) === null || _r === void 0 ? void 0 : _r.call(options, msg);
|
|
187
|
+
}
|
|
188
|
+
}));
|
|
189
|
+
return sock;
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
// console.log("SOCKET ERROR", error);
|
|
193
|
+
return sock;
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
return startSocket();
|
|
197
|
+
});
|
|
198
|
+
exports.startSession = startSession;
|
|
199
|
+
/**
|
|
200
|
+
*
|
|
201
|
+
* @deprecated Use startSession method instead
|
|
202
|
+
*/
|
|
203
|
+
const startSessionWithPairingCode = (sessionId, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
204
|
+
if (isSessionExistAndRunning(sessionId))
|
|
205
|
+
throw new Error_1.WhatsappError(Defaults_1.Messages.sessionAlreadyExist(sessionId));
|
|
206
|
+
yield initMongo();
|
|
207
|
+
const { version } = yield (0, baileys_1.fetchLatestBaileysVersion)();
|
|
208
|
+
const startSocket = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
209
|
+
var _a;
|
|
210
|
+
const { state, saveCreds } = yield (0, mongo_auth_state_1.useMongoAuthState)(sessionId, authCollection);
|
|
211
|
+
const sock = (0, baileys_1.default)({
|
|
212
|
+
version,
|
|
213
|
+
printQRInTerminal: false,
|
|
214
|
+
auth: state,
|
|
215
|
+
logger: P,
|
|
216
|
+
markOnlineOnConnect: false,
|
|
217
|
+
browser: baileys_1.Browsers.ubuntu("Chrome"),
|
|
218
|
+
});
|
|
219
|
+
sessions.set(sessionId, Object.assign({}, sock));
|
|
220
|
+
try {
|
|
221
|
+
if (!sock.authState.creds.registered) {
|
|
222
|
+
console.log("first time pairing");
|
|
223
|
+
const code = yield sock.requestPairingCode(options.phoneNumber);
|
|
224
|
+
console.log(code);
|
|
225
|
+
(_a = callback.get(Defaults_1.CALLBACK_KEY.ON_PAIRING_CODE)) === null || _a === void 0 ? void 0 : _a(sessionId, code);
|
|
226
|
+
}
|
|
227
|
+
sock.ev.process((events) => __awaiter(void 0, void 0, void 0, function* () {
|
|
228
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
229
|
+
if (events["connection.update"]) {
|
|
230
|
+
const update = events["connection.update"];
|
|
231
|
+
const { connection, lastDisconnect } = update;
|
|
232
|
+
if (update.qr) {
|
|
233
|
+
(_a = callback.get(Defaults_1.CALLBACK_KEY.ON_QR)) === null || _a === void 0 ? void 0 : _a({
|
|
234
|
+
sessionId,
|
|
235
|
+
qr: update.qr,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
if (connection == "connecting") {
|
|
239
|
+
(_b = callback.get(Defaults_1.CALLBACK_KEY.ON_CONNECTING)) === null || _b === void 0 ? void 0 : _b(sessionId);
|
|
240
|
+
}
|
|
241
|
+
if (connection === "close") {
|
|
242
|
+
const code = (_d = (_c = lastDisconnect === null || lastDisconnect === void 0 ? void 0 : lastDisconnect.error) === null || _c === void 0 ? void 0 : _c.output) === null || _d === void 0 ? void 0 : _d.statusCode;
|
|
243
|
+
let retryAttempt = (_e = retryCount.get(sessionId)) !== null && _e !== void 0 ? _e : 0;
|
|
244
|
+
let shouldRetry;
|
|
245
|
+
if (code != baileys_1.DisconnectReason.loggedOut && retryAttempt < 10) {
|
|
246
|
+
shouldRetry = true;
|
|
247
|
+
}
|
|
248
|
+
if (shouldRetry) {
|
|
249
|
+
retryAttempt++;
|
|
250
|
+
}
|
|
251
|
+
if (shouldRetry) {
|
|
252
|
+
retryCount.set(sessionId, retryAttempt);
|
|
253
|
+
startSocket();
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
retryCount.delete(sessionId);
|
|
257
|
+
(0, exports.deleteSession)(sessionId);
|
|
258
|
+
(_f = callback.get(Defaults_1.CALLBACK_KEY.ON_DISCONNECTED)) === null || _f === void 0 ? void 0 : _f(sessionId);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (connection == "open") {
|
|
262
|
+
retryCount.delete(sessionId);
|
|
263
|
+
(_g = callback.get(Defaults_1.CALLBACK_KEY.ON_CONNECTED)) === null || _g === void 0 ? void 0 : _g(sessionId);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (events["creds.update"]) {
|
|
267
|
+
yield saveCreds();
|
|
268
|
+
}
|
|
269
|
+
if (events["messages.update"]) {
|
|
270
|
+
const msg = events["messages.update"][0];
|
|
271
|
+
const data = Object.assign({ sessionId: sessionId, messageStatus: (0, message_status_1.parseMessageStatusCodeToReadable)(msg.update.status) }, msg);
|
|
272
|
+
(_h = callback.get(Defaults_1.CALLBACK_KEY.ON_MESSAGE_UPDATED)) === null || _h === void 0 ? void 0 : _h(sessionId, data);
|
|
273
|
+
}
|
|
274
|
+
if (events["messages.upsert"]) {
|
|
275
|
+
const msg = (_j = events["messages.upsert"]
|
|
276
|
+
.messages) === null || _j === void 0 ? void 0 : _j[0];
|
|
277
|
+
msg.sessionId = sessionId;
|
|
278
|
+
msg.saveImage = (path) => (0, save_media_1.saveImageHandler)(msg, path);
|
|
279
|
+
msg.saveVideo = (path) => (0, save_media_1.saveVideoHandler)(msg, path);
|
|
280
|
+
msg.saveDocument = (path) => (0, save_media_1.saveDocumentHandler)(msg, path);
|
|
281
|
+
msg.saveAudio = (path) => (0, save_media_1.saveAudioHandler)(msg, path);
|
|
282
|
+
(_k = callback.get(Defaults_1.CALLBACK_KEY.ON_MESSAGE_RECEIVED)) === null || _k === void 0 ? void 0 : _k(Object.assign({}, msg));
|
|
283
|
+
}
|
|
284
|
+
}));
|
|
285
|
+
return sock;
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
// console.log("SOCKET ERROR", error);
|
|
289
|
+
return sock;
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
return startSocket();
|
|
293
|
+
});
|
|
294
|
+
exports.startSessionWithPairingCode = startSessionWithPairingCode;
|
|
295
|
+
/**
|
|
296
|
+
* @deprecated Use startSession method instead
|
|
297
|
+
*/
|
|
298
|
+
exports.startWhatsapp = exports.startSession;
|
|
299
|
+
const deleteSession = (sessionId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
300
|
+
const session = (0, exports.getSession)(sessionId);
|
|
301
|
+
try {
|
|
302
|
+
yield (session === null || session === void 0 ? void 0 : session.logout());
|
|
303
|
+
}
|
|
304
|
+
catch (error) { }
|
|
305
|
+
session === null || session === void 0 ? void 0 : session.end(undefined);
|
|
306
|
+
sessions.delete(sessionId);
|
|
307
|
+
// Hapus juga dari MongoDB jika authCollection ada
|
|
308
|
+
if (authCollection) {
|
|
309
|
+
try {
|
|
310
|
+
yield authCollection.deleteOne({ sessionId });
|
|
311
|
+
console.log(`Session ${sessionId} deleted from MongoDB`);
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
console.error(`Error deleting session ${sessionId} from MongoDB:`, error);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// Legacy: hapus juga dari file system jika ada
|
|
318
|
+
const dir = path_1.default.resolve(Defaults_1.CREDENTIALS.DIR_NAME, sessionId + Defaults_1.CREDENTIALS.PREFIX);
|
|
319
|
+
if (fs_1.default.existsSync(dir)) {
|
|
320
|
+
fs_1.default.rmSync(dir, { force: true, recursive: true });
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
exports.deleteSession = deleteSession;
|
|
324
|
+
/**
|
|
325
|
+
* Get all active session IDs
|
|
326
|
+
* @returns Array of session IDs
|
|
327
|
+
*/
|
|
328
|
+
const getAllSession = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
329
|
+
// Return active sessions from Map (sessions yang sudah running di memori)
|
|
330
|
+
const runningSessionIds = Array.from(sessions.keys());
|
|
331
|
+
// Jika authCollection belum diinisialisasi, kembalikan hanya sessions dari memori
|
|
332
|
+
if (!authCollection) {
|
|
333
|
+
return runningSessionIds;
|
|
334
|
+
}
|
|
335
|
+
try {
|
|
336
|
+
// Ambil semua sessionId dari MongoDB
|
|
337
|
+
const sessionDocs = yield authCollection.find({}).toArray();
|
|
338
|
+
const mongoSessionIds = sessionDocs.map((doc) => doc.sessionId);
|
|
339
|
+
// Gabungkan dan deduplikasi session IDs
|
|
340
|
+
const allSessionIds = [...new Set([...runningSessionIds, ...mongoSessionIds])];
|
|
341
|
+
return allSessionIds;
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
console.error("Error fetching sessions from MongoDB:", error);
|
|
345
|
+
// Fallback ke sessions yang ada di memori jika MongoDB error
|
|
346
|
+
return runningSessionIds;
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
exports.getAllSession = getAllSession;
|
|
350
|
+
// Untuk backward compatibility
|
|
351
|
+
const getAllSessionSync = () => Array.from(sessions.keys());
|
|
352
|
+
exports.getAllSessionSync = getAllSessionSync;
|
|
353
|
+
const getSession = (key) => sessions.get(key);
|
|
354
|
+
exports.getSession = getSession;
|
|
355
|
+
const isSessionExistAndRunning = (sessionId) => {
|
|
356
|
+
// Cek jika session sudah berjalan di memory
|
|
357
|
+
if ((0, exports.getSession)(sessionId)) {
|
|
358
|
+
return true;
|
|
359
|
+
}
|
|
360
|
+
return false;
|
|
361
|
+
};
|
|
362
|
+
/**
|
|
363
|
+
* Check if session should be loaded
|
|
364
|
+
* @param sessionId Session ID to check
|
|
365
|
+
* @returns Boolean indicating if session should be loaded
|
|
366
|
+
*/
|
|
367
|
+
const shouldLoadSession = (sessionId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
368
|
+
// Jika session sudah berjalan di memory, tidak perlu load lagi
|
|
369
|
+
if ((0, exports.getSession)(sessionId)) {
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
// Jika authCollection belum diinisialisasi, tidak bisa load
|
|
373
|
+
if (!authCollection) {
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
try {
|
|
377
|
+
// Periksa apakah session ada di MongoDB
|
|
378
|
+
const sessionDoc = yield authCollection.findOne({ sessionId });
|
|
379
|
+
return !!sessionDoc; // Return true jika session ditemukan di MongoDB
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
console.error(`Error checking session ${sessionId} in MongoDB:`, error);
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
/**
|
|
387
|
+
* @deprecated Use loadSessionsFromMongo instead
|
|
388
|
+
*/
|
|
389
|
+
const loadSessionsFromStorage = () => {
|
|
390
|
+
console.warn("loadSessionsFromStorage is deprecated, use loadSessionsFromMongo instead");
|
|
391
|
+
// Redirect ke fungsi loadSessionsFromMongo untuk backward compatibility
|
|
392
|
+
(0, exports.loadSessionsFromMongo)().catch(err => {
|
|
393
|
+
console.error("Error loading sessions from MongoDB:", err);
|
|
394
|
+
});
|
|
395
|
+
};
|
|
396
|
+
exports.loadSessionsFromStorage = loadSessionsFromStorage;
|
|
397
|
+
const onMessageReceived = (listener) => {
|
|
398
|
+
callback.set(Defaults_1.CALLBACK_KEY.ON_MESSAGE_RECEIVED, listener);
|
|
399
|
+
};
|
|
400
|
+
exports.onMessageReceived = onMessageReceived;
|
|
401
|
+
const onQRUpdated = (listener) => {
|
|
402
|
+
callback.set(Defaults_1.CALLBACK_KEY.ON_QR, listener);
|
|
403
|
+
};
|
|
404
|
+
exports.onQRUpdated = onQRUpdated;
|
|
405
|
+
const onConnected = (listener) => {
|
|
406
|
+
callback.set(Defaults_1.CALLBACK_KEY.ON_CONNECTED, listener);
|
|
407
|
+
};
|
|
408
|
+
exports.onConnected = onConnected;
|
|
409
|
+
const onDisconnected = (listener) => {
|
|
410
|
+
callback.set(Defaults_1.CALLBACK_KEY.ON_DISCONNECTED, listener);
|
|
411
|
+
};
|
|
412
|
+
exports.onDisconnected = onDisconnected;
|
|
413
|
+
const onConnecting = (listener) => {
|
|
414
|
+
callback.set(Defaults_1.CALLBACK_KEY.ON_CONNECTING, listener);
|
|
415
|
+
};
|
|
416
|
+
exports.onConnecting = onConnecting;
|
|
417
|
+
const onMessageUpdate = (listener) => {
|
|
418
|
+
callback.set(Defaults_1.CALLBACK_KEY.ON_MESSAGE_UPDATED, listener);
|
|
419
|
+
};
|
|
420
|
+
exports.onMessageUpdate = onMessageUpdate;
|
|
421
|
+
const onPairingCode = (listener) => {
|
|
422
|
+
callback.set(Defaults_1.CALLBACK_KEY.ON_MESSAGE_UPDATED, listener);
|
|
423
|
+
};
|
|
424
|
+
exports.onPairingCode = onPairingCode;
|
|
425
|
+
/**
|
|
426
|
+
* Load all sessions from MongoDB and start them automatically
|
|
427
|
+
*/
|
|
428
|
+
const loadSessionsFromMongo = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
429
|
+
yield initMongo();
|
|
430
|
+
const sessionDocs = yield authCollection.find({}).toArray();
|
|
431
|
+
for (const doc of sessionDocs) {
|
|
432
|
+
const sessionId = doc.sessionId;
|
|
433
|
+
if (sessionId && !(0, exports.getSession)(sessionId)) {
|
|
434
|
+
try {
|
|
435
|
+
yield (0, exports.startSession)(sessionId, { printQR: false });
|
|
436
|
+
}
|
|
437
|
+
catch (e) {
|
|
438
|
+
// Optional: log error jika gagal load session tertentu
|
|
439
|
+
console.error(`Failed to load session ${sessionId}:`, e);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
exports.loadSessionsFromMongo = loadSessionsFromMongo;
|
|
445
|
+
/**
|
|
446
|
+
* Configure MongoDB database and collection names
|
|
447
|
+
*
|
|
448
|
+
* @param dbName MongoDB database name (default: "wa_session")
|
|
449
|
+
* @param collectionName MongoDB collection name for auth storage (default: "auth")
|
|
450
|
+
*/
|
|
451
|
+
const setMongoDBNames = (dbName = "wa_session", collectionName = "auth") => {
|
|
452
|
+
Defaults_1.CREDENTIALS.MONGO_DB_NAME = dbName;
|
|
453
|
+
Defaults_1.CREDENTIALS.MONGO_COLLECTION_NAME = collectionName;
|
|
454
|
+
console.log(`MongoDB names configured: database="${dbName}", collection="${collectionName}"`);
|
|
455
|
+
};
|
|
456
|
+
exports.setMongoDBNames = setMongoDBNames;
|
|
457
|
+
/**
|
|
458
|
+
* Sets the directory name for storing credentials (File-based storage)
|
|
459
|
+
*
|
|
460
|
+
* @deprecated When using MongoDB, this setting has no effect. Only used for legacy file-based storage.
|
|
461
|
+
* @param dirname Directory name for storing credentials (default: "wa_credentials")
|
|
462
|
+
*/
|
|
463
|
+
const setCredentialsDir = (dirname = "wa_credentials") => {
|
|
464
|
+
console.warn("setCredentialsDir() is deprecated when using MongoDB storage. This setting only affects legacy file-based storage.");
|
|
465
|
+
Defaults_1.CREDENTIALS.DIR_NAME = dirname;
|
|
466
|
+
};
|
|
467
|
+
exports.setCredentialsDir = setCredentialsDir;
|
|
468
|
+
/**
|
|
469
|
+
* Attempt to reconnect a disconnected session
|
|
470
|
+
*
|
|
471
|
+
* @param sessionId Session ID to reconnect
|
|
472
|
+
* @returns Promise<boolean> indicating success
|
|
473
|
+
*/
|
|
474
|
+
const reconnect = (sessionId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
475
|
+
try {
|
|
476
|
+
// Cek jika session masih ada di memory
|
|
477
|
+
const existingSession = sessions.get(sessionId);
|
|
478
|
+
// Hapus session terlebih dahulu untuk menghindari konflik
|
|
479
|
+
if (existingSession) {
|
|
480
|
+
try {
|
|
481
|
+
// Coba lakukan logout jika memungkinkan (tapi jangan crash jika gagal)
|
|
482
|
+
yield existingSession.logout().catch((e) => { });
|
|
483
|
+
}
|
|
484
|
+
catch (logoutError) {
|
|
485
|
+
// Abaikan error saat logout
|
|
486
|
+
}
|
|
487
|
+
// Akhiri session dan hapus dari map secara paksa
|
|
488
|
+
try {
|
|
489
|
+
existingSession.end(undefined);
|
|
490
|
+
}
|
|
491
|
+
catch (endError) {
|
|
492
|
+
// Abaikan error saat mengakhiri
|
|
493
|
+
}
|
|
494
|
+
sessions.delete(sessionId);
|
|
495
|
+
}
|
|
496
|
+
// Tunggu sedikit waktu untuk memastikan cleanup selesai
|
|
497
|
+
yield (0, create_delay_1.createDelay)(1000);
|
|
498
|
+
// Cek jika data session tersedia di MongoDB
|
|
499
|
+
yield initMongo();
|
|
500
|
+
const sessionExists = yield shouldLoadSession(sessionId);
|
|
501
|
+
if (sessionExists) {
|
|
502
|
+
// Mulai session baru dari data yang tersimpan di MongoDB
|
|
503
|
+
// Gunakan opsi khusus untuk reconnect
|
|
504
|
+
try {
|
|
505
|
+
yield (0, exports.startSession)(sessionId, {
|
|
506
|
+
printQR: false,
|
|
507
|
+
// Tambahkan callback khusus untuk reconnect
|
|
508
|
+
onConnected: () => { },
|
|
509
|
+
onDisconnected: () => { },
|
|
510
|
+
onQRUpdated: (qr) => { }
|
|
511
|
+
});
|
|
512
|
+
// Periksa jika session berhasil dimulai
|
|
513
|
+
return !!(0, exports.getSession)(sessionId);
|
|
514
|
+
}
|
|
515
|
+
catch (startError) {
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
catch (error) {
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
});
|
|
527
|
+
exports.reconnect = reconnect;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { WAMessageUpdate, proto } from "baileys";
|
|
2
|
+
export interface SendMessageTypes {
|
|
3
|
+
to: string | number;
|
|
4
|
+
text?: string;
|
|
5
|
+
sessionId: string;
|
|
6
|
+
isGroup?: boolean;
|
|
7
|
+
answering?: proto.IWebMessageInfo;
|
|
8
|
+
}
|
|
9
|
+
export interface SendMediaTypes extends SendMessageTypes {
|
|
10
|
+
media: string | Buffer;
|
|
11
|
+
type: "image" | "video" | "audio" | "pdf" | "xls" | "xlsx" | "doc" | "docx" | "zip" | "mp3";
|
|
12
|
+
caption?: string;
|
|
13
|
+
fileName?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface SendTypingTypes extends SendMessageTypes {
|
|
16
|
+
duration: number;
|
|
17
|
+
}
|
|
18
|
+
export interface SendReadTypes {
|
|
19
|
+
sessionId: string;
|
|
20
|
+
key: proto.IMessageKey;
|
|
21
|
+
}
|
|
22
|
+
export interface MessageReceived extends proto.IWebMessageInfo {
|
|
23
|
+
/**
|
|
24
|
+
* Your Session ID
|
|
25
|
+
*/
|
|
26
|
+
sessionId: string;
|
|
27
|
+
/**
|
|
28
|
+
* @param path save image location path with extension
|
|
29
|
+
* @example "./myimage.jpg"
|
|
30
|
+
*/
|
|
31
|
+
saveImage: (path: string) => Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* @param path save video location path with extension
|
|
34
|
+
* @example "./myvideo.mp4"
|
|
35
|
+
*/
|
|
36
|
+
saveVideo: (path: string) => Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* @param path save audio location path with extension
|
|
39
|
+
* @example "./myaudio.mp3"
|
|
40
|
+
*/
|
|
41
|
+
saveAudio: (path: string) => Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* @param path save image location path without extension
|
|
44
|
+
* @example "./mydocument"
|
|
45
|
+
*/
|
|
46
|
+
saveDocument: (path: string) => Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
export interface StartSessionParams {
|
|
49
|
+
/**
|
|
50
|
+
* Print QR Code into Terminal
|
|
51
|
+
*/
|
|
52
|
+
printQR?: boolean;
|
|
53
|
+
onQRUpdated?: (qr: string) => void;
|
|
54
|
+
onConnected?: () => void;
|
|
55
|
+
onConnecting?: () => void;
|
|
56
|
+
onDisconnected?: () => void;
|
|
57
|
+
onMessageReceived?: (message: MessageReceived) => void;
|
|
58
|
+
onMessageUpdated?: (message: MessageUpdated) => void;
|
|
59
|
+
}
|
|
60
|
+
export interface StartSessionWithPairingCodeParams {
|
|
61
|
+
/**
|
|
62
|
+
* Phone Number with Country Code
|
|
63
|
+
*/
|
|
64
|
+
phoneNumber: string;
|
|
65
|
+
}
|
|
66
|
+
export type MessageUpdated = WAMessageUpdate & {
|
|
67
|
+
sessionId: string;
|
|
68
|
+
messageStatus: "error" | "pending" | "server" | "delivered" | "read" | "played";
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC;CACxB;AAED,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,eAAe;IAC5D;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C;;;OAGG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C;;;OAGG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C;;;OAGG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAGlB,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAG5B,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACvD,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,iCAAiC;IAChD;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EACT,OAAO,GACP,SAAS,GACT,QAAQ,GACR,WAAW,GACX,MAAM,GACN,QAAQ,CAAC;CACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/Types/profile.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create delay for certain milliseconds
|
|
3
|
+
*
|
|
4
|
+
* @param ms - Delay in milliseconds
|
|
5
|
+
* @returns Promise that resolves after the specified delay
|
|
6
|
+
*/
|
|
7
|
+
export declare const createDelay: (ms: number) => Promise<unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Execute a promise with a timeout
|
|
10
|
+
*
|
|
11
|
+
* @param promise - The promise to execute
|
|
12
|
+
* @param timeoutMs - Timeout in milliseconds
|
|
13
|
+
* @param errorMessage - Custom error message for timeout
|
|
14
|
+
* @returns Promise that resolves with the result or rejects with timeout error
|
|
15
|
+
*/
|
|
16
|
+
export declare const withTimeout: <T>(promise: Promise<T>, timeoutMs?: number, errorMessage?: string) => Promise<T>;
|
|
17
|
+
//# sourceMappingURL=create-delay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-delay.d.ts","sourceRoot":"","sources":["../../src/Utils/create-delay.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,IAAI,MAAM,qBAErC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAC3B,SAAS,OAAO,CAAC,CAAC,CAAC,EACnB,YAAW,MAAc,EACzB,eAAc,MAA8B,KAC3C,OAAO,CAAC,CAAC,CAgBX,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withTimeout = exports.createDelay = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Create delay for certain milliseconds
|
|
6
|
+
*
|
|
7
|
+
* @param ms - Delay in milliseconds
|
|
8
|
+
* @returns Promise that resolves after the specified delay
|
|
9
|
+
*/
|
|
10
|
+
const createDelay = (ms) => {
|
|
11
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
12
|
+
};
|
|
13
|
+
exports.createDelay = createDelay;
|
|
14
|
+
/**
|
|
15
|
+
* Execute a promise with a timeout
|
|
16
|
+
*
|
|
17
|
+
* @param promise - The promise to execute
|
|
18
|
+
* @param timeoutMs - Timeout in milliseconds
|
|
19
|
+
* @param errorMessage - Custom error message for timeout
|
|
20
|
+
* @returns Promise that resolves with the result or rejects with timeout error
|
|
21
|
+
*/
|
|
22
|
+
const withTimeout = (promise, timeoutMs = 10000, errorMessage = 'Operation timed out') => {
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
const timeoutId = setTimeout(() => {
|
|
25
|
+
reject(new Error(errorMessage));
|
|
26
|
+
}, timeoutMs);
|
|
27
|
+
promise
|
|
28
|
+
.then((result) => {
|
|
29
|
+
clearTimeout(timeoutId);
|
|
30
|
+
resolve(result);
|
|
31
|
+
})
|
|
32
|
+
.catch((error) => {
|
|
33
|
+
clearTimeout(timeoutId);
|
|
34
|
+
reject(error);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
exports.withTimeout = withTimeout;
|