Compare commits
31
Commits
2024.10.8
...
2024.10.11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1bb445593 | ||
|
|
7f777f338f | ||
|
|
4449dfdbd6 | ||
|
|
6226e65e97 | ||
|
|
be1783c029 | ||
|
|
83a002ae5b | ||
|
|
f0fcb2b329 | ||
|
|
5ff695a5b3 | ||
|
|
43fe1f076e | ||
|
|
1afd7e042c | ||
|
|
ba6474f97e | ||
|
|
d8eed114aa | ||
|
|
e61ad6f79c | ||
|
|
9d27616003 | ||
|
|
0f2641909f | ||
|
|
9ca96acda2 | ||
|
|
77db6c5e98 | ||
|
|
c4aa9804d2 | ||
|
|
eb7bfe3a62 | ||
|
|
01fd7a8d56 | ||
|
|
81fb93e5d6 | ||
|
|
64716ec6e6 | ||
|
|
e0f787be32 | ||
|
|
138da79599 | ||
|
|
b8b290c2a5 | ||
|
|
f35dcc0ec6 | ||
|
|
62704e261a | ||
|
|
f16ace6169 | ||
|
|
35628aa93b | ||
|
|
64bf42dc1c | ||
|
|
55fc6a4282 |
No files matched your search
@@ -8,7 +8,8 @@ assignees: ''
|
||||
|
||||
### Describe the bug
|
||||
|
||||
A clear and concise description of what the bug is. Feel free to remove sections that you don't feel to make the text shorter!
|
||||
A clear and concise description of what the bug is. Feel free to remove sections
|
||||
that you don't feel to make the text shorter!
|
||||
|
||||
### Version
|
||||
|
||||
@@ -22,9 +23,12 @@ Get the WAHA version by calling `GET /api/version`
|
||||
}
|
||||
```
|
||||
|
||||
Try to update to [the latest version](https://github.com/devlikeapro/waha/releases) before creating an issue!
|
||||
Try to update to
|
||||
[the latest version](https://github.com/devlikeapro/waha/releases) before
|
||||
creating an issue!
|
||||
|
||||
## Steps
|
||||
|
||||
**To Reproduce** Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
|
||||
@@ -6,19 +6,19 @@ labels: ''
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
I'm always frustrated when [...]
|
||||
**Is your feature request related to a problem? Please describe.** I'm always
|
||||
frustrated when [...]
|
||||
|
||||
A clear and concise description of what the problem is. Ex.
|
||||
|
||||
**Describe the solution you'd like**
|
||||
|
||||
A clear and concise description of what you want to happen.
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
|
||||
A clear and concise description of any alternative solutions or features
|
||||
you've considered.
|
||||
A clear and concise description of any alternative solutions or features you've
|
||||
considered.
|
||||
|
||||
**Additional context** Add any other context or screenshots about the feature
|
||||
request here.
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
name: Question
|
||||
about: I have a question about the project or feature
|
||||
title: '[Question] '
|
||||
labels: 'question'
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
👉 Kindly use
|
||||
[GitHub Discussions](https://github.com/devlikeapro/waha/discussions) to ask
|
||||
questions!
|
||||
@@ -72,4 +72,5 @@ repos:
|
||||
entrypoint.sh|
|
||||
.pre-commit-config.yaml|
|
||||
^src/core/engines/webjs/session.webjs.core.ts|
|
||||
^src/core/engines/webjs/_lodash.js|
|
||||
)$
|
||||
+8
-4
@@ -26,7 +26,7 @@ RUN yarn build && find ./dist -name "*.d.ts" -delete
|
||||
FROM node:${NODE_VERSION} AS dashboard
|
||||
|
||||
# Download WAHA Dashboard
|
||||
ENV WAHA_DASHBOARD_SHA 5199c68522e81e911b440834fa7adc15ff4a1cf9
|
||||
ENV WAHA_DASHBOARD_SHA e6a72c5de2effc97d83e997cb1f361851604bae8
|
||||
RUN \
|
||||
wget https://github.com/devlikeapro/dashboard/archive/${WAHA_DASHBOARD_SHA}.zip \
|
||||
&& unzip ${WAHA_DASHBOARD_SHA}.zip -d /tmp/dashboard \
|
||||
@@ -50,8 +50,12 @@ RUN echo "USE_BROWSER=$USE_BROWSER"
|
||||
# Install ffmpeg to generate previews for videos
|
||||
RUN apt-get update && apt-get install -y ffmpeg --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install zip and unzip
|
||||
RUN apt-get update && apt-get install -y zip unzip --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
# Install zip and unzip - either for chromium or chrome
|
||||
RUN if [ "$USE_BROWSER" = "chromium" ] || [ "$USE_BROWSER" = "chrome" ]; then \
|
||||
apt-get update \
|
||||
&& apt-get install -y zip unzip \
|
||||
&& rm -rf /var/lib/apt/lists/*; \
|
||||
fi
|
||||
|
||||
# Install fonts if using either chromium or chrome
|
||||
RUN if [ "$USE_BROWSER" = "chromium" ] || [ "$USE_BROWSER" = "chrome" ]; then \
|
||||
@@ -73,7 +77,7 @@ RUN if [ "$USE_BROWSER" = "chromium" ]; then \
|
||||
# Install Chrome
|
||||
# Available versions:
|
||||
# https://www.ubuntuupdates.org/package/google_chrome/stable/main/base/google-chrome-stable
|
||||
ARG CHROME_VERSION="126.0.6478.182-1"
|
||||
ARG CHROME_VERSION="130.0.6723.69-1"
|
||||
RUN if [ "$USE_BROWSER" = "chrome" ]; then \
|
||||
wget --no-verbose -O /tmp/chrome.deb https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_${CHROME_VERSION}_amd64.deb \
|
||||
&& apt-get update \
|
||||
|
||||
+10
-1
@@ -70,7 +70,7 @@
|
||||
"pino-pretty": "^11.2.1",
|
||||
"pretty-bytes": "5.6.0",
|
||||
"promise-retry": "^2.0.1",
|
||||
"puppeteer": "^21.0.0",
|
||||
"puppeteer": "^23.6.0",
|
||||
"qrcode": "^1.5.1",
|
||||
"qrcode-terminal": "^0.12.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
@@ -80,6 +80,15 @@
|
||||
"swagger-ui-express": "^4.1.4",
|
||||
"whatsapp-web.js": "github:devlikeapro/whatsapp-web.js#fork-main-channels"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"bufferutil": "^4.0.8"
|
||||
},
|
||||
"resolutions": {
|
||||
"bufferutil": "^4.0.8",
|
||||
"ws": "^8.18.0",
|
||||
"puppeteer": "^23.6.0",
|
||||
"whatwg-url": "13.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "^9.0.0",
|
||||
"@nestjs/schematics": "^9.0.1",
|
||||
|
||||
@@ -82,7 +82,7 @@ export class ChannelsController {
|
||||
}
|
||||
}
|
||||
|
||||
@Post('follow')
|
||||
@Post(':id/follow')
|
||||
@SessionApiParam
|
||||
@NewsletterIdApiParam
|
||||
@ApiOperation({ summary: 'Follow the channel.' })
|
||||
@@ -93,7 +93,7 @@ export class ChannelsController {
|
||||
return session.channelsFollowChannel(id);
|
||||
}
|
||||
|
||||
@Post('unfollow')
|
||||
@Post(':id/unfollow')
|
||||
@SessionApiParam
|
||||
@NewsletterIdApiParam
|
||||
@ApiOperation({ summary: 'Unfollow the channel.' })
|
||||
@@ -104,7 +104,7 @@ export class ChannelsController {
|
||||
return session.channelsUnfollowChannel(id);
|
||||
}
|
||||
|
||||
@Post('mute')
|
||||
@Post(':id/mute')
|
||||
@SessionApiParam
|
||||
@NewsletterIdApiParam
|
||||
@ApiOperation({ summary: 'Mute the channel.' })
|
||||
@@ -115,7 +115,7 @@ export class ChannelsController {
|
||||
return session.channelsMuteChannel(id);
|
||||
}
|
||||
|
||||
@Post('unmute')
|
||||
@Post(':id/unmute')
|
||||
@SessionApiParam
|
||||
@NewsletterIdApiParam
|
||||
@ApiOperation({ summary: 'Unmute the channel.' })
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
NotFoundException,
|
||||
Param,
|
||||
Post,
|
||||
Put,
|
||||
@@ -21,7 +22,12 @@ import {
|
||||
import { SessionManager } from '../core/abc/manager.abc';
|
||||
import { WhatsappSession } from '../core/abc/session.abc';
|
||||
import { parseBool } from '../helpers';
|
||||
import { GetChatMessagesQuery, GetChatsQuery } from '../structures/chats.dto';
|
||||
import {
|
||||
ChatsPaginationParams,
|
||||
GetChatMessageQuery,
|
||||
GetChatMessagesFilter,
|
||||
GetChatMessagesQuery,
|
||||
} from '../structures/chats.dto';
|
||||
import { EditMessageRequest } from '../structures/chatting.dto';
|
||||
|
||||
@ApiSecurity('api_key')
|
||||
@@ -36,9 +42,9 @@ class ChatsController {
|
||||
@ApiOperation({ summary: 'Get chats' })
|
||||
getChats(
|
||||
@WorkingSessionParam session: WhatsappSession,
|
||||
@Query() query: GetChatsQuery,
|
||||
@Query() pagination: ChatsPaginationParams,
|
||||
) {
|
||||
return session.getChats(query);
|
||||
return session.getChats(pagination);
|
||||
}
|
||||
|
||||
@Delete(':chatId')
|
||||
@@ -56,13 +62,31 @@ class ChatsController {
|
||||
@SessionApiParam
|
||||
@ApiOperation({ summary: 'Gets messages in the chat' })
|
||||
@ChatIdApiParam
|
||||
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
|
||||
getChatMessages(
|
||||
@Query() query: GetChatMessagesQuery,
|
||||
@Query() filter: GetChatMessagesFilter,
|
||||
@WorkingSessionParam session: WhatsappSession,
|
||||
@Param('chatId') chatId: string,
|
||||
) {
|
||||
const downloadMedia = parseBool(query.downloadMedia);
|
||||
return session.getChatMessages(chatId, query.limit, downloadMedia);
|
||||
return session.getChatMessages(chatId, query, filter);
|
||||
}
|
||||
|
||||
@Get(':chatId/messages/:messageId')
|
||||
@SessionApiParam
|
||||
@ApiOperation({ summary: 'Gets message by id' })
|
||||
@ChatIdApiParam
|
||||
async getChatMessage(
|
||||
@Query() query: GetChatMessageQuery,
|
||||
@WorkingSessionParam session: WhatsappSession,
|
||||
@Param('chatId') chatId: string,
|
||||
@Param('messageId') messageId: string,
|
||||
) {
|
||||
const message = await session.getChatMessage(chatId, messageId, query);
|
||||
if (!message) {
|
||||
throw new NotFoundException('Message not found');
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
@Delete(':chatId/messages')
|
||||
@@ -124,6 +148,17 @@ class ChatsController {
|
||||
) {
|
||||
return session.chatsUnarchiveChat(chatId);
|
||||
}
|
||||
|
||||
@Post(':chatId/unread')
|
||||
@SessionApiParam
|
||||
@ChatIdApiParam
|
||||
@ApiOperation({ summary: 'Unread the chat' })
|
||||
unreadChat(
|
||||
@WorkingSessionParam session: WhatsappSession,
|
||||
@Param('chatId') chatId: string,
|
||||
) {
|
||||
return session.chatsUnreadChat(chatId);
|
||||
}
|
||||
}
|
||||
|
||||
export { ChatsController };
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
|
||||
import { WAHAValidationPipe } from '@waha/nestjs/pipes/WAHAValidationPipe';
|
||||
import { GetChatMessagesFilter } from '@waha/structures/chats.dto';
|
||||
import { SendButtonsRequest } from '@waha/structures/chatting.buttons.dto';
|
||||
|
||||
import { SessionManager } from '../core/abc/manager.abc';
|
||||
@@ -171,9 +172,12 @@ export class ChattingController {
|
||||
|
||||
@Get('/messages')
|
||||
@ApiOperation({ summary: 'Get messages in a chat' })
|
||||
async getMessages(@Query() query: GetMessageQuery) {
|
||||
async getMessages(
|
||||
@Query() query: GetMessageQuery,
|
||||
@Query() filter: GetChatMessagesFilter,
|
||||
) {
|
||||
const whatsapp = await this.manager.getWorkingSession(query.session);
|
||||
return whatsapp.getMessages(query);
|
||||
return whatsapp.getChatMessages(query.chatId, query, filter);
|
||||
}
|
||||
|
||||
@Get('/sendText')
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Query,
|
||||
UsePipes,
|
||||
ValidationPipe,
|
||||
} from '@nestjs/common';
|
||||
import { ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
import { SessionManager } from '../core/abc/manager.abc';
|
||||
@@ -7,7 +15,11 @@ import {
|
||||
CheckNumberStatusQuery,
|
||||
WANumberExistResult,
|
||||
} from '../structures/chatting.dto';
|
||||
import { ContactQuery, ContactRequest } from '../structures/contacts.dto';
|
||||
import {
|
||||
ContactQuery,
|
||||
ContactRequest,
|
||||
ContactsPaginationParams,
|
||||
} from '../structures/contacts.dto';
|
||||
|
||||
@ApiSecurity('api_key')
|
||||
@Controller('api/contacts')
|
||||
@@ -15,6 +27,17 @@ import { ContactQuery, ContactRequest } from '../structures/contacts.dto';
|
||||
export class ContactsController {
|
||||
constructor(private manager: SessionManager) {}
|
||||
|
||||
@Get('/all')
|
||||
@ApiOperation({ summary: 'Get all contacts' })
|
||||
@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
|
||||
async getAll(
|
||||
@Query() query: SessionQuery,
|
||||
@Query() pagination: ContactsPaginationParams,
|
||||
) {
|
||||
const whatsapp = await this.manager.getWorkingSession(query.session);
|
||||
return whatsapp.getContacts(pagination);
|
||||
}
|
||||
|
||||
@Get('/')
|
||||
@ApiOperation({
|
||||
summary: 'Get contact basic info',
|
||||
@@ -26,13 +49,6 @@ export class ContactsController {
|
||||
return whatsapp.getContact(query);
|
||||
}
|
||||
|
||||
@Get('/all')
|
||||
@ApiOperation({ summary: 'Get all contacts' })
|
||||
async getAll(@Query() query: SessionQuery) {
|
||||
const whatsapp = await this.manager.getWorkingSession(query.session);
|
||||
return whatsapp.getContacts();
|
||||
}
|
||||
|
||||
@Get('/check-exists')
|
||||
@ApiOperation({ summary: 'Check phone number is registered in WhatsApp.' })
|
||||
async checkExists(
|
||||
|
||||
@@ -135,6 +135,7 @@ class SessionsController {
|
||||
async delete(@Param('session') name: string): Promise<void> {
|
||||
await this.withLock(name, async () => {
|
||||
await this.manager.unassign(name);
|
||||
await this.manager.unpair(name);
|
||||
await this.manager.stop(name, true);
|
||||
await this.manager.logout(name);
|
||||
await this.manager.delete(name);
|
||||
@@ -190,6 +191,7 @@ class SessionsController {
|
||||
throw new NotFoundException('Session not found');
|
||||
}
|
||||
const isRunning = this.manager.isRunning(name);
|
||||
await this.manager.unpair(name);
|
||||
await this.manager.stop(name, true);
|
||||
await this.manager.logout(name);
|
||||
if (isRunning) {
|
||||
@@ -258,6 +260,7 @@ class SessionsController {
|
||||
// Old API did remove the session complete
|
||||
await this.withLock(name, async () => {
|
||||
await this.manager.unassign(name);
|
||||
await this.manager.unpair(name);
|
||||
await this.manager.stop(name, true);
|
||||
await this.manager.logout(name);
|
||||
await this.manager.delete(name);
|
||||
@@ -283,6 +286,7 @@ class SessionsController {
|
||||
const name = request.name;
|
||||
await this.withLock(name, async () => {
|
||||
await this.manager.unassign(name);
|
||||
await this.manager.unpair(name);
|
||||
await this.manager.stop(name, true);
|
||||
await this.manager.logout(name);
|
||||
await this.manager.delete(name);
|
||||
|
||||
@@ -94,6 +94,8 @@ export abstract class SessionManager implements BeforeApplicationShutdown {
|
||||
|
||||
abstract logout(name: string): Promise<void>;
|
||||
|
||||
abstract unpair(name: string): Promise<void>;
|
||||
|
||||
abstract getSession(name: string): WhatsappSession;
|
||||
|
||||
abstract getSessionInfo(name: string): Promise<SessionDetailedInfo | null>;
|
||||
|
||||
+35
-10
@@ -3,9 +3,14 @@ import {
|
||||
CreateChannelRequest,
|
||||
ListChannelsQuery,
|
||||
} from '@waha/structures/channels.dto';
|
||||
import { GetChatsQuery } from '@waha/structures/chats.dto';
|
||||
import {
|
||||
GetChatMessageQuery,
|
||||
GetChatMessagesFilter,
|
||||
GetChatMessagesQuery,
|
||||
} from '@waha/structures/chats.dto';
|
||||
import { SendButtonsRequest } from '@waha/structures/chatting.buttons.dto';
|
||||
import { Label, LabelID } from '@waha/structures/labels.dto';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
import { WAMessage } from '@waha/structures/responses.dto';
|
||||
import { LoggerBuilder } from '@waha/utils/logging';
|
||||
import { EventEmitter } from 'events';
|
||||
@@ -17,7 +22,6 @@ import {
|
||||
ChatRequest,
|
||||
CheckNumberStatusQuery,
|
||||
EditMessageRequest,
|
||||
GetMessageQuery,
|
||||
MessageContactVcardRequest,
|
||||
MessageFileRequest,
|
||||
MessageForwardRequest,
|
||||
@@ -111,6 +115,7 @@ export abstract class WhatsappSession {
|
||||
protected proxyConfig?: ProxyConfig;
|
||||
public sessionConfig?: SessionConfig;
|
||||
protected engineConfig?: any;
|
||||
protected unpairing: boolean = false;
|
||||
|
||||
private _status: WAHASessionStatus;
|
||||
private shouldPrintQR: boolean;
|
||||
@@ -138,6 +143,11 @@ export abstract class WhatsappSession {
|
||||
}
|
||||
|
||||
protected set status(value: WAHASessionStatus) {
|
||||
if (this.unpairing && value !== WAHASessionStatus.STOPPED) {
|
||||
// In case of unpairing
|
||||
// wait for STOPPED event, ignore the rest
|
||||
return;
|
||||
}
|
||||
this._status = value;
|
||||
const body: WASessionStatusBody = { name: this.name, status: value };
|
||||
this.events.emit(WAHAEvents.SESSION_STATUS, body);
|
||||
@@ -168,6 +178,7 @@ export abstract class WhatsappSession {
|
||||
'--disable-default-apps',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-extensions',
|
||||
'--disable-features=site-per-process',
|
||||
'--disable-gpu',
|
||||
'--disable-offer-store-unmasked-wallet-cards',
|
||||
'--disable-offline-load-stale-cache',
|
||||
@@ -195,6 +206,7 @@ export abstract class WhatsappSession {
|
||||
'--safebrowsing-disable-auto-update',
|
||||
'--single-process',
|
||||
'--use-mock-keychain',
|
||||
'--window-size=1280,720',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -208,6 +220,11 @@ export abstract class WhatsappSession {
|
||||
/** Stop the session */
|
||||
abstract stop(): Promise<void>;
|
||||
|
||||
/* Unpair the account */
|
||||
async unpair(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
/** Subscribe the handler to specific hook */
|
||||
subscribeSessionEvent(
|
||||
hook: WAHAEvents | string,
|
||||
@@ -306,10 +323,6 @@ export abstract class WhatsappSession {
|
||||
|
||||
abstract stopTyping(chat: ChatRequest);
|
||||
|
||||
getMessages(query: GetMessageQuery) {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
abstract setReaction(request: MessageReactionRequest);
|
||||
|
||||
setStar(request: MessageStarRequest): Promise<void> {
|
||||
@@ -319,7 +332,7 @@ export abstract class WhatsappSession {
|
||||
/**
|
||||
* Chats methods
|
||||
*/
|
||||
public getChats(query: GetChatsQuery) {
|
||||
public getChats(pagination: PaginationParams) {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
@@ -329,12 +342,20 @@ export abstract class WhatsappSession {
|
||||
|
||||
public getChatMessages(
|
||||
chatId: string,
|
||||
limit: number,
|
||||
downloadMedia: boolean,
|
||||
query: GetChatMessagesQuery,
|
||||
filter: GetChatMessagesFilter,
|
||||
) {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
public getChatMessage(
|
||||
chatId: string,
|
||||
messageId: string,
|
||||
query: GetChatMessageQuery,
|
||||
): Promise<null | WAMessage> {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
public deleteMessage(chatId: string, messageId: string) {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
@@ -359,6 +380,10 @@ export abstract class WhatsappSession {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
public chatsUnreadChat(chatId: string): Promise<any> {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Labels methods
|
||||
*/
|
||||
@@ -386,7 +411,7 @@ export abstract class WhatsappSession {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
public getContacts() {
|
||||
public getContacts(pagination: PaginationParams) {
|
||||
throw new NotImplementedByEngineError();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import { UnprocessableEntityException } from '@nestjs/common';
|
||||
import { sendButtonMessage } from '@waha/core/engines/noweb/noweb.buttons';
|
||||
import { NowebInMemoryStore } from '@waha/core/engines/noweb/store/NowebInMemoryStore';
|
||||
import { IMediaEngineProcessor } from '@waha/core/media/IMediaEngineProcessor';
|
||||
import { flipObject, parseBool, splitAt } from '@waha/helpers';
|
||||
import { flipObject, splitAt } from '@waha/helpers';
|
||||
import { PairingCodeResponse } from '@waha/structures/auth.dto';
|
||||
import { CallData } from '@waha/structures/calls.dto';
|
||||
import {
|
||||
@@ -38,7 +38,11 @@ import {
|
||||
CreateChannelRequest,
|
||||
ListChannelsQuery,
|
||||
} from '@waha/structures/channels.dto';
|
||||
import { GetChatsQuery } from '@waha/structures/chats.dto';
|
||||
import {
|
||||
GetChatMessageQuery,
|
||||
GetChatMessagesFilter,
|
||||
GetChatMessagesQuery,
|
||||
} from '@waha/structures/chats.dto';
|
||||
import { SendButtonsRequest } from '@waha/structures/chatting.buttons.dto';
|
||||
import { ContactQuery, ContactRequest } from '@waha/structures/contacts.dto';
|
||||
import { BinaryFile, RemoteFile } from '@waha/structures/files.dto';
|
||||
@@ -48,26 +52,25 @@ import {
|
||||
LabelID,
|
||||
} from '@waha/structures/labels.dto';
|
||||
import { ReplyToMessage } from '@waha/structures/message.dto';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
import {
|
||||
PollVote,
|
||||
PollVotePayload,
|
||||
WAMessageAckBody,
|
||||
} from '@waha/structures/webhooks.dto';
|
||||
import { LoggerBuilder } from '@waha/utils/logging';
|
||||
import { waitUntil } from '@waha/utils/promiseTimeout';
|
||||
import { sleep, waitUntil } from '@waha/utils/promiseTimeout';
|
||||
import { SingleDelayedJobRunner } from '@waha/utils/SingleDelayedJobRunner';
|
||||
import { SinglePeriodicJobRunner } from '@waha/utils/SinglePeriodicJobRunner';
|
||||
import * as Buffer from 'buffer';
|
||||
import { Agent } from 'https';
|
||||
import * as lodash from 'lodash';
|
||||
import { toNumber } from 'lodash';
|
||||
import * as NodeCache from 'node-cache';
|
||||
|
||||
import {
|
||||
ChatRequest,
|
||||
CheckNumberStatusQuery,
|
||||
EditMessageRequest,
|
||||
GetMessageQuery,
|
||||
MessageContactVcardRequest,
|
||||
MessageDestination,
|
||||
MessageFileRequest,
|
||||
@@ -221,6 +224,12 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
});
|
||||
}
|
||||
|
||||
async unpair() {
|
||||
this.unpairing = true;
|
||||
this.shouldRestart = false;
|
||||
await this.sock?.logout();
|
||||
}
|
||||
|
||||
getSocketConfig(agent, state): any {
|
||||
const fullSyncEnabled = this.sessionConfig?.noweb?.store?.fullSync || false;
|
||||
const browser = fullSyncEnabled
|
||||
@@ -437,8 +446,14 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
this.startDelayedJob.cancel();
|
||||
this.autoRestartJob.stop();
|
||||
|
||||
// We'll restart the client if it's in the process of unpairing
|
||||
this.status = WAHASessionStatus.FAILED;
|
||||
|
||||
if (this.unpairing) {
|
||||
// Wait for unpairing to complete before ending the socket
|
||||
await sleep(1_000);
|
||||
}
|
||||
|
||||
await this.end();
|
||||
await this.store?.close();
|
||||
}
|
||||
@@ -754,19 +769,17 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
return this.sock.sendPresenceUpdate('paused', chatId);
|
||||
}
|
||||
|
||||
async getMessages(query: GetMessageQuery) {
|
||||
return this.getChatMessages(query.chatId, query.limit, query.downloadMedia);
|
||||
}
|
||||
|
||||
public async getChatMessages(
|
||||
chatId: string,
|
||||
limit: number,
|
||||
downloadMedia: boolean,
|
||||
query: GetChatMessagesQuery,
|
||||
filter: GetChatMessagesFilter,
|
||||
) {
|
||||
downloadMedia = parseBool(downloadMedia);
|
||||
const downloadMedia = query.downloadMedia;
|
||||
const pagination = query as PaginationParams;
|
||||
const messages = await this.store.getMessagesByJid(
|
||||
toJID(chatId),
|
||||
toNumber(limit),
|
||||
filter,
|
||||
pagination,
|
||||
);
|
||||
|
||||
const promises = [];
|
||||
@@ -778,6 +791,17 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
return result;
|
||||
}
|
||||
|
||||
public async getChatMessage(
|
||||
chatId: string,
|
||||
messageId: string,
|
||||
query: GetChatMessageQuery,
|
||||
): Promise<null | WAMessage> {
|
||||
const key = parseMessageIdSerialized(messageId, true);
|
||||
const message = await this.store.getMessageById(toJID(chatId), key.id);
|
||||
if (!message) return null;
|
||||
return await this.processIncomingMessage(message, query.downloadMedia);
|
||||
}
|
||||
|
||||
async setReaction(request: MessageReactionRequest) {
|
||||
const key = parseMessageIdSerialized(request.messageId);
|
||||
const reactionMessage = {
|
||||
@@ -806,8 +830,8 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
* Chats methods
|
||||
*/
|
||||
|
||||
async getChats(query: GetChatsQuery) {
|
||||
const chats = await this.store.getChats(query.limit, query.offset);
|
||||
async getChats(pagination: PaginationParams) {
|
||||
const chats = await this.store.getChats(pagination);
|
||||
// Remove unreadCount, it's not ready yet
|
||||
chats.forEach((chat) => delete chat.unreadCount);
|
||||
return chats;
|
||||
@@ -818,7 +842,7 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
archive: boolean,
|
||||
): Promise<any> {
|
||||
const jid = toJID(chatId);
|
||||
const messages = await this.store.getMessagesByJid(jid, 1);
|
||||
const messages = await this.store.getMessagesByJid(jid, {}, { limit: 1 });
|
||||
return await this.sock.chatModify(
|
||||
{ archive: archive, lastMessages: messages },
|
||||
jid,
|
||||
@@ -833,6 +857,15 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
return this.chatsPutArchive(chatId, false);
|
||||
}
|
||||
|
||||
public async chatsUnreadChat(chatId: string): Promise<any> {
|
||||
const jid = toJID(chatId);
|
||||
const messages = await this.store.getMessagesByJid(jid, {}, { limit: 1 });
|
||||
return await this.sock.chatModify(
|
||||
{ markRead: false, lastMessages: messages },
|
||||
jid,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Labels methods
|
||||
*/
|
||||
@@ -892,8 +925,8 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
return this.toWAContact(contact);
|
||||
}
|
||||
|
||||
async getContacts() {
|
||||
const contacts = await this.store.getContacts();
|
||||
async getContacts(pagination: PaginationParams) {
|
||||
const contacts = await this.store.getContacts(pagination);
|
||||
return contacts.map(this.toWAContact);
|
||||
}
|
||||
|
||||
@@ -1702,6 +1735,8 @@ function toCusFormat(remoteJid) {
|
||||
return ensureSuffix(number);
|
||||
}
|
||||
|
||||
export const ALL_JID = 'all@s.whatsapp.net';
|
||||
|
||||
/**
|
||||
* Convert from 11111111111@c.us to 11111111111@s.whatsapp.net
|
||||
* @param chatId
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Chat } from '@adiwajshing/baileys';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
|
||||
export interface IChatRepository {
|
||||
getAll(): Promise<Chat[]>;
|
||||
|
||||
getAllByIds(ids: string[]): Promise<Chat[]>;
|
||||
|
||||
getAllWithMessages(limit?: number, offset?: number): Promise<Chat[]>;
|
||||
getAllWithMessages(pagination: PaginationParams): Promise<Chat[]>;
|
||||
|
||||
getById(id: string): Promise<Chat | null>;
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Contact } from '@adiwajshing/baileys';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
|
||||
export interface IContactRepository {
|
||||
getAll(): Promise<Contact[]>;
|
||||
getAll(pagination?: PaginationParams): Promise<Contact[]>;
|
||||
|
||||
getById(id: string): Promise<Contact | null>;
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { GetChatMessagesFilter } from '@waha/structures/chats.dto';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
|
||||
export interface IMessagesRepository {
|
||||
deleteAll(): Promise<void>;
|
||||
|
||||
@@ -5,7 +8,11 @@ export interface IMessagesRepository {
|
||||
|
||||
upsertOne(message: any): Promise<void>;
|
||||
|
||||
getAllByJid(jid: string, limit: number): Promise<any[]>;
|
||||
getAllByJid(
|
||||
jid: string,
|
||||
filter: GetChatMessagesFilter,
|
||||
pagination: PaginationParams,
|
||||
): Promise<any[]>;
|
||||
|
||||
getByJidById(jid: string, id: string): Promise<any | null>;
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ import {
|
||||
proto,
|
||||
} from '@adiwajshing/baileys';
|
||||
import { Label } from '@adiwajshing/baileys/lib/Types/Label';
|
||||
import { GetChatMessagesFilter } from '@waha/structures/chats.dto';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
|
||||
export interface INowebStore {
|
||||
presences: any;
|
||||
@@ -17,11 +19,17 @@ export interface INowebStore {
|
||||
|
||||
loadMessage(jid: string, id: string): Promise<proto.IWebMessageInfo>;
|
||||
|
||||
getMessagesByJid(chatId: string, limit: number): Promise<any>;
|
||||
getMessagesByJid(
|
||||
chatId: string,
|
||||
filter: GetChatMessagesFilter,
|
||||
pagination: PaginationParams,
|
||||
): Promise<any>;
|
||||
|
||||
getChats(limit?: number, offset?: number): Promise<Chat[]>;
|
||||
getMessageById(chatId: string, messageId: string): Promise<any>;
|
||||
|
||||
getContacts(): Promise<Contact[]>;
|
||||
getChats(pagination: PaginationParams): Promise<Chat[]>;
|
||||
|
||||
getContacts(pagination: PaginationParams): Promise<Contact[]>;
|
||||
|
||||
getContactById(jid: string): Promise<Contact>;
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Chat, Contact, makeInMemoryStore, proto } from '@adiwajshing/baileys';
|
||||
import { Label } from '@adiwajshing/baileys/lib/Types/Label';
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
import { GetChatMessagesFilter } from '@waha/structures/chats.dto';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
|
||||
import { INowebStore } from './INowebStore';
|
||||
|
||||
@@ -37,15 +39,23 @@ export class NowebInMemoryStore implements INowebStore {
|
||||
return this.store.loadMessage(jid, id);
|
||||
}
|
||||
|
||||
getMessagesByJid(chatId: string, limit: number): Promise<any> {
|
||||
getMessagesByJid(
|
||||
chatId: string,
|
||||
filter: GetChatMessagesFilter,
|
||||
pagination: PaginationParams,
|
||||
): Promise<any> {
|
||||
throw new BadRequestException(this.errorMessage);
|
||||
}
|
||||
|
||||
getChats(limit?: number, offset?: number): Promise<Chat[]> {
|
||||
getMessageById(chatId: string, messageId: string): Promise<any> {
|
||||
throw new BadRequestException(this.errorMessage);
|
||||
}
|
||||
|
||||
getContacts(): Promise<Contact[]> {
|
||||
getChats(pagination: PaginationParams): Promise<Chat[]> {
|
||||
throw new BadRequestException(this.errorMessage);
|
||||
}
|
||||
|
||||
getContacts(pagination: PaginationParams): Promise<Contact[]> {
|
||||
throw new BadRequestException(this.errorMessage);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ import {
|
||||
} from '@adiwajshing/baileys/lib/Types/LabelAssociation';
|
||||
import { ILabelAssociationRepository } from '@waha/core/engines/noweb/store/ILabelAssociationsRepository';
|
||||
import { ILabelsRepository } from '@waha/core/engines/noweb/store/ILabelsRepository';
|
||||
import { GetChatMessagesFilter } from '@waha/structures/chats.dto';
|
||||
import { PaginationParams, SortOrder } from '@waha/structures/pagination.dto';
|
||||
import { toNumber } from 'lodash';
|
||||
import { Logger } from 'pino';
|
||||
|
||||
@@ -322,20 +324,32 @@ export class NowebPersistentStore implements INowebStore {
|
||||
return proto.WebMessageInfo.fromObject(data);
|
||||
}
|
||||
|
||||
getMessagesByJid(chatId: string, limit: number) {
|
||||
return this.messagesRepo.getAllByJid(toJID(chatId), toNumber(limit));
|
||||
getMessagesByJid(
|
||||
chatId: string,
|
||||
filter: GetChatMessagesFilter,
|
||||
pagination: PaginationParams,
|
||||
): Promise<any> {
|
||||
pagination.sortBy = 'messageTimestamp';
|
||||
pagination.sortOrder = SortOrder.DESC;
|
||||
return this.messagesRepo.getAllByJid(chatId, filter, pagination);
|
||||
}
|
||||
|
||||
getChats(limit?: number, offset?: number): Promise<Chat[]> {
|
||||
return this.chatRepo.getAllWithMessages(limit, offset);
|
||||
getMessageById(chatId: string, messageId: string): Promise<any> {
|
||||
return this.messagesRepo.getByJidById(chatId, messageId);
|
||||
}
|
||||
|
||||
getChats(pagination: PaginationParams): Promise<Chat[]> {
|
||||
pagination.sortBy ||= 'conversationTimestamp';
|
||||
pagination.sortOrder ||= SortOrder.DESC;
|
||||
return this.chatRepo.getAllWithMessages(pagination);
|
||||
}
|
||||
|
||||
getContactById(jid) {
|
||||
return this.contactRepo.getById(jid);
|
||||
}
|
||||
|
||||
getContacts() {
|
||||
return this.contactRepo.getAll();
|
||||
getContacts(pagination: PaginationParams) {
|
||||
return this.contactRepo.getAll(pagination);
|
||||
}
|
||||
|
||||
getLabels(): Promise<Label[]> {
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
import { Chat } from '@adiwajshing/baileys';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
import { KnexPaginator } from '@waha/utils/Paginator';
|
||||
|
||||
import { IChatRepository } from '../IChatRepository';
|
||||
import { NOWEBSqlite3KVRepository } from './NOWEBSqlite3KVRepository';
|
||||
|
||||
class ChatPaginator extends KnexPaginator {
|
||||
indexes = ['id', 'conversationTimestamp'];
|
||||
}
|
||||
|
||||
export class Sqlite3ChatRepository
|
||||
extends NOWEBSqlite3KVRepository<Chat>
|
||||
implements IChatRepository
|
||||
{
|
||||
async getAllWithMessages(limit?: number, offset?: number): Promise<Chat[]> {
|
||||
protected Paginator = ChatPaginator;
|
||||
|
||||
async getAllWithMessages(pagination: PaginationParams): Promise<Chat[]> {
|
||||
// Get chats with conversationTimestamp is not Null
|
||||
let query = this.select()
|
||||
.whereNotNull('conversationTimestamp')
|
||||
.orderBy('conversationTimestamp', 'desc');
|
||||
if (limit != null) {
|
||||
query = query.limit(limit);
|
||||
}
|
||||
if (offset != null) {
|
||||
query = query.offset(offset);
|
||||
}
|
||||
let query = this.select().whereNotNull('conversationTimestamp');
|
||||
query = this.pagination(query, pagination);
|
||||
return await this.all(query);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,16 @@
|
||||
import { Contact } from '@adiwajshing/baileys';
|
||||
import { KnexPaginator } from '@waha/utils/Paginator';
|
||||
|
||||
import { IContactRepository } from '../IContactRepository';
|
||||
import { NOWEBSqlite3KVRepository } from './NOWEBSqlite3KVRepository';
|
||||
|
||||
class ContactPaginator extends KnexPaginator {
|
||||
indexes = ['id'];
|
||||
}
|
||||
|
||||
export class Sqlite3ContactRepository
|
||||
extends NOWEBSqlite3KVRepository<Contact>
|
||||
implements IContactRepository {}
|
||||
implements IContactRepository
|
||||
{
|
||||
protected Paginator = ContactPaginator;
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
import { ALL_JID } from '@waha/core/engines/noweb/session.noweb.core';
|
||||
import { GetChatMessagesFilter } from '@waha/structures/chats.dto';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
|
||||
import { IMessagesRepository } from '../IMessagesRepository';
|
||||
import { NOWEBSqlite3KVRepository } from './NOWEBSqlite3KVRepository';
|
||||
|
||||
@@ -9,11 +13,36 @@ export class Sqlite3MessagesRepository
|
||||
return this.upsertMany(messages);
|
||||
}
|
||||
|
||||
getAllByJid(jid: string, limit: number): Promise<any[]> {
|
||||
const query = this.select()
|
||||
.where({ jid: jid })
|
||||
.limit(limit)
|
||||
.orderBy('messageTimestamp', 'DESC');
|
||||
async getAllByJid(
|
||||
jid: string,
|
||||
filter: GetChatMessagesFilter,
|
||||
pagination: PaginationParams,
|
||||
): Promise<any[]> {
|
||||
let query = this.select();
|
||||
if (jid !== ALL_JID) {
|
||||
query = this.select().where({ jid: jid });
|
||||
}
|
||||
if (filter['filter.timestamp.lte'] != null) {
|
||||
query = query.where(
|
||||
'messageTimestamp',
|
||||
'<=',
|
||||
filter['filter.timestamp.lte'],
|
||||
);
|
||||
}
|
||||
if (filter['filter.timestamp.gte'] != null) {
|
||||
query = query.where(
|
||||
'messageTimestamp',
|
||||
'>=',
|
||||
filter['filter.timestamp.gte'],
|
||||
);
|
||||
}
|
||||
if (filter['filter.fromMe'] != null) {
|
||||
// filter by data->"$.key.fromMe"
|
||||
query = query.whereRaw("data->'$.key.fromMe' = ?", [
|
||||
filter['filter.fromMe'] ? 'true' : 'false',
|
||||
]);
|
||||
}
|
||||
query = this.pagination(query, pagination);
|
||||
return this.all(query);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import pino, { Logger } from 'pino';
|
||||
import { AuthStrategy, Client } from 'whatsapp-web.js';
|
||||
|
||||
async function isValidPath(path: string) {
|
||||
try {
|
||||
await fs.promises.access(path);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class LocalAuth implements AuthStrategy {
|
||||
private readonly logger: Logger;
|
||||
|
||||
private client: Client;
|
||||
private readonly clientId: string;
|
||||
private readonly dataPath: string;
|
||||
private readonly rmMaxRetries: number;
|
||||
|
||||
private userDataDir: string;
|
||||
|
||||
setup(client: Client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
constructor({ clientId, dataPath, rmMaxRetries, logger }) {
|
||||
const idRegex = /^[-_\w]+$/i;
|
||||
if (clientId && !idRegex.test(clientId)) {
|
||||
throw new Error(
|
||||
'Invalid clientId. Only alphanumeric characters, underscores and hyphens are allowed.',
|
||||
);
|
||||
}
|
||||
|
||||
this.dataPath = path.resolve(dataPath || './.wwebjs_auth/');
|
||||
this.clientId = clientId;
|
||||
this.rmMaxRetries = rmMaxRetries ?? 4;
|
||||
this.logger = logger || pino({ name: LocalAuth.name });
|
||||
}
|
||||
|
||||
async beforeBrowserInitialized() {
|
||||
// @ts-ignore
|
||||
const puppeteerOpts = this.client.options.puppeteer;
|
||||
const sessionDirName = this.clientId
|
||||
? `session-${this.clientId}`
|
||||
: 'session';
|
||||
const dirPath = path.join(this.dataPath, sessionDirName);
|
||||
|
||||
if (puppeteerOpts.userDataDir && puppeteerOpts.userDataDir !== dirPath) {
|
||||
throw new Error(
|
||||
'LocalAuth is not compatible with a user-supplied userDataDir.',
|
||||
);
|
||||
}
|
||||
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
|
||||
// @ts-ignore
|
||||
this.client.options.puppeteer = {
|
||||
...puppeteerOpts,
|
||||
userDataDir: dirPath,
|
||||
};
|
||||
|
||||
this.userDataDir = dirPath;
|
||||
await this.removeSingletonFiles(dirPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find in direction Singleton* files and try to remove it
|
||||
* Fix for SingletonLock and other files
|
||||
*/
|
||||
private async removeSingletonFiles(dir: string) {
|
||||
const files = await fs.promises.readdir(dir);
|
||||
for (const file of files) {
|
||||
if (file.startsWith('Singleton')) {
|
||||
const filePath = path.join(dir, file);
|
||||
try {
|
||||
await fs.promises.rm(filePath, {
|
||||
maxRetries: this.rmMaxRetries,
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
} catch (err) {
|
||||
this.logger.error(err, `Error deleting: ${filePath}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async logout() {
|
||||
if (this.userDataDir) {
|
||||
await this.removePathSilently(this.userDataDir);
|
||||
}
|
||||
}
|
||||
|
||||
private async removePathSilently(path: string) {
|
||||
const exists = await isValidPath(path);
|
||||
if (!exists) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await fs.promises.rm(path, {
|
||||
maxRetries: this.rmMaxRetries,
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
} catch (err) {
|
||||
this.logger.error(err, `Error deleting: ${path}`);
|
||||
}
|
||||
}
|
||||
|
||||
async afterBrowserInitialized() {
|
||||
return;
|
||||
}
|
||||
|
||||
async onAuthenticationNeeded() {
|
||||
return {
|
||||
failed: false,
|
||||
restart: false,
|
||||
failureEventPayload: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
async getAuthEventPayload() {
|
||||
return;
|
||||
}
|
||||
|
||||
async afterAuthReady() {
|
||||
return;
|
||||
}
|
||||
|
||||
async disconnect() {
|
||||
return;
|
||||
}
|
||||
|
||||
async destroy() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
exports.LoadUtils = () => {
|
||||
window.WAHA = {};
|
||||
|
||||
window.WAHA.getChats = async (limit, offset) => {
|
||||
let chats = window.Store.Chat.getModelsArray();
|
||||
if (limit || offset) {
|
||||
offset = offset || 0;
|
||||
limit = limit || Infinity;
|
||||
chats = chats.slice(offset, offset + limit);
|
||||
}
|
||||
|
||||
const chatPromises = chats.map((chat) => window.WWebJS.getChatModel(chat));
|
||||
return await Promise.all(chatPromises);
|
||||
};
|
||||
};
|
||||
@@ -1,7 +1,17 @@
|
||||
import { GetChatMessagesFilter } from '@waha/structures/chats.dto';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
import * as lodash from 'lodash';
|
||||
import { Client } from 'whatsapp-web.js';
|
||||
import { Message } from 'whatsapp-web.js/src/structures';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { LoadUtils } = require('./WahaInjected');
|
||||
const { LoadWAHA } = require('./_WAHA.js');
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { LoadLodash } = require('./_lodash.js');
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { LoadPaginator } = require('./_Paginator.js');
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const ChatFactory = require('whatsapp-web.js/src/factories/ChatFactory');
|
||||
@@ -12,27 +22,110 @@ export class WebjsClient extends Client {
|
||||
// We can still call and override it
|
||||
// @ts-ignore
|
||||
await super.inject();
|
||||
//Load util functions (serializers, helper functions)
|
||||
await this.pupPage.evaluate(LoadUtils);
|
||||
|
||||
// Load util functions (serializers, helper functions)
|
||||
await this.pupPage.evaluate(LoadLodash);
|
||||
await this.pupPage.evaluate(LoadPaginator);
|
||||
await this.pupPage.evaluate(LoadWAHA);
|
||||
}
|
||||
|
||||
async getChats(limit?: number, offset?: number) {
|
||||
if (limit == null && offset == null) {
|
||||
async unpair() {
|
||||
await this.pupPage.evaluate(async () => {
|
||||
if (
|
||||
// @ts-ignore
|
||||
window.Store &&
|
||||
// @ts-ignore
|
||||
window.Store.AppState &&
|
||||
// @ts-ignore
|
||||
typeof window.Store.AppState.logout === 'function'
|
||||
) {
|
||||
// @ts-ignore
|
||||
await window.Store.AppState.logout();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async getChats(pagination?: PaginationParams) {
|
||||
if (lodash.isEmpty(pagination)) {
|
||||
return await super.getChats();
|
||||
}
|
||||
return await this.getChats2(limit, offset);
|
||||
}
|
||||
|
||||
private async getChats2(limit?: number, offset?: number) {
|
||||
const chats = await this.pupPage.evaluate(
|
||||
async (limit, offset) => {
|
||||
// @ts-ignore
|
||||
return await window.WAHA.getChats(limit, offset);
|
||||
},
|
||||
limit,
|
||||
offset,
|
||||
);
|
||||
// Get paginated chats
|
||||
pagination.limit ||= Infinity;
|
||||
pagination.offset ||= 0;
|
||||
|
||||
const chats = await this.pupPage.evaluate(async (pagination) => {
|
||||
// @ts-ignore
|
||||
return await window.WAHA.getChats(pagination);
|
||||
}, pagination);
|
||||
|
||||
return chats.map((chat) => ChatFactory.create(this, chat));
|
||||
}
|
||||
|
||||
async getMessages(
|
||||
chatId: string,
|
||||
filter: GetChatMessagesFilter,
|
||||
pagination: PaginationParams,
|
||||
) {
|
||||
const messages = await this.pupPage.evaluate(
|
||||
async (chatId, filter, pagination) => {
|
||||
pagination.limit ||= Infinity;
|
||||
pagination.offset ||= 0;
|
||||
|
||||
const msgFilter = (m) => {
|
||||
if (m.isNotification) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
filter['filter.fromMe'] != null &&
|
||||
m.id.fromMe !== filter['filter.fromMe']
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
filter['filter.timestamp.gte'] != null &&
|
||||
m.t < filter['filter.timestamp.gte']
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
filter['filter.timestamp.lte'] != null &&
|
||||
m.t > filter['filter.timestamp.lte']
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
const chat = await window.WWebJS.getChat(chatId, { getAsModel: false });
|
||||
let msgs = chat.msgs.getModelsArray().filter(msgFilter);
|
||||
|
||||
while (msgs.length < pagination.limit + pagination.offset) {
|
||||
const loadedMessages =
|
||||
// @ts-ignore
|
||||
await window.Store.ConversationMsgs.loadEarlierMsgs(chat);
|
||||
if (!loadedMessages || !loadedMessages.length) break;
|
||||
msgs = [...loadedMessages.filter(msgFilter), ...msgs];
|
||||
}
|
||||
|
||||
if (msgs.length > pagination.limit + pagination.offset) {
|
||||
// sort by t - new first
|
||||
msgs = msgs.sort((a, b) => b.t - a.t);
|
||||
msgs = msgs.slice(
|
||||
pagination.offset,
|
||||
pagination.limit + pagination.offset,
|
||||
);
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return msgs.map((m) => window.WWebJS.getMessageModel(m));
|
||||
},
|
||||
chatId,
|
||||
filter,
|
||||
pagination,
|
||||
);
|
||||
|
||||
return messages.map((m) => new Message(this, m));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
exports.LoadPaginator = () => {
|
||||
class Paginator {
|
||||
constructor(pagination) {
|
||||
this.pagination = pagination;
|
||||
}
|
||||
|
||||
apply(data) {
|
||||
if (window.lodash.isEmpty(this.pagination)) {
|
||||
return data;
|
||||
}
|
||||
return this.limit(this.sort(data));
|
||||
}
|
||||
|
||||
sort(data) {
|
||||
if (!this.pagination?.sortBy) {
|
||||
return data;
|
||||
}
|
||||
return window.lodash.orderBy(
|
||||
data,
|
||||
[this.pagination.sortBy],
|
||||
[this.pagination.sortOrder || 'asc'],
|
||||
);
|
||||
}
|
||||
|
||||
limit(data) {
|
||||
if (!this.pagination?.limit) {
|
||||
return data;
|
||||
}
|
||||
const offset = this.pagination.offset || 0;
|
||||
const limit = this.pagination.limit || Infinity;
|
||||
return data.slice(offset, offset + limit);
|
||||
}
|
||||
}
|
||||
window.Paginator = Paginator;
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
exports.LoadWAHA = () => {
|
||||
window.WAHA = {};
|
||||
|
||||
window.WAHA.getChats = async (pagination) => {
|
||||
let chats = window.Store.Chat.getModelsArray().slice();
|
||||
const paginator = new window.Paginator(pagination);
|
||||
chats = paginator.apply(chats);
|
||||
const chatPromises = chats.map((chat) => window.WWebJS.getChatModel(chat));
|
||||
return await Promise.all(chatPromises);
|
||||
};
|
||||
};
|
||||
File diff suppressed because it is too large.
Load diff
@@ -3,6 +3,7 @@ import {
|
||||
WAHAInternalEvent,
|
||||
WhatsappSession,
|
||||
} from '@waha/core/abc/session.abc';
|
||||
import { LocalAuth } from '@waha/core/engines/webjs/LocalAuth';
|
||||
import { WebjsClient } from '@waha/core/engines/webjs/WebjsClient';
|
||||
import {
|
||||
AvailableInPlusVersion,
|
||||
@@ -10,7 +11,7 @@ import {
|
||||
} from '@waha/core/exceptions';
|
||||
import { IMediaEngineProcessor } from '@waha/core/media/IMediaEngineProcessor';
|
||||
import { QR } from '@waha/core/QR';
|
||||
import { parseBool, splitAt } from '@waha/helpers';
|
||||
import { splitAt } from '@waha/helpers';
|
||||
import { PairingCodeResponse } from '@waha/structures/auth.dto';
|
||||
import { CallData } from '@waha/structures/calls.dto';
|
||||
import {
|
||||
@@ -19,12 +20,17 @@ import {
|
||||
CreateChannelRequest,
|
||||
ListChannelsQuery,
|
||||
} from '@waha/structures/channels.dto';
|
||||
import { ChatArchiveEvent, GetChatsQuery } from '@waha/structures/chats.dto';
|
||||
import {
|
||||
ChatArchiveEvent,
|
||||
ChatSortField,
|
||||
GetChatMessageQuery,
|
||||
GetChatMessagesFilter,
|
||||
GetChatMessagesQuery,
|
||||
} from '@waha/structures/chats.dto';
|
||||
import {
|
||||
ChatRequest,
|
||||
CheckNumberStatusQuery,
|
||||
EditMessageRequest,
|
||||
GetMessageQuery,
|
||||
MessageFileRequest,
|
||||
MessageForwardRequest,
|
||||
MessageImageRequest,
|
||||
@@ -54,10 +60,12 @@ import {
|
||||
} from '@waha/structures/groups.dto';
|
||||
import { Label, LabelID } from '@waha/structures/labels.dto';
|
||||
import { ReplyToMessage } from '@waha/structures/message.dto';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
import { WAMessage, WAMessageReaction } from '@waha/structures/responses.dto';
|
||||
import { MeInfo } from '@waha/structures/sessions.dto';
|
||||
import { WAMessageRevokedBody } from '@waha/structures/webhooks.dto';
|
||||
import { waitUntil } from '@waha/utils/promiseTimeout';
|
||||
import { PaginatorInMemory } from '@waha/utils/Paginator';
|
||||
import { sleep, waitUntil } from '@waha/utils/promiseTimeout';
|
||||
import { SingleDelayedJobRunner } from '@waha/utils/SingleDelayedJobRunner';
|
||||
import {
|
||||
Call,
|
||||
@@ -144,6 +152,12 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
|
||||
protected async buildClient() {
|
||||
const clientOptions = this.getClientOptions();
|
||||
clientOptions.authStrategy = new LocalAuth({
|
||||
clientId: this.name,
|
||||
dataPath: undefined,
|
||||
logger: this.logger,
|
||||
rmMaxRetries: undefined,
|
||||
});
|
||||
this.addProxyConfig(clientOptions);
|
||||
return new WebjsClient(clientOptions);
|
||||
}
|
||||
@@ -193,15 +207,13 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
.then(() => {
|
||||
// Listen for browser disconnected event
|
||||
this.whatsapp.pupBrowser.on('disconnected', () => {
|
||||
this.status = WAHASessionStatus.FAILED;
|
||||
this.logger.error('The browser has been disconnected');
|
||||
this.restartClient();
|
||||
this.failed();
|
||||
});
|
||||
// Listen for page close event
|
||||
this.whatsapp.pupPage.on('close', () => {
|
||||
this.status = WAHASessionStatus.FAILED;
|
||||
this.logger.error('The WhatsApp Web page has been closed');
|
||||
this.restartClient();
|
||||
this.failed();
|
||||
});
|
||||
|
||||
// Listen for page error event
|
||||
@@ -216,9 +228,8 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.status = WAHASessionStatus.FAILED;
|
||||
this.logger.error(error);
|
||||
this.restartClient();
|
||||
this.failed();
|
||||
return;
|
||||
});
|
||||
if (this.isDebugEnabled()) {
|
||||
@@ -233,8 +244,7 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
await this.init().catch((err) => {
|
||||
this.logger.error('Failed to start the client');
|
||||
this.logger.error(err, err.stack);
|
||||
this.status = WAHASessionStatus.FAILED;
|
||||
this.restartClient();
|
||||
this.failed();
|
||||
});
|
||||
return this;
|
||||
}
|
||||
@@ -247,6 +257,20 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
await this.end();
|
||||
}
|
||||
|
||||
protected failed() {
|
||||
// We'll restart the client if it's in the process of unpairing
|
||||
this.status = WAHASessionStatus.FAILED;
|
||||
this.restartClient();
|
||||
}
|
||||
|
||||
async unpair() {
|
||||
this.unpairing = true;
|
||||
this.shouldRestart = false;
|
||||
await this.whatsapp.unpair();
|
||||
// Wait for unpairing to complete
|
||||
await sleep(2_000);
|
||||
}
|
||||
|
||||
private async end() {
|
||||
this.engineStateCheckDelayedJob.cancel();
|
||||
try {
|
||||
@@ -318,13 +342,13 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
});
|
||||
|
||||
this.whatsapp.on(Events.AUTHENTICATION_FAILURE, (args) => {
|
||||
this.status = WAHASessionStatus.FAILED;
|
||||
this.failed();
|
||||
this.qr.save('');
|
||||
this.logger.info({ args: args }, `Session has failed to authenticate!`);
|
||||
});
|
||||
|
||||
this.whatsapp.on(Events.DISCONNECTED, (args) => {
|
||||
this.status = WAHASessionStatus.FAILED;
|
||||
this.failed();
|
||||
this.qr.save('');
|
||||
this.logger.info({ args: args }, `Session has been disconnected!`);
|
||||
});
|
||||
@@ -340,7 +364,7 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
|
||||
log.info(`Session state changed to bad state, waiting for recovery...`);
|
||||
this.engineStateCheckDelayedJob.schedule(async () => {
|
||||
if (!this.startDelayedJob.scheduled) {
|
||||
if (this.startDelayedJob.scheduled) {
|
||||
log.info('Session is restarting already, skip check.');
|
||||
return;
|
||||
}
|
||||
@@ -493,10 +517,6 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
await chat.clearState();
|
||||
}
|
||||
|
||||
async getMessages(query: GetMessageQuery) {
|
||||
return this.getChatMessages(query.chatId, query.limit, query.downloadMedia);
|
||||
}
|
||||
|
||||
async setReaction(request: MessageReactionRequest) {
|
||||
const message = this.recreateMessage(request.messageId);
|
||||
return message.react(request.reaction);
|
||||
@@ -525,18 +545,39 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
/**
|
||||
* Chats methods
|
||||
*/
|
||||
getChats(query: GetChatsQuery) {
|
||||
return this.whatsapp.getChats(query.limit, query.offset);
|
||||
getChats(pagination: PaginationParams) {
|
||||
switch (pagination.sortBy) {
|
||||
case ChatSortField.ID:
|
||||
pagination.sortBy = 'id._serialized';
|
||||
break;
|
||||
case ChatSortField.CONVERSATION_TIMESTAMP:
|
||||
pagination.sortBy = 't';
|
||||
break;
|
||||
}
|
||||
return this.whatsapp.getChats(pagination);
|
||||
}
|
||||
|
||||
async getChatMessages(chatId: string, limit: number, downloadMedia: boolean) {
|
||||
downloadMedia = parseBool(downloadMedia);
|
||||
const chat: Chat = await this.whatsapp.getChatById(
|
||||
public async getChatMessages(
|
||||
chatId: string,
|
||||
query: GetChatMessagesQuery,
|
||||
filter: GetChatMessagesFilter,
|
||||
) {
|
||||
if (chatId == 'all') {
|
||||
throw new NotImplementedByEngineError(
|
||||
"Can not get messages from 'all' in WEBJS",
|
||||
);
|
||||
}
|
||||
|
||||
const limit = query.limit;
|
||||
const downloadMedia = query.downloadMedia;
|
||||
// Test there's chat with id
|
||||
await this.whatsapp.getChatById(this.ensureSuffix(chatId));
|
||||
const pagination: PaginationParams = query;
|
||||
const messages = await this.whatsapp.getMessages(
|
||||
this.ensureSuffix(chatId),
|
||||
filter,
|
||||
pagination,
|
||||
);
|
||||
const messages = await chat.fetchMessages({
|
||||
limit: limit,
|
||||
});
|
||||
const promises = [];
|
||||
for (const msg of messages) {
|
||||
promises.push(this.processIncomingMessage(msg, downloadMedia));
|
||||
@@ -546,6 +587,16 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
return result;
|
||||
}
|
||||
|
||||
public async getChatMessage(
|
||||
chatId: string,
|
||||
messageId: string,
|
||||
query: GetChatMessageQuery,
|
||||
): Promise<null | WAMessage> {
|
||||
const message = await this.whatsapp.getMessageById(messageId);
|
||||
if (!message) return null;
|
||||
return await this.processIncomingMessage(message, query.downloadMedia);
|
||||
}
|
||||
|
||||
async deleteChat(chatId) {
|
||||
const chat = await this.whatsapp.getChatById(chatId);
|
||||
return chat.delete();
|
||||
@@ -566,6 +617,11 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
return this.whatsapp.unarchiveChat(id);
|
||||
}
|
||||
|
||||
public chatsUnreadChat(chatId: string): Promise<any> {
|
||||
const id = this.ensureSuffix(chatId);
|
||||
return this.whatsapp.markChatUnread(id);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Label methods
|
||||
@@ -611,10 +667,11 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
.then(this.toWAContact);
|
||||
}
|
||||
|
||||
getContacts() {
|
||||
return this.whatsapp
|
||||
.getContacts()
|
||||
.then((contacts) => contacts.map(this.toWAContact));
|
||||
async getContacts(pagination: PaginationParams) {
|
||||
const contactsWEBJS = await this.whatsapp.getContacts();
|
||||
const contacts = contactsWEBJS.map(this.toWAContact);
|
||||
const paginator = new PaginatorInMemory(pagination);
|
||||
return paginator.apply(contacts);
|
||||
}
|
||||
|
||||
public async getContactAbout(query: ContactQuery) {
|
||||
|
||||
@@ -6,7 +6,7 @@ export class NotImplementedByEngineError extends UnprocessableEntityException {
|
||||
constructor(msg = '') {
|
||||
let error = 'The method is not implemented by the engine.';
|
||||
if (msg) {
|
||||
error += ` ${msg}`;
|
||||
error = `${msg} ${error}`;
|
||||
}
|
||||
super(error);
|
||||
}
|
||||
|
||||
@@ -211,6 +211,19 @@ export class SessionManagerCore extends SessionManager {
|
||||
await sleep(this.SESSION_STOP_TIMEOUT);
|
||||
}
|
||||
|
||||
async unpair(name: string) {
|
||||
if (!this.session) {
|
||||
return;
|
||||
}
|
||||
const session = this.session as WhatsappSession;
|
||||
|
||||
this.log.info('Unpairing the device from account...', { session: name });
|
||||
await session.unpair().catch((err) => {
|
||||
this.log.warn(`Error while unpairing from device: ${err}`);
|
||||
});
|
||||
await sleep(1000);
|
||||
}
|
||||
|
||||
async logout(name: string): Promise<void> {
|
||||
this.onlyDefault(name);
|
||||
await this.sessionAuthRepository.clean(name);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
import { KnexPaginator } from '@waha/utils/Paginator';
|
||||
import { Database } from 'better-sqlite3';
|
||||
import Knex from 'knex';
|
||||
import Knex, { QueryBuilder } from 'knex';
|
||||
|
||||
import { Field, Schema } from './Schema';
|
||||
|
||||
@@ -15,6 +17,8 @@ export class Sqlite3KVRepository<Entity> {
|
||||
private readonly columns: Field[];
|
||||
private knex: Knex.Knex;
|
||||
|
||||
protected Paginator = KnexPaginator;
|
||||
|
||||
constructor(
|
||||
db: Database,
|
||||
schema: Schema,
|
||||
@@ -29,8 +33,10 @@ export class Sqlite3KVRepository<Entity> {
|
||||
this.knex = Knex({ client: 'better-sqlite3', useNullAsDefault: true });
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return this.all(this.select());
|
||||
getAll(pagination?: PaginationParams) {
|
||||
let query = this.select();
|
||||
query = this.pagination(query, pagination);
|
||||
return this.all(query);
|
||||
}
|
||||
|
||||
getAllByIds(ids: string[]) {
|
||||
@@ -163,4 +169,9 @@ export class Sqlite3KVRepository<Entity> {
|
||||
protected parse(row: any) {
|
||||
return JSON.parse(row.data);
|
||||
}
|
||||
|
||||
protected pagination(query: any, pagination?: PaginationParams) {
|
||||
const paginator = new this.Paginator(pagination);
|
||||
return paginator.apply(query);
|
||||
}
|
||||
}
|
||||
+68
-12
@@ -1,35 +1,91 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { BooleanString } from '@waha/nestjs/validation/BooleanString';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
import { ChatIdProperty } from '@waha/structures/properties.dto';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsNumber, IsOptional } from 'class-validator';
|
||||
|
||||
import { SessionQuery } from './base.dto';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
import { IsBoolean, IsEnum, IsNumber, IsOptional } from 'class-validator';
|
||||
|
||||
/**
|
||||
* Queries
|
||||
*/
|
||||
|
||||
export class GetChatMessagesQuery extends SessionQuery {
|
||||
export class GetChatMessagesFilter {
|
||||
@ApiProperty({
|
||||
required: false,
|
||||
description: 'Filter messages before this timestamp (inclusive)',
|
||||
})
|
||||
@IsNumber()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
'filter.timestamp.lte'?: number;
|
||||
|
||||
@ApiProperty({
|
||||
required: false,
|
||||
description: 'Filter messages after this timestamp (inclusive)',
|
||||
})
|
||||
@IsNumber()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
'filter.timestamp.gte'?: number;
|
||||
|
||||
@ApiProperty({
|
||||
required: false,
|
||||
description: 'From me filter (by default shows all messages)',
|
||||
})
|
||||
@Transform(BooleanString)
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
'filter.fromMe'?: boolean;
|
||||
}
|
||||
|
||||
export class GetChatMessagesQuery {
|
||||
@IsNumber()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
limit: number = 100;
|
||||
|
||||
@IsNumber()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
offset?: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: true,
|
||||
required: false,
|
||||
description: 'Download media for messages',
|
||||
})
|
||||
@Transform(BooleanString)
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
downloadMedia: boolean = true;
|
||||
}
|
||||
|
||||
export class GetChatsQuery {
|
||||
@IsNumber()
|
||||
export class GetChatMessageQuery {
|
||||
@ApiProperty({
|
||||
example: true,
|
||||
required: false,
|
||||
description: 'Download media for messages',
|
||||
})
|
||||
@Transform(BooleanString)
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
limit?: number;
|
||||
downloadMedia: boolean = true;
|
||||
}
|
||||
|
||||
@IsNumber()
|
||||
export enum ChatSortField {
|
||||
CONVERSATION_TIMESTAMP = 'conversationTimestamp',
|
||||
ID = 'id',
|
||||
NAME = 'name',
|
||||
}
|
||||
|
||||
export class ChatsPaginationParams extends PaginationParams {
|
||||
@ApiProperty({
|
||||
description: 'Sort by field',
|
||||
enum: ChatSortField,
|
||||
})
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
offset?: number;
|
||||
@IsEnum(ChatSortField)
|
||||
sortBy?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,9 +4,14 @@ import {
|
||||
ApiProperty,
|
||||
getSchemaPath,
|
||||
} from '@nestjs/swagger';
|
||||
import { IsNumber, IsString } from 'class-validator';
|
||||
import { GetChatMessagesQuery } from '@waha/structures/chats.dto';
|
||||
import { IsNotEmpty, IsNumber, IsString } from 'class-validator';
|
||||
|
||||
import { SessionBaseRequest, SessionQuery } from './base.dto';
|
||||
import {
|
||||
SessionBaseRequest,
|
||||
SessionQuery,
|
||||
WHATSAPP_DEFAULT_SESSION_NAME,
|
||||
} from './base.dto';
|
||||
import {
|
||||
BinaryFile,
|
||||
RemoteFile,
|
||||
@@ -42,16 +47,12 @@ export class ChatQuery extends SessionQuery {
|
||||
chatId: string;
|
||||
}
|
||||
|
||||
export class GetMessageQuery extends ChatQuery {
|
||||
@IsNumber()
|
||||
limit: number;
|
||||
export class GetMessageQuery extends GetChatMessagesQuery {
|
||||
@IsNotEmpty()
|
||||
session: string = WHATSAPP_DEFAULT_SESSION_NAME;
|
||||
|
||||
@ApiProperty({
|
||||
example: true,
|
||||
required: false,
|
||||
description: 'Download media for messages',
|
||||
})
|
||||
downloadMedia: true;
|
||||
@ChatIdProperty()
|
||||
chatId: string;
|
||||
}
|
||||
|
||||
export class GetPresenceQuery extends ChatQuery {}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
import { ChatIdProperty } from '@waha/structures/properties.dto';
|
||||
import { IsString } from 'class-validator';
|
||||
import { IsEnum, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
import { SessionBaseRequest, SessionQuery } from './base.dto';
|
||||
|
||||
@@ -13,6 +15,21 @@ export class ContactQuery extends SessionQuery {
|
||||
contactId: string;
|
||||
}
|
||||
|
||||
enum ContactSortField {
|
||||
ID = 'id',
|
||||
NAME = 'name',
|
||||
}
|
||||
|
||||
export class ContactsPaginationParams extends PaginationParams {
|
||||
@ApiProperty({
|
||||
description: 'Sort by field',
|
||||
enum: ContactSortField,
|
||||
})
|
||||
@IsOptional()
|
||||
@IsEnum(ContactSortField)
|
||||
sortBy?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Type } from 'class-transformer';
|
||||
import { IsNumber, IsOptional, ValidateIf } from 'class-validator';
|
||||
|
||||
export enum SortOrder {
|
||||
DESC = 'desc',
|
||||
ASC = 'asc',
|
||||
}
|
||||
|
||||
export class PaginationParams {
|
||||
@IsNumber()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
limit?: number;
|
||||
|
||||
@IsNumber()
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
offset?: number;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Sort by field',
|
||||
})
|
||||
@IsOptional()
|
||||
sortBy?: string;
|
||||
|
||||
@ApiProperty({
|
||||
description:
|
||||
'Sort order - <b>desc</b>ending (Z => A, New first) or <b>asc</b>ending (A => Z, Old first)',
|
||||
})
|
||||
@IsOptional()
|
||||
sortOrder?: SortOrder;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import { PaginationParams } from '@waha/structures/pagination.dto';
|
||||
import * as lodash from 'lodash';
|
||||
|
||||
export abstract class Paginator {
|
||||
constructor(protected readonly pagination: PaginationParams) {}
|
||||
|
||||
apply<T>(data: T): T {
|
||||
if (lodash.isEmpty(this.pagination)) {
|
||||
return data;
|
||||
}
|
||||
return this.limit(this.sort(data));
|
||||
}
|
||||
|
||||
protected abstract sort(data: any);
|
||||
|
||||
protected abstract limit(data: any);
|
||||
}
|
||||
|
||||
export class PaginatorInMemory extends Paginator {
|
||||
protected sort(data: any[]) {
|
||||
if (!this.pagination?.sortBy) {
|
||||
return data;
|
||||
}
|
||||
return lodash.orderBy(
|
||||
data,
|
||||
this.pagination.sortBy,
|
||||
this.pagination.sortOrder || 'asc',
|
||||
);
|
||||
}
|
||||
|
||||
protected limit(data: any[]) {
|
||||
if (!this.pagination?.limit) {
|
||||
return data;
|
||||
}
|
||||
const offset = this.pagination.offset || 0;
|
||||
const limit = this.pagination.limit || Infinity;
|
||||
return data.slice(offset, offset + limit);
|
||||
}
|
||||
}
|
||||
|
||||
export class KnexPaginator extends Paginator {
|
||||
indexes: string[] = [];
|
||||
dataField: string = 'data';
|
||||
|
||||
protected sort(query: any) {
|
||||
if (!this.pagination?.sortBy) {
|
||||
return query;
|
||||
}
|
||||
const sortBy = this.pagination.sortBy;
|
||||
const direction = this.pagination.sortOrder || 'asc';
|
||||
if (this.indexes.includes(sortBy)) {
|
||||
return query.orderBy(sortBy, direction);
|
||||
}
|
||||
// Use data->"$.{field}"
|
||||
// Make sure to sanitize sortBy to prevent SQL injection
|
||||
// sqlite3 doesn't support binding for column names and direction
|
||||
return query.orderByRaw(`${this.dataField}->'$.${sortBy}' ${direction}`);
|
||||
}
|
||||
|
||||
protected limit(query: any) {
|
||||
const limit = this.pagination.limit;
|
||||
const offset = this.pagination.offset;
|
||||
if (limit != null) {
|
||||
query = query.limit(limit);
|
||||
}
|
||||
if (offset != null) {
|
||||
query = query.offset(offset);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
||||
export class MongoPaginator extends Paginator {
|
||||
protected sort(query: any) {
|
||||
if (!this.pagination?.sortBy) {
|
||||
return query;
|
||||
}
|
||||
const mongoDirection = this.pagination.sortOrder === 'asc' ? 1 : -1;
|
||||
return query.sort({ [this.pagination.sortBy]: mongoDirection });
|
||||
}
|
||||
|
||||
protected limit(query: any) {
|
||||
const limit = this.pagination.limit;
|
||||
const offset = this.pagination.offset;
|
||||
if (limit != null) {
|
||||
query = query.limit(limit);
|
||||
}
|
||||
if (offset != null) {
|
||||
query = query.skip(offset);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -33,7 +33,7 @@ export function getEngineName(): string {
|
||||
}
|
||||
|
||||
export const VERSION: WAHAEnvironment = {
|
||||
version: '2024.10.8',
|
||||
version: '2024.10.11',
|
||||
engine: getEngineName(),
|
||||
tier: getWAHAVersion(),
|
||||
browser: getBrowserExecutablePath(),
|
||||
|
||||
@@ -7,7 +7,7 @@ __metadata:
|
||||
|
||||
"@adiwajshing/baileys@github:devlikeapro/Baileys#fork-master-channels-678":
|
||||
version: 6.7.8
|
||||
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=d0323b92eb8365e6f32a61e41dd00010602d07f1"
|
||||
resolution: "@adiwajshing/baileys@https://github.com/devlikeapro/Baileys.git#commit=1a3d827b5d9633e0b82d95362fc07cf1060aa32f"
|
||||
dependencies:
|
||||
"@adiwajshing/keyed-db": ^0.2.4
|
||||
"@hapi/boom": ^9.1.3
|
||||
@@ -39,7 +39,7 @@ __metadata:
|
||||
optional: true
|
||||
sharp:
|
||||
optional: true
|
||||
checksum: a3b461006443713074401a17c3481aef571301e83f1fba193d06e7f9ea4c47359b5c973d0b3804e34d4e48c35bdc1a64d8c3e59a0a744e5bc9bcca591d180901
|
||||
checksum: fd4053af48069c3cdd6017075490d2061302e8006acbcf4d9a831159a1ae213548d135acbc4f2b8217c48bf989dbdc5c96a904df71becf2b0576a7a61998cc83
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -2266,20 +2266,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@puppeteer/browsers@npm:1.9.1":
|
||||
version: 1.9.1
|
||||
resolution: "@puppeteer/browsers@npm:1.9.1"
|
||||
"@puppeteer/browsers@npm:2.4.0":
|
||||
version: 2.4.0
|
||||
resolution: "@puppeteer/browsers@npm:2.4.0"
|
||||
dependencies:
|
||||
debug: 4.3.4
|
||||
extract-zip: 2.0.1
|
||||
progress: 2.0.3
|
||||
proxy-agent: 6.3.1
|
||||
tar-fs: 3.0.4
|
||||
unbzip2-stream: 1.4.3
|
||||
yargs: 17.7.2
|
||||
debug: ^4.3.6
|
||||
extract-zip: ^2.0.1
|
||||
progress: ^2.0.3
|
||||
proxy-agent: ^6.4.0
|
||||
semver: ^7.6.3
|
||||
tar-fs: ^3.0.6
|
||||
unbzip2-stream: ^1.4.3
|
||||
yargs: ^17.7.2
|
||||
bin:
|
||||
browsers: lib/cjs/main-cli.js
|
||||
checksum: 1ea82e34af882dc6d7e8392a88ec4196e206a7f65743be39c196c7068d66b9bdfa370e28c6ab09946bd2baa2182adbcbf445e79cc9bcc5242f05878ae7045b27
|
||||
checksum: c5f9890f1bf355783574c00b42e8a9bf9e4788d0dce76cc4cd50fcf80b5e5f99ae2b4325edd5350d4fb289f7dfa89f67edf8bc2da9abd53eba1f815caae97beb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -3752,15 +3753,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"agent-base@npm:6":
|
||||
version: 6.0.2
|
||||
resolution: "agent-base@npm:6.0.2"
|
||||
dependencies:
|
||||
debug: 4
|
||||
checksum: f52b6872cc96fd5f622071b71ef200e01c7c4c454ee68bc9accca90c98cfb39f2810e3e9aa330435835eedc8c23f4f8a15267f67c6e245d2b33757575bdac49d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1":
|
||||
version: 7.1.1
|
||||
resolution: "agent-base@npm:7.1.1"
|
||||
@@ -4315,6 +4307,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bare-events@npm:^2.0.0":
|
||||
version: 2.5.0
|
||||
resolution: "bare-events@npm:2.5.0"
|
||||
checksum: 5aa10716e7f33c5dfc471fd657eee2a33f2db0f78b3c83b5cdd1a45a7e7871114a69460ea96cd838807c55eb470b9e53dd0dfda8c83cced1352cc8253cebff48
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bare-events@npm:^2.2.0":
|
||||
version: 2.4.2
|
||||
resolution: "bare-events@npm:2.4.2"
|
||||
@@ -4322,6 +4321,42 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bare-fs@npm:^2.1.1":
|
||||
version: 2.3.5
|
||||
resolution: "bare-fs@npm:2.3.5"
|
||||
dependencies:
|
||||
bare-events: ^2.0.0
|
||||
bare-path: ^2.0.0
|
||||
bare-stream: ^2.0.0
|
||||
checksum: 071b1dff94a213eaf0b41693953959bf10af2deade597a56ff206a5d833579d56bc8530aa4614bb88bf39fd6d52f2404f7c36af4695109ffa756a13837ac3d91
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bare-os@npm:^2.1.0":
|
||||
version: 2.4.4
|
||||
resolution: "bare-os@npm:2.4.4"
|
||||
checksum: e90088a7dc0307c020350a28df8ec5564cae5a4b7a213d8509d70831d7064308e2ed31de801b68f474cb004ad3a0a66bd28c38374d270484d9025ee71af20396
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bare-path@npm:^2.0.0, bare-path@npm:^2.1.0":
|
||||
version: 2.1.3
|
||||
resolution: "bare-path@npm:2.1.3"
|
||||
dependencies:
|
||||
bare-os: ^2.1.0
|
||||
checksum: 20301aeb05b735852a396515464908e51e896922c3bb353ef2a09ff54e81ced94e6ad857bb0a36d2ce659c42bd43dd5c3d5643edd8faaf910ee9950c4e137b88
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bare-stream@npm:^2.0.0":
|
||||
version: 2.3.2
|
||||
resolution: "bare-stream@npm:2.3.2"
|
||||
dependencies:
|
||||
streamx: ^2.20.0
|
||||
checksum: 051c817f0b74617d99002a91c61e6fa2b56bff3bb329c5ab4a817287bc1f46f3aef5f13bc11201b344a91873782a45f755d3910012381f16e47feee2194fd792
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"base64-js@npm:^1.3.1":
|
||||
version: 1.5.1
|
||||
resolution: "base64-js@npm:1.5.1"
|
||||
@@ -4599,6 +4634,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bufferutil@npm:^4.0.8":
|
||||
version: 4.0.8
|
||||
resolution: "bufferutil@npm:4.0.8"
|
||||
dependencies:
|
||||
node-gyp: latest
|
||||
node-gyp-build: ^4.3.0
|
||||
checksum: 7e9a46f1867dca72fda350966eb468eca77f4d623407b0650913fadf73d5750d883147d6e5e21c56f9d3b0bdc35d5474e80a600b9f31ec781315b4d2469ef087
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"busboy@npm:^1.0.0":
|
||||
version: 1.6.0
|
||||
resolution: "busboy@npm:1.6.0"
|
||||
@@ -4838,15 +4883,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chromium-bidi@npm:0.5.8":
|
||||
version: 0.5.8
|
||||
resolution: "chromium-bidi@npm:0.5.8"
|
||||
"chromium-bidi@npm:0.8.0":
|
||||
version: 0.8.0
|
||||
resolution: "chromium-bidi@npm:0.8.0"
|
||||
dependencies:
|
||||
mitt: 3.0.1
|
||||
urlpattern-polyfill: 10.0.0
|
||||
zod: 3.23.8
|
||||
peerDependencies:
|
||||
devtools-protocol: "*"
|
||||
checksum: 4e4bb8d3907b3a17adf15e95220fc16733e0c4b03d0eccb071010a78ca85d122a0435da95ab657ade6d15e8c9b3cd917088b6128a0aec45e4444916625a4076f
|
||||
checksum: 5c5b12e00564b6f145511ca4c159db24b07bfc6a1eb6add26d88c4331d74ef6cc8cd2f58bc169e0726c689910a1888313722f39ccab1bac14284d1918155d5e9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -5191,7 +5237,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cosmiconfig@npm:9.0.0":
|
||||
"cosmiconfig@npm:^7.0.1":
|
||||
version: 7.1.0
|
||||
resolution: "cosmiconfig@npm:7.1.0"
|
||||
dependencies:
|
||||
"@types/parse-json": ^4.0.0
|
||||
import-fresh: ^3.2.1
|
||||
parse-json: ^5.0.0
|
||||
path-type: ^4.0.0
|
||||
yaml: ^1.10.0
|
||||
checksum: c53bf7befc1591b2651a22414a5e786cd5f2eeaa87f3678a3d49d6069835a9d8d1aef223728e98aa8fec9a95bf831120d245096db12abe019fecb51f5696c96f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cosmiconfig@npm:^9.0.0":
|
||||
version: 9.0.0
|
||||
resolution: "cosmiconfig@npm:9.0.0"
|
||||
dependencies:
|
||||
@@ -5208,19 +5267,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cosmiconfig@npm:^7.0.1":
|
||||
version: 7.1.0
|
||||
resolution: "cosmiconfig@npm:7.1.0"
|
||||
dependencies:
|
||||
"@types/parse-json": ^4.0.0
|
||||
import-fresh: ^3.2.1
|
||||
parse-json: ^5.0.0
|
||||
path-type: ^4.0.0
|
||||
yaml: ^1.10.0
|
||||
checksum: c53bf7befc1591b2651a22414a5e786cd5f2eeaa87f3678a3d49d6069835a9d8d1aef223728e98aa8fec9a95bf831120d245096db12abe019fecb51f5696c96f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"crc-32@npm:^1.2.0":
|
||||
version: 1.2.2
|
||||
resolution: "crc-32@npm:1.2.2"
|
||||
@@ -5273,15 +5319,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-fetch@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "cross-fetch@npm:4.0.0"
|
||||
dependencies:
|
||||
node-fetch: ^2.6.12
|
||||
checksum: ecca4f37ffa0e8283e7a8a590926b66713a7ef7892757aa36c2d20ffa27b0ac5c60dcf453119c809abe5923fc0bae3702a4d896bfb406ef1077b0d0018213e24
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3":
|
||||
version: 7.0.3
|
||||
resolution: "cross-spawn@npm:7.0.3"
|
||||
@@ -5409,6 +5446,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"debug@npm:^4.3.6, debug@npm:^4.3.7":
|
||||
version: 4.3.7
|
||||
resolution: "debug@npm:4.3.7"
|
||||
dependencies:
|
||||
ms: ^2.1.3
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
checksum: 822d74e209cd910ef0802d261b150314bbcf36c582ccdbb3e70f0894823c17e49a50d3e66d96b633524263975ca16b6a833f3e3b7e030c157169a5fabac63160
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"decamelize@npm:^1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "decamelize@npm:1.2.0"
|
||||
@@ -5551,17 +5600,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"devtools-protocol@npm:0.0.1045489":
|
||||
version: 0.0.1045489
|
||||
resolution: "devtools-protocol@npm:0.0.1045489"
|
||||
checksum: 670b2ecc8e890358b08da3095b4c927ffc5ef846a39e1526ff99aecaa623b339450dfe308e421e64bf94308441832b8e9497ebda97fb02266fef3f455286742f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"devtools-protocol@npm:0.0.1232444":
|
||||
version: 0.0.1232444
|
||||
resolution: "devtools-protocol@npm:0.0.1232444"
|
||||
checksum: b421a3c20506d597211d101c3ed4e550db2ca195d59c3371b2e04a8d057f33be60e732bafc80dc53b34546593a7751857321971e235e9ce9f1c5a9523fd8fa20
|
||||
"devtools-protocol@npm:0.0.1354347":
|
||||
version: 0.0.1354347
|
||||
resolution: "devtools-protocol@npm:0.0.1354347"
|
||||
checksum: f3e29033319579f7e49c8fd05752faf811870cb6f4ec795b69b6f606984f11af52f317b98a229f39fe8e420346203a9f18df9c8053181e368e43440def1a9a5f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -6389,7 +6431,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"extract-zip@npm:2.0.1":
|
||||
"extract-zip@npm:^2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "extract-zip@npm:2.0.1"
|
||||
dependencies:
|
||||
@@ -7147,7 +7189,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"http-proxy-agent@npm:^7.0.0":
|
||||
"http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.1":
|
||||
version: 7.0.2
|
||||
resolution: "http-proxy-agent@npm:7.0.2"
|
||||
dependencies:
|
||||
@@ -7157,16 +7199,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"https-proxy-agent@npm:5.0.1":
|
||||
version: 5.0.1
|
||||
resolution: "https-proxy-agent@npm:5.0.1"
|
||||
dependencies:
|
||||
agent-base: 6
|
||||
debug: 4
|
||||
checksum: 571fccdf38184f05943e12d37d6ce38197becdd69e58d03f43637f7fa1269cf303a7d228aa27e5b27bbd3af8f09fd938e1c91dcfefff2df7ba77c20ed8dfc765
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2":
|
||||
version: 7.0.4
|
||||
resolution: "https-proxy-agent@npm:7.0.4"
|
||||
@@ -7177,6 +7209,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"https-proxy-agent@npm:^7.0.3":
|
||||
version: 7.0.5
|
||||
resolution: "https-proxy-agent@npm:7.0.5"
|
||||
dependencies:
|
||||
agent-base: ^7.0.2
|
||||
debug: 4
|
||||
checksum: 2e1a28960f13b041a50702ee74f240add8e75146a5c37fc98f1960f0496710f6918b3a9fe1e5aba41e50f58e6df48d107edd9c405c5f0d73ac260dabf2210857
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"human-signals@npm:^1.1.1":
|
||||
version: 1.1.1
|
||||
resolution: "human-signals@npm:1.1.1"
|
||||
@@ -9027,7 +9069,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ms@npm:2.1.3, ms@npm:^2.0.0, ms@npm:^2.1.1":
|
||||
"ms@npm:2.1.3, ms@npm:^2.0.0, ms@npm:^2.1.1, ms@npm:^2.1.3":
|
||||
version: 2.1.3
|
||||
resolution: "ms@npm:2.1.3"
|
||||
checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d
|
||||
@@ -9164,7 +9206,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.9":
|
||||
"node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.9":
|
||||
version: 2.7.0
|
||||
resolution: "node-fetch@npm:2.7.0"
|
||||
dependencies:
|
||||
@@ -9178,6 +9220,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"node-gyp-build@npm:^4.3.0":
|
||||
version: 4.8.2
|
||||
resolution: "node-gyp-build@npm:4.8.2"
|
||||
bin:
|
||||
node-gyp-build: bin.js
|
||||
node-gyp-build-optional: optional.js
|
||||
node-gyp-build-test: build-test.js
|
||||
checksum: 1a57bba8c4c193f808bd8ad1484d4ebdd8106dd9f04a3e82554dc716e3a2d87d7e369e9503c145e0e6a7e2c663fec0d8aaf52bd8156342ec7fc388195f37824e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"node-gyp@npm:latest":
|
||||
version: 10.1.0
|
||||
resolution: "node-gyp@npm:10.1.0"
|
||||
@@ -9956,7 +10009,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"progress@npm:2.0.3, progress@npm:^2.0.0":
|
||||
"progress@npm:^2.0.0, progress@npm:^2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "progress@npm:2.0.3"
|
||||
checksum: f67403fe7b34912148d9252cb7481266a354bd99ce82c835f79070643bb3c6583d10dbcfda4d41e04bbc1d8437e9af0fb1e1f2135727878f5308682a579429b7
|
||||
@@ -10044,23 +10097,23 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"proxy-agent@npm:6.3.1":
|
||||
version: 6.3.1
|
||||
resolution: "proxy-agent@npm:6.3.1"
|
||||
"proxy-agent@npm:^6.4.0":
|
||||
version: 6.4.0
|
||||
resolution: "proxy-agent@npm:6.4.0"
|
||||
dependencies:
|
||||
agent-base: ^7.0.2
|
||||
debug: ^4.3.4
|
||||
http-proxy-agent: ^7.0.0
|
||||
https-proxy-agent: ^7.0.2
|
||||
http-proxy-agent: ^7.0.1
|
||||
https-proxy-agent: ^7.0.3
|
||||
lru-cache: ^7.14.1
|
||||
pac-proxy-agent: ^7.0.1
|
||||
proxy-from-env: ^1.1.0
|
||||
socks-proxy-agent: ^8.0.2
|
||||
checksum: 31030da419da31809340ac2521090c9a5bf4fe47a944843f829b3502883208c8586a468955e64b694140a41d70af6f45cf4793f5efd4a6f3ed94e5ac8023e36d
|
||||
checksum: 4d3794ad5e07486298902f0a7f250d0f869fa0e92d790767ca3f793a81374ce0ab6c605f8ab8e791c4d754da96656b48d1c24cb7094bfd310a15867e4a0841d7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"proxy-from-env@npm:1.1.0, proxy-from-env@npm:^1.1.0":
|
||||
"proxy-from-env@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "proxy-from-env@npm:1.1.0"
|
||||
checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4
|
||||
@@ -10098,60 +10151,33 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"puppeteer-core@npm:18.2.1":
|
||||
version: 18.2.1
|
||||
resolution: "puppeteer-core@npm:18.2.1"
|
||||
"puppeteer-core@npm:23.6.0":
|
||||
version: 23.6.0
|
||||
resolution: "puppeteer-core@npm:23.6.0"
|
||||
dependencies:
|
||||
cross-fetch: 3.1.5
|
||||
debug: 4.3.4
|
||||
devtools-protocol: 0.0.1045489
|
||||
extract-zip: 2.0.1
|
||||
https-proxy-agent: 5.0.1
|
||||
proxy-from-env: 1.1.0
|
||||
rimraf: 3.0.2
|
||||
tar-fs: 2.1.1
|
||||
unbzip2-stream: 1.4.3
|
||||
ws: 8.9.0
|
||||
checksum: 27ed65a7335ee3f4356425ebe4bbb5202f7b39493398643554a12b981922b2243dc331d9a478215706b79696bcf391637dd5e5405d60aff6ba8f94f0c3fea742
|
||||
"@puppeteer/browsers": 2.4.0
|
||||
chromium-bidi: 0.8.0
|
||||
debug: ^4.3.7
|
||||
devtools-protocol: 0.0.1354347
|
||||
typed-query-selector: ^2.12.0
|
||||
ws: ^8.18.0
|
||||
checksum: cb2d659a94d4cb8f466f6e56ac5aff1374506326c2cd2a964dcd556e872f00db8c4079f1e7149ffb8200b30da9d31d4cd299ad28ac38a4c445ac0b66cf90fafc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"puppeteer-core@npm:21.11.0":
|
||||
version: 21.11.0
|
||||
resolution: "puppeteer-core@npm:21.11.0"
|
||||
"puppeteer@npm:^23.6.0":
|
||||
version: 23.6.0
|
||||
resolution: "puppeteer@npm:23.6.0"
|
||||
dependencies:
|
||||
"@puppeteer/browsers": 1.9.1
|
||||
chromium-bidi: 0.5.8
|
||||
cross-fetch: 4.0.0
|
||||
debug: 4.3.4
|
||||
devtools-protocol: 0.0.1232444
|
||||
ws: 8.16.0
|
||||
checksum: 953018ca679542d747e5974fd732349d73f4c685c0b49dd6027d493ad95d64a23b2d6e3e72f0a0a12c7335d3e08a0b3e6bc9ac3adfb3fb0316fb1ca62f46f129
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"puppeteer@npm:^18.2.1":
|
||||
version: 18.2.1
|
||||
resolution: "puppeteer@npm:18.2.1"
|
||||
dependencies:
|
||||
https-proxy-agent: 5.0.1
|
||||
progress: 2.0.3
|
||||
proxy-from-env: 1.1.0
|
||||
puppeteer-core: 18.2.1
|
||||
checksum: 58ba8c7abd82071dc12e280622fa352a8ac253375a514c7a3527b468672a4ccdfe20b37aa09498774da2f0666bcdd9a47838c6661de483a3d6e10b47ef666113
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"puppeteer@npm:^21.0.0":
|
||||
version: 21.11.0
|
||||
resolution: "puppeteer@npm:21.11.0"
|
||||
dependencies:
|
||||
"@puppeteer/browsers": 1.9.1
|
||||
cosmiconfig: 9.0.0
|
||||
puppeteer-core: 21.11.0
|
||||
"@puppeteer/browsers": 2.4.0
|
||||
chromium-bidi: 0.8.0
|
||||
cosmiconfig: ^9.0.0
|
||||
devtools-protocol: 0.0.1354347
|
||||
puppeteer-core: 23.6.0
|
||||
typed-query-selector: ^2.12.0
|
||||
bin:
|
||||
puppeteer: lib/esm/puppeteer/node/cli.js
|
||||
checksum: 0f2e6f6d9269e511022ec8e8478f42bf5f3dbddbdac7b50d31c90504993eaef436e8729a5b3f105576ec2031519de723d4a9d0ad797821d0f16540073fabc37a
|
||||
puppeteer: lib/cjs/puppeteer/node/cli.js
|
||||
checksum: c0cf82393418154d392dcccca8614aaf894f489fa0a5de664556816d70eff773e8a0bb60331a727b5d954a30c0cab74bff968ff11e37defa1a75ae524655ac2c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -10555,17 +10581,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rimraf@npm:3.0.2, rimraf@npm:^3.0.2":
|
||||
version: 3.0.2
|
||||
resolution: "rimraf@npm:3.0.2"
|
||||
dependencies:
|
||||
glob: ^7.1.3
|
||||
bin:
|
||||
rimraf: bin.js
|
||||
checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rimraf@npm:4.4.1":
|
||||
version: 4.4.1
|
||||
resolution: "rimraf@npm:4.4.1"
|
||||
@@ -10577,6 +10592,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rimraf@npm:^3.0.2":
|
||||
version: 3.0.2
|
||||
resolution: "rimraf@npm:3.0.2"
|
||||
dependencies:
|
||||
glob: ^7.1.3
|
||||
bin:
|
||||
rimraf: bin.js
|
||||
checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"run-async@npm:^2.4.0":
|
||||
version: 2.4.1
|
||||
resolution: "run-async@npm:2.4.1"
|
||||
@@ -10689,6 +10715,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"semver@npm:^7.6.3":
|
||||
version: 7.6.3
|
||||
resolution: "semver@npm:7.6.3"
|
||||
bin:
|
||||
semver: bin/semver.js
|
||||
checksum: 4110ec5d015c9438f322257b1c51fe30276e5f766a3f64c09edd1d7ea7118ecbc3f379f3b69032bacf13116dc7abc4ad8ce0d7e2bd642e26b0d271b56b61a7d8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"send@npm:0.18.0":
|
||||
version: 0.18.0
|
||||
resolution: "send@npm:0.18.0"
|
||||
@@ -11125,6 +11160,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"streamx@npm:^2.20.0":
|
||||
version: 2.20.1
|
||||
resolution: "streamx@npm:2.20.1"
|
||||
dependencies:
|
||||
bare-events: ^2.2.0
|
||||
fast-fifo: ^1.3.2
|
||||
queue-tick: ^1.0.1
|
||||
text-decoder: ^1.1.0
|
||||
dependenciesMeta:
|
||||
bare-events:
|
||||
optional: true
|
||||
checksum: 48605ddd3abdd86d2e3ee945ec7c9317f36abb5303347a8fff6e4c7926a72c33ec7ac86b50734ccd1cf65602b6a38e247966e8199b24e5a7485d9cec8f5327bd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"string-length@npm:^4.0.1":
|
||||
version: 4.0.2
|
||||
resolution: "string-length@npm:4.0.2"
|
||||
@@ -11419,7 +11469,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tar-fs@npm:2.1.1, tar-fs@npm:^2.0.0":
|
||||
"tar-fs@npm:^2.0.0":
|
||||
version: 2.1.1
|
||||
resolution: "tar-fs@npm:2.1.1"
|
||||
dependencies:
|
||||
@@ -11431,14 +11481,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tar-fs@npm:3.0.4":
|
||||
version: 3.0.4
|
||||
resolution: "tar-fs@npm:3.0.4"
|
||||
"tar-fs@npm:^3.0.6":
|
||||
version: 3.0.6
|
||||
resolution: "tar-fs@npm:3.0.6"
|
||||
dependencies:
|
||||
mkdirp-classic: ^0.5.2
|
||||
bare-fs: ^2.1.1
|
||||
bare-path: ^2.1.0
|
||||
pump: ^3.0.0
|
||||
tar-stream: ^3.1.5
|
||||
checksum: dcf4054f9e92ca0efe61c2b3f612914fb259a47900aa908a63106513a6d006c899b426ada53eb88d9dbbf089b5724c8e90b96a2c4ca6171845fa14203d734e30
|
||||
dependenciesMeta:
|
||||
bare-fs:
|
||||
optional: true
|
||||
bare-path:
|
||||
optional: true
|
||||
checksum: b4fa09c70f75caf05bf5cf87369cd2862f1ac5fb75c4ddf9d25d55999f7736a94b58ad679d384196cba837c5f5ff14086e060fafccef5474a16e2d3058ffa488
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -11640,13 +11696,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tr46@npm:~0.0.3":
|
||||
version: 0.0.3
|
||||
resolution: "tr46@npm:0.0.3"
|
||||
checksum: 726321c5eaf41b5002e17ffbd1fb7245999a073e8979085dacd47c4b4e8068ff5777142fc6726d6ca1fd2ff16921b48788b87225cbc57c72636f6efa8efbffe3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"traverse@npm:>=0.3.0 <0.4":
|
||||
version: 0.3.9
|
||||
resolution: "traverse@npm:0.3.9"
|
||||
@@ -11926,6 +11975,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typed-query-selector@npm:^2.12.0":
|
||||
version: 2.12.0
|
||||
resolution: "typed-query-selector@npm:2.12.0"
|
||||
checksum: c4652f2eec16112d69e0da30c2effab3f03d1710f9559da1e1209bbfc9a20990d5de4ba97890c11f9d17d85c8ae3310953a86c198166599d4c36abc63664f169
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typedarray@npm:^0.0.6":
|
||||
version: 0.0.6
|
||||
resolution: "typedarray@npm:0.0.6"
|
||||
@@ -11974,7 +12030,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"unbzip2-stream@npm:1.4.3":
|
||||
"unbzip2-stream@npm:^1.4.3":
|
||||
version: 1.4.3
|
||||
resolution: "unbzip2-stream@npm:1.4.3"
|
||||
dependencies:
|
||||
@@ -12189,6 +12245,7 @@ __metadata:
|
||||
axios: ^1.7.7
|
||||
axios-retry: ^4.5.0
|
||||
better-sqlite3: 11.3.0
|
||||
bufferutil: ^4.0.8
|
||||
check-disk-space: ^3.4.0
|
||||
chokidar: ^3.6.0
|
||||
class-transformer: ^0.5.1
|
||||
@@ -12218,7 +12275,7 @@ __metadata:
|
||||
prettier: ^1.19.1
|
||||
pretty-bytes: 5.6.0
|
||||
promise-retry: ^2.0.1
|
||||
puppeteer: ^21.0.0
|
||||
puppeteer: ^23.6.0
|
||||
qrcode: ^1.5.1
|
||||
qrcode-terminal: ^0.12.0
|
||||
reflect-metadata: ^0.1.13
|
||||
@@ -12233,6 +12290,9 @@ __metadata:
|
||||
tsconfig-paths: ^4.1.0
|
||||
typescript: ^4.8.4
|
||||
whatsapp-web.js: "github:devlikeapro/whatsapp-web.js#fork-main-channels"
|
||||
dependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -12264,13 +12324,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"webidl-conversions@npm:^3.0.0":
|
||||
version: 3.0.1
|
||||
resolution: "webidl-conversions@npm:3.0.1"
|
||||
checksum: c92a0a6ab95314bde9c32e1d0a6dfac83b578f8fa5f21e675bc2706ed6981bc26b7eb7e6a1fab158e5ce4adf9caa4a0aee49a52505d4d13c7be545f15021b17c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"webidl-conversions@npm:^7.0.0":
|
||||
version: 7.0.0
|
||||
resolution: "webidl-conversions@npm:7.0.0"
|
||||
@@ -12331,7 +12384,7 @@ __metadata:
|
||||
|
||||
"whatsapp-web.js@github:devlikeapro/whatsapp-web.js#fork-main-channels":
|
||||
version: 1.26.0
|
||||
resolution: "whatsapp-web.js@https://github.com/devlikeapro/whatsapp-web.js.git#commit=6a333d0088591269238726e9effa3cbb14c8e7c7"
|
||||
resolution: "whatsapp-web.js@https://github.com/devlikeapro/whatsapp-web.js.git#commit=76329eedc27b07c11e38bf1b60e6c2476c11dd73"
|
||||
dependencies:
|
||||
"@pedroslopez/moduleraid": ^5.0.2
|
||||
archiver: ^5.3.1
|
||||
@@ -12349,11 +12402,11 @@ __metadata:
|
||||
optional: true
|
||||
unzipper:
|
||||
optional: true
|
||||
checksum: 51e9dce51270cf6fb20acd0bd7368f36763dcc3d28c6c3725c78b46edd5da21fea2c9c1f78ab6699464e4e1a6d9c361b6ab76a88225ebdeeb3f9abdd860d082c
|
||||
checksum: b8d4fcb1fd1365a38f07f95dd2eb1fd743c6c406fc7ac679662ddeded80c441720bc8400222a37d61765ebcbb5c6799f169d5ac45f12f58b5421c55bb9f2ab7e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"whatwg-url@npm:^13.0.0":
|
||||
"whatwg-url@npm:13.0.0":
|
||||
version: 13.0.0
|
||||
resolution: "whatwg-url@npm:13.0.0"
|
||||
dependencies:
|
||||
@@ -12363,16 +12416,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"whatwg-url@npm:^5.0.0":
|
||||
version: 5.0.0
|
||||
resolution: "whatwg-url@npm:5.0.0"
|
||||
dependencies:
|
||||
tr46: ~0.0.3
|
||||
webidl-conversions: ^3.0.0
|
||||
checksum: b8daed4ad3356cc4899048a15b2c143a9aed0dfae1f611ebd55073310c7b910f522ad75d727346ad64203d7e6c79ef25eafd465f4d12775ca44b90fa82ed9e2c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"which-boxed-primitive@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "which-boxed-primitive@npm:1.0.2"
|
||||
@@ -12523,9 +12566,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:8.13.0":
|
||||
version: 8.13.0
|
||||
resolution: "ws@npm:8.13.0"
|
||||
"ws@npm:^8.18.0":
|
||||
version: 8.18.0
|
||||
resolution: "ws@npm:8.18.0"
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ">=5.0.2"
|
||||
@@ -12534,52 +12577,7 @@ __metadata:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
checksum: 53e991bbf928faf5dc6efac9b8eb9ab6497c69feeb94f963d648b7a3530a720b19ec2e0ec037344257e05a4f35bd9ad04d9de6f289615ffb133282031b18c61c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:8.16.0":
|
||||
version: 8.16.0
|
||||
resolution: "ws@npm:8.16.0"
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ">=5.0.2"
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
checksum: feb3eecd2bae82fa8a8beef800290ce437d8b8063bdc69712725f21aef77c49cb2ff45c6e5e7fce622248f9c7abaee506bae0a9064067ffd6935460c7357321b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:8.9.0":
|
||||
version: 8.9.0
|
||||
resolution: "ws@npm:8.9.0"
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ^5.0.2
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
checksum: 23aa0f021b2eb65c108ec4c3e08c0d81ba01f82b500432dfe327fd6be36079c1d81fdb0eac6464d2a0eb49904d34a9ab8c59619d673fa07b8346f83aeb0cbf12
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:^8.13.0":
|
||||
version: 8.17.1
|
||||
resolution: "ws@npm:8.17.1"
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ">=5.0.2"
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
checksum: 442badcce1f1178ec87a0b5372ae2e9771e07c4929a3180321901f226127f252441e8689d765aa5cfba5f50ac60dd830954afc5aeae81609aefa11d3ddf5cecf
|
||||
checksum: 91d4d35bc99ff6df483bdf029b9ea4bfd7af1f16fc91231a96777a63d263e1eabf486e13a2353970efc534f9faa43bdbf9ee76525af22f4752cbc5ebda333975
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -12642,21 +12640,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yargs@npm:17.7.2, yargs@npm:^17.3.1":
|
||||
version: 17.7.2
|
||||
resolution: "yargs@npm:17.7.2"
|
||||
dependencies:
|
||||
cliui: ^8.0.1
|
||||
escalade: ^3.1.1
|
||||
get-caller-file: ^2.0.5
|
||||
require-directory: ^2.1.1
|
||||
string-width: ^4.2.3
|
||||
y18n: ^5.0.5
|
||||
yargs-parser: ^21.1.1
|
||||
checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yargs@npm:^15.3.1":
|
||||
version: 15.4.1
|
||||
resolution: "yargs@npm:15.4.1"
|
||||
@@ -12676,6 +12659,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yargs@npm:^17.3.1, yargs@npm:^17.7.2":
|
||||
version: 17.7.2
|
||||
resolution: "yargs@npm:17.7.2"
|
||||
dependencies:
|
||||
cliui: ^8.0.1
|
||||
escalade: ^3.1.1
|
||||
get-caller-file: ^2.0.5
|
||||
require-directory: ^2.1.1
|
||||
string-width: ^4.2.3
|
||||
y18n: ^5.0.5
|
||||
yargs-parser: ^21.1.1
|
||||
checksum: 73b572e863aa4a8cbef323dd911d79d193b772defd5a51aab0aca2d446655216f5002c42c5306033968193bdbf892a7a4c110b0d77954a7fdf563e653967b56a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yauzl@npm:^2.10.0":
|
||||
version: 2.10.0
|
||||
resolution: "yauzl@npm:2.10.0"
|
||||
@@ -12710,3 +12708,10 @@ __metadata:
|
||||
checksum: 33bd5ee7017656c2ad728b5d4ba510e15bd65ce1ec180c5bbdc7a5f063256353ec482e6a2bc74de7515219d8494147924b9aae16e63fdaaf37cdf7d1ee8df125
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"zod@npm:3.23.8":
|
||||
version: 3.23.8
|
||||
resolution: "zod@npm:3.23.8"
|
||||
checksum: 15949ff82118f59c893dacd9d3c766d02b6fa2e71cf474d5aa888570c469dbf5446ac5ad562bb035bf7ac9650da94f290655c194f4a6de3e766f43febd432c5c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
Reference in new issue
Block a user