@kaikybrofc/omnizap-system 2.2.10 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -18
- package/app/config/adminIdentity.js +1 -3
- package/app/connection/socketController.js +10 -20
- package/app/controllers/messageController.js +7 -28
- package/app/modules/aiModule/catCommand.js +29 -192
- package/app/modules/broadcastModule/noticeCommand.js +28 -97
- package/app/modules/gameModule/diceCommand.js +6 -32
- package/app/modules/playModule/playCommand.js +57 -258
- package/app/modules/quoteModule/quoteCommand.js +2 -4
- package/app/modules/rpgPokemonModule/rpgPokemonRepository.js +1 -13
- package/app/modules/statsModule/noMessageCommand.js +16 -84
- package/app/modules/statsModule/rankingCommand.js +5 -25
- package/app/modules/statsModule/rankingCommon.js +1 -9
- package/app/modules/stickerModule/convertToWebp.js +4 -27
- package/app/modules/stickerModule/stickerCommand.js +13 -24
- package/app/modules/stickerModule/stickerTextCommand.js +13 -25
- package/app/modules/stickerPackModule/autoPackCollectorService.js +16 -7
- package/app/modules/stickerPackModule/domainEventOutboxRepository.js +20 -36
- package/app/modules/stickerPackModule/domainEvents.js +2 -11
- package/app/modules/stickerPackModule/semanticReclassificationEngine.js +13 -50
- package/app/modules/stickerPackModule/semanticReclassificationEngine.test.js +2 -15
- package/app/modules/stickerPackModule/semanticThemeClusterService.js +14 -41
- package/app/modules/stickerPackModule/stickerAssetClassificationRepository.js +25 -95
- package/app/modules/stickerPackModule/stickerAssetRepository.js +12 -31
- package/app/modules/stickerPackModule/stickerAssetReprocessQueueRepository.js +13 -18
- package/app/modules/stickerPackModule/stickerAutoPackByTagsRuntime.js +284 -709
- package/app/modules/stickerPackModule/stickerClassificationBackgroundRuntime.js +27 -106
- package/app/modules/stickerPackModule/stickerClassificationService.js +46 -77
- package/app/modules/stickerPackModule/stickerDedicatedTaskWorkerRuntime.js +13 -53
- package/app/modules/stickerPackModule/stickerDomainEventBus.js +10 -16
- package/app/modules/stickerPackModule/stickerDomainEventConsumerRuntime.js +13 -34
- package/app/modules/stickerPackModule/stickerMarketplaceDriftService.js +1 -4
- package/app/modules/stickerPackModule/stickerObjectStorageService.js +26 -26
- package/app/modules/stickerPackModule/stickerPackCommandHandlers.js +32 -187
- package/app/modules/stickerPackModule/stickerPackInteractionEventRepository.js +6 -15
- package/app/modules/stickerPackModule/stickerPackItemRepository.js +6 -32
- package/app/modules/stickerPackModule/stickerPackMarketplaceService.js +12 -36
- package/app/modules/stickerPackModule/stickerPackMessageService.js +12 -40
- package/app/modules/stickerPackModule/stickerPackRepository.js +23 -66
- package/app/modules/stickerPackModule/stickerPackScoreSnapshotRepository.js +9 -21
- package/app/modules/stickerPackModule/stickerPackScoreSnapshotRuntime.js +10 -40
- package/app/modules/stickerPackModule/stickerPackService.js +50 -115
- package/app/modules/stickerPackModule/stickerPackServiceRuntime.js +2 -21
- package/app/modules/stickerPackModule/stickerPackUtils.js +13 -3
- package/app/modules/stickerPackModule/stickerStorageService.js +16 -65
- package/app/modules/stickerPackModule/stickerWorkerPipelineRuntime.js +4 -22
- package/app/modules/stickerPackModule/stickerWorkerTaskQueueRepository.js +14 -29
- package/app/modules/systemMetricsModule/pingCommand.js +9 -39
- package/app/modules/tiktokModule/tiktokCommand.js +17 -109
- package/app/modules/userModule/userCommand.js +2 -88
- package/app/observability/metrics.js +5 -16
- package/app/services/captchaService.js +1 -6
- package/app/services/dbWriteQueue.js +3 -18
- package/app/services/featureFlagService.js +2 -8
- package/app/services/newsBroadcastService.js +0 -1
- package/app/services/queueUtils.js +2 -4
- package/app/services/whatsappLoginLinkService.js +7 -9
- package/app/store/premiumUserStore.js +1 -2
- package/app/utils/antiLink/antiLinkModule.js +3 -233
- package/app/utils/logger/loggerModule.js +9 -34
- package/app/utils/systemMetrics/systemMetricsModule.js +1 -4
- package/database/init.js +1 -8
- package/docker-compose.yml +27 -27
- package/docs/seo/omnizap-seo-playbook-br-2026-02-28.md +26 -0
- package/docs/seo/satellite-page-template.md +2 -0
- package/docs/seo/satellite-pages-phase1.json +40 -177
- package/eslint.config.js +2 -15
- package/index.js +8 -36
- package/ml/clip_classifier/README.md +4 -6
- package/observability/alert-rules.yml +12 -12
- package/observability/grafana/provisioning/dashboards/dashboards.yml +1 -1
- package/package.json +6 -3
- package/public/api-docs/index.html +220 -193
- package/public/bot-whatsapp-para-grupo/index.html +291 -261
- package/public/bot-whatsapp-sem-programar/index.html +291 -261
- package/public/comandos/index.html +421 -406
- package/public/como-automatizar-avisos-no-whatsapp/index.html +291 -261
- package/public/como-criar-comandos-whatsapp/index.html +291 -261
- package/public/como-evitar-spam-no-whatsapp/index.html +291 -261
- package/public/como-moderar-grupo-whatsapp/index.html +291 -261
- package/public/como-organizar-comunidade-whatsapp/index.html +291 -261
- package/public/css/github-project-panel.css +13 -8
- package/public/css/stickers-admin.css +25 -9
- package/public/css/styles.css +23 -16
- package/public/index.html +1117 -994
- package/public/js/apps/apiDocsApp.js +17 -167
- package/public/js/apps/createPackApp.js +69 -332
- package/public/js/apps/homeApp.js +94 -74
- package/public/js/apps/loginApp.js +3 -12
- package/public/js/apps/stickersAdminApp.js +190 -181
- package/public/js/apps/stickersApp.js +496 -1397
- package/public/js/catalog.js +11 -74
- package/public/js/github-panel/components/ErrorState.js +1 -8
- package/public/js/github-panel/components/GithubProjectPanel.js +2 -9
- package/public/js/github-panel/components/SkeletonPanel.js +1 -11
- package/public/js/github-panel/components/StatCard.js +1 -7
- package/public/js/github-panel/vendor/react.js +1 -9
- package/public/js/runtime/react-runtime.js +1 -9
- package/public/licenca/index.html +104 -86
- package/public/login/index.html +315 -325
- package/public/melhor-bot-whatsapp-para-grupos/index.html +291 -261
- package/public/stickers/admin/index.html +14 -19
- package/public/stickers/create/index.html +39 -44
- package/public/stickers/index.html +96 -107
- package/public/termos-de-uso/index.html +142 -115
- package/public/user/index.html +347 -350
- package/scripts/cache-bust.mjs +5 -24
- package/scripts/generate-seo-satellite-pages.mjs +10 -13
- package/scripts/run-prettier-all.mjs +25 -0
- package/scripts/sticker-catalog-loadtest.mjs +13 -11
- package/scripts/sticker-worker-task.mjs +1 -4
- package/scripts/sync-readme-snapshot.mjs +3 -2
- package/server/controllers/stickerCatalogController.js +67 -5
- package/server/http/httpServer.js +2 -10
- package/server/routes/stickerCatalog/catalogHandlers/catalogAdminHttp.js +1 -8
- package/server/routes/stickerCatalog/catalogHandlers/catalogAuthHttp.js +1 -9
- package/server/routes/stickerCatalog/catalogHandlers/catalogPublicHttp.js +10 -11
- package/server/routes/stickerCatalog/catalogHandlers/catalogUploadHttp.js +1 -10
- package/server/routes/stickerCatalog/catalogRouter.js +11 -13
|
@@ -2,16 +2,10 @@ import { executeQuery } from '../../../database/index.js';
|
|
|
2
2
|
import logger from '../../utils/logger/loggerModule.js';
|
|
3
3
|
import { getGroupParticipants, isUserAdmin } from '../../config/groupUtils.js';
|
|
4
4
|
import { resolveBotJid } from '../../config/baileysConfig.js';
|
|
5
|
-
import {
|
|
6
|
-
primeLidCache,
|
|
7
|
-
resolveUserIdCached,
|
|
8
|
-
isLidUserId,
|
|
9
|
-
isWhatsAppUserId,
|
|
10
|
-
} from '../../services/lidMapService.js';
|
|
5
|
+
import { primeLidCache, resolveUserIdCached, isLidUserId, isWhatsAppUserId } from '../../services/lidMapService.js';
|
|
11
6
|
import { sendAndStore } from '../../services/messagePersistenceService.js';
|
|
12
7
|
|
|
13
|
-
const getParticipantJid = (participant) =>
|
|
14
|
-
participant?.id || participant?.jid || participant?.lid || null;
|
|
8
|
+
const getParticipantJid = (participant) => participant?.id || participant?.jid || participant?.lid || null;
|
|
15
9
|
|
|
16
10
|
const MAX_MENTIONS_PER_MESSAGE = 80;
|
|
17
11
|
const BATCH_DELAY_MS = 400;
|
|
@@ -71,13 +65,8 @@ const normalizeParticipant = (participant, sock) => {
|
|
|
71
65
|
jid: rawId,
|
|
72
66
|
participantAlt,
|
|
73
67
|
});
|
|
74
|
-
const contact =
|
|
75
|
-
|
|
76
|
-
(participantAlt && sock?.contacts?.[participantAlt]) ||
|
|
77
|
-
(rawId && sock?.contacts?.[rawId]) ||
|
|
78
|
-
null;
|
|
79
|
-
const displayName =
|
|
80
|
-
participant?.notify || participant?.name || contact?.notify || contact?.name || contact?.short;
|
|
68
|
+
const contact = (canonical && sock?.contacts?.[canonical]) || (participantAlt && sock?.contacts?.[participantAlt]) || (rawId && sock?.contacts?.[rawId]) || null;
|
|
69
|
+
const displayName = participant?.notify || participant?.name || contact?.notify || contact?.name || contact?.short;
|
|
81
70
|
return {
|
|
82
71
|
rawId,
|
|
83
72
|
participantAlt,
|
|
@@ -86,28 +75,9 @@ const normalizeParticipant = (participant, sock) => {
|
|
|
86
75
|
};
|
|
87
76
|
};
|
|
88
77
|
|
|
89
|
-
const buildNoMessageText = ({
|
|
90
|
-
minMessages
|
|
91
|
-
periodLabel
|
|
92
|
-
totalParticipants,
|
|
93
|
-
totalListed,
|
|
94
|
-
batchIndex = 1,
|
|
95
|
-
batchTotal = 1,
|
|
96
|
-
batchSize = 0,
|
|
97
|
-
}) => {
|
|
98
|
-
const title =
|
|
99
|
-
minMessages <= 1 ? '🔇 *Membros sem mensagens no grupo*' : '🔇 *Membros abaixo do mínimo*';
|
|
100
|
-
const lines = [
|
|
101
|
-
title,
|
|
102
|
-
'',
|
|
103
|
-
`• Mínimo de mensagens: ${minMessages}`,
|
|
104
|
-
`• Período: ${periodLabel}`,
|
|
105
|
-
`• Participantes: ${totalParticipants}`,
|
|
106
|
-
`• Abaixo do mínimo: ${totalListed}`,
|
|
107
|
-
...(batchTotal > 1
|
|
108
|
-
? [`• Parte: ${batchIndex}/${batchTotal}`, `• Notificados nesta mensagem: ${batchSize}`]
|
|
109
|
-
: []),
|
|
110
|
-
];
|
|
78
|
+
const buildNoMessageText = ({ minMessages, periodLabel, totalParticipants, totalListed, batchIndex = 1, batchTotal = 1, batchSize = 0 }) => {
|
|
79
|
+
const title = minMessages <= 1 ? '🔇 *Membros sem mensagens no grupo*' : '🔇 *Membros abaixo do mínimo*';
|
|
80
|
+
const lines = [title, '', `• Mínimo de mensagens: ${minMessages}`, `• Período: ${periodLabel}`, `• Participantes: ${totalParticipants}`, `• Abaixo do mínimo: ${totalListed}`, ...(batchTotal > 1 ? [`• Parte: ${batchIndex}/${batchTotal}`, `• Notificados nesta mensagem: ${batchSize}`] : [])];
|
|
111
81
|
|
|
112
82
|
if (!totalListed) {
|
|
113
83
|
lines.push('', '✅ Todos os membros atingiram o mínimo.');
|
|
@@ -139,40 +109,20 @@ const splitEntriesByMentions = (entries, maxMentions) => {
|
|
|
139
109
|
return batches;
|
|
140
110
|
};
|
|
141
111
|
|
|
142
|
-
export async function handleNoMessageCommand({
|
|
143
|
-
sock,
|
|
144
|
-
remoteJid,
|
|
145
|
-
messageInfo,
|
|
146
|
-
expirationMessage,
|
|
147
|
-
isGroupMessage,
|
|
148
|
-
senderJid,
|
|
149
|
-
text,
|
|
150
|
-
}) {
|
|
112
|
+
export async function handleNoMessageCommand({ sock, remoteJid, messageInfo, expirationMessage, isGroupMessage, senderJid, text }) {
|
|
151
113
|
if (!isGroupMessage) {
|
|
152
|
-
await sendAndStore(sock,
|
|
153
|
-
remoteJid,
|
|
154
|
-
{ text: 'Este comando so pode ser usado em grupos.' },
|
|
155
|
-
{ quoted: messageInfo, ephemeralExpiration: expirationMessage },
|
|
156
|
-
);
|
|
114
|
+
await sendAndStore(sock, remoteJid, { text: 'Este comando so pode ser usado em grupos.' }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
157
115
|
return;
|
|
158
116
|
}
|
|
159
117
|
if (!(await isUserAdmin(remoteJid, senderJid))) {
|
|
160
|
-
await sendAndStore(sock,
|
|
161
|
-
remoteJid,
|
|
162
|
-
{ text: 'Você não tem permissão para usar este comando.' },
|
|
163
|
-
{ quoted: messageInfo, ephemeralExpiration: expirationMessage },
|
|
164
|
-
);
|
|
118
|
+
await sendAndStore(sock, remoteJid, { text: 'Você não tem permissão para usar este comando.' }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
165
119
|
return;
|
|
166
120
|
}
|
|
167
121
|
|
|
168
122
|
try {
|
|
169
123
|
const participants = await getGroupParticipants(remoteJid);
|
|
170
124
|
if (!participants || participants.length === 0) {
|
|
171
|
-
await sendAndStore(sock,
|
|
172
|
-
remoteJid,
|
|
173
|
-
{ text: 'Nao foi possivel obter os participantes do grupo.' },
|
|
174
|
-
{ quoted: messageInfo, ephemeralExpiration: expirationMessage },
|
|
175
|
-
);
|
|
125
|
+
await sendAndStore(sock, remoteJid, { text: 'Nao foi possivel obter os participantes do grupo.' }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
176
126
|
return;
|
|
177
127
|
}
|
|
178
128
|
|
|
@@ -224,11 +174,7 @@ export async function handleNoMessageCommand({
|
|
|
224
174
|
if (botCanonical && canonical === botCanonical) return;
|
|
225
175
|
const total = countsByCanonical.get(canonical) || 0;
|
|
226
176
|
if (total >= minMessages) return;
|
|
227
|
-
const mentionJid = isWhatsAppUserId(canonical)
|
|
228
|
-
? canonical
|
|
229
|
-
: isWhatsAppUserId(participant.participantAlt)
|
|
230
|
-
? participant.participantAlt
|
|
231
|
-
: null;
|
|
177
|
+
const mentionJid = isWhatsAppUserId(canonical) ? canonical : isWhatsAppUserId(participant.participantAlt) ? participant.participantAlt : null;
|
|
232
178
|
entries.push({
|
|
233
179
|
canonical,
|
|
234
180
|
rawId: participant.rawId,
|
|
@@ -246,19 +192,13 @@ export async function handleNoMessageCommand({
|
|
|
246
192
|
totalParticipants,
|
|
247
193
|
totalListed,
|
|
248
194
|
});
|
|
249
|
-
await sendAndStore(sock,
|
|
250
|
-
remoteJid,
|
|
251
|
-
{ text: responseText },
|
|
252
|
-
{ quoted: messageInfo, ephemeralExpiration: expirationMessage },
|
|
253
|
-
);
|
|
195
|
+
await sendAndStore(sock, remoteJid, { text: responseText }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
254
196
|
return;
|
|
255
197
|
}
|
|
256
198
|
|
|
257
199
|
for (let index = 0; index < batches.length; index += 1) {
|
|
258
200
|
const batch = batches[index];
|
|
259
|
-
const batchMentions = Array.from(
|
|
260
|
-
new Set(batch.map((entry) => entry.mentionJid).filter(Boolean)),
|
|
261
|
-
);
|
|
201
|
+
const batchMentions = Array.from(new Set(batch.map((entry) => entry.mentionJid).filter(Boolean)));
|
|
262
202
|
const responseText = buildNoMessageText({
|
|
263
203
|
minMessages,
|
|
264
204
|
periodLabel,
|
|
@@ -268,21 +208,13 @@ export async function handleNoMessageCommand({
|
|
|
268
208
|
batchTotal: batches.length,
|
|
269
209
|
batchSize: batch.length,
|
|
270
210
|
});
|
|
271
|
-
await sendAndStore(sock,
|
|
272
|
-
remoteJid,
|
|
273
|
-
{ text: responseText, mentions: batchMentions },
|
|
274
|
-
{ quoted: messageInfo, ephemeralExpiration: expirationMessage },
|
|
275
|
-
);
|
|
211
|
+
await sendAndStore(sock, remoteJid, { text: responseText, mentions: batchMentions }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
276
212
|
if (index < batches.length - 1) {
|
|
277
213
|
await sleep(BATCH_DELAY_MS);
|
|
278
214
|
}
|
|
279
215
|
}
|
|
280
216
|
} catch (error) {
|
|
281
217
|
logger.error('Erro ao buscar membros sem mensagens:', { error: error.message });
|
|
282
|
-
await sendAndStore(sock,
|
|
283
|
-
remoteJid,
|
|
284
|
-
{ text: `Erro ao buscar membros sem mensagens: ${error.message}` },
|
|
285
|
-
{ quoted: messageInfo, ephemeralExpiration: expirationMessage },
|
|
286
|
-
);
|
|
218
|
+
await sendAndStore(sock, remoteJid, { text: `Erro ao buscar membros sem mensagens: ${error.message}` }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
287
219
|
}
|
|
288
220
|
}
|
|
@@ -6,19 +6,9 @@ import { sendAndStore } from '../../services/messagePersistenceService.js';
|
|
|
6
6
|
|
|
7
7
|
const RANKING_LIMIT = 5;
|
|
8
8
|
|
|
9
|
-
export async function handleRankingCommand({
|
|
10
|
-
sock,
|
|
11
|
-
remoteJid,
|
|
12
|
-
messageInfo,
|
|
13
|
-
expirationMessage,
|
|
14
|
-
isGroupMessage,
|
|
15
|
-
}) {
|
|
9
|
+
export async function handleRankingCommand({ sock, remoteJid, messageInfo, expirationMessage, isGroupMessage }) {
|
|
16
10
|
if (!isGroupMessage) {
|
|
17
|
-
await sendAndStore(sock,
|
|
18
|
-
remoteJid,
|
|
19
|
-
{ text: 'Este comando so pode ser usado em grupos.' },
|
|
20
|
-
{ quoted: messageInfo, ephemeralExpiration: expirationMessage },
|
|
21
|
-
);
|
|
11
|
+
await sendAndStore(sock, remoteJid, { text: 'Este comando so pode ser usado em grupos.' }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
22
12
|
return;
|
|
23
13
|
}
|
|
24
14
|
|
|
@@ -31,9 +21,7 @@ export async function handleRankingCommand({
|
|
|
31
21
|
limit: RANKING_LIMIT,
|
|
32
22
|
});
|
|
33
23
|
const text = buildRankingMessage({ scope: 'group', limit: RANKING_LIMIT, ...report });
|
|
34
|
-
const mentions = report.rows
|
|
35
|
-
.map((row) => row.mention_id)
|
|
36
|
-
.filter((jid) => isWhatsAppUserId(jid));
|
|
24
|
+
const mentions = report.rows.map((row) => row.mention_id).filter((jid) => isWhatsAppUserId(jid));
|
|
37
25
|
|
|
38
26
|
const imageBuffer = await renderRankingImage({
|
|
39
27
|
sock,
|
|
@@ -44,17 +32,9 @@ export async function handleRankingCommand({
|
|
|
44
32
|
scope: 'group',
|
|
45
33
|
limit: RANKING_LIMIT,
|
|
46
34
|
});
|
|
47
|
-
await sendAndStore(sock,
|
|
48
|
-
remoteJid,
|
|
49
|
-
{ image: imageBuffer, caption: text, ...(mentions.length ? { mentions } : {}) },
|
|
50
|
-
{ quoted: messageInfo, ephemeralExpiration: expirationMessage },
|
|
51
|
-
);
|
|
35
|
+
await sendAndStore(sock, remoteJid, { image: imageBuffer, caption: text, ...(mentions.length ? { mentions } : {}) }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
52
36
|
} catch (error) {
|
|
53
37
|
logger.error('Erro ao gerar ranking do grupo:', { error: error.message });
|
|
54
|
-
await sendAndStore(sock,
|
|
55
|
-
remoteJid,
|
|
56
|
-
{ text: `Erro ao gerar ranking: ${error.message}` },
|
|
57
|
-
{ quoted: messageInfo, ephemeralExpiration: expirationMessage },
|
|
58
|
-
);
|
|
38
|
+
await sendAndStore(sock, remoteJid, { text: `Erro ao gerar ranking: ${error.message}` }, { quoted: messageInfo, ephemeralExpiration: expirationMessage });
|
|
59
39
|
}
|
|
60
40
|
}
|
|
@@ -545,15 +545,7 @@ export const enrichRankingRows = async ({ rows, scope, remoteJid, botJid }) => {
|
|
|
545
545
|
* @param {{scope: 'group'|'global', remoteJid?: string|null, botJid?: string|null, limit?: number|null, includeTopType?: boolean, includeDbStart?: boolean, enrichRows?: boolean}} params
|
|
546
546
|
* @returns {Promise<{rows: Array<any>, totalMessages: number, topType: {label: string, count: number}|null, topTotal: number, dbStart: any}>}
|
|
547
547
|
*/
|
|
548
|
-
export const getRankingReport = async ({
|
|
549
|
-
scope,
|
|
550
|
-
remoteJid,
|
|
551
|
-
botJid,
|
|
552
|
-
limit = null,
|
|
553
|
-
includeTopType = true,
|
|
554
|
-
includeDbStart = true,
|
|
555
|
-
enrichRows = true,
|
|
556
|
-
}) => {
|
|
548
|
+
export const getRankingReport = async ({ scope, remoteJid, botJid, limit = null, includeTopType = true, includeDbStart = true, enrichRows = true }) => {
|
|
557
549
|
const totalMessages = await getTotalMessages({ scope, remoteJid, botJid });
|
|
558
550
|
const topType = includeTopType ? await getTopMessageType({ scope, remoteJid, botJid }) : null;
|
|
559
551
|
const { rows } = await getRankingBase({ scope, remoteJid, botJid, limit });
|
|
@@ -224,9 +224,7 @@ function runProcess(command, args, { timeoutMs }) {
|
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
if (code !== 0) {
|
|
227
|
-
const processError = new Error(
|
|
228
|
-
`${command} finalizou com código ${code}${signal ? ` (sinal: ${signal})` : ''}.`,
|
|
229
|
-
);
|
|
227
|
+
const processError = new Error(`${command} finalizou com código ${code}${signal ? ` (sinal: ${signal})` : ''}.`);
|
|
230
228
|
processError.code = code;
|
|
231
229
|
processError.signal = signal;
|
|
232
230
|
processError.stderr = stderr;
|
|
@@ -277,17 +275,7 @@ export async function convertToWebp(inputPath, mediaType, userId, uniqueId, opti
|
|
|
277
275
|
const sanitizedUserId = String(userId || 'anon').replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
278
276
|
const userStickerDir = path.join(TEMP_DIR, sanitizedUserId);
|
|
279
277
|
const outputPath = path.join(userStickerDir, `sticker_${uniqueId}.webp`);
|
|
280
|
-
const {
|
|
281
|
-
stretch = true,
|
|
282
|
-
videoMaxDurationSeconds = DEFAULT_VIDEO_MAX_DURATION_SECONDS,
|
|
283
|
-
videoFps = DEFAULT_VIDEO_FPS,
|
|
284
|
-
videoQuality = DEFAULT_VIDEO_QUALITY,
|
|
285
|
-
videoCompressionLevel = DEFAULT_VIDEO_COMPRESSION_LEVEL,
|
|
286
|
-
maxOutputSizeBytes,
|
|
287
|
-
maxOutputSizeBytesByType = DEFAULT_MAX_OUTPUT_SIZE_BYTES_BY_TYPE,
|
|
288
|
-
timeoutMsByType = DEFAULT_TIMEOUT_MS_BY_TYPE,
|
|
289
|
-
timeoutMs,
|
|
290
|
-
} = options;
|
|
278
|
+
const { stretch = true, videoMaxDurationSeconds = DEFAULT_VIDEO_MAX_DURATION_SECONDS, videoFps = DEFAULT_VIDEO_FPS, videoQuality = DEFAULT_VIDEO_QUALITY, videoCompressionLevel = DEFAULT_VIDEO_COMPRESSION_LEVEL, maxOutputSizeBytes, maxOutputSizeBytesByType = DEFAULT_MAX_OUTPUT_SIZE_BYTES_BY_TYPE, timeoutMsByType = DEFAULT_TIMEOUT_MS_BY_TYPE, timeoutMs } = options;
|
|
291
279
|
const maxOutputLimit = resolveMaxOutputLimit(mediaType, maxOutputSizeBytes, maxOutputSizeBytesByType);
|
|
292
280
|
|
|
293
281
|
try {
|
|
@@ -309,9 +297,7 @@ export async function convertToWebp(inputPath, mediaType, userId, uniqueId, opti
|
|
|
309
297
|
return outputPath;
|
|
310
298
|
}
|
|
311
299
|
|
|
312
|
-
const normalizedDuration = Math.trunc(
|
|
313
|
-
clampNumber(videoMaxDurationSeconds, 1, 30, DEFAULT_VIDEO_MAX_DURATION_SECONDS),
|
|
314
|
-
);
|
|
300
|
+
const normalizedDuration = Math.trunc(clampNumber(videoMaxDurationSeconds, 1, 30, DEFAULT_VIDEO_MAX_DURATION_SECONDS));
|
|
315
301
|
const normalizedFps = Math.trunc(clampNumber(videoFps, 1, 30, DEFAULT_VIDEO_FPS));
|
|
316
302
|
const normalizedQuality = Math.trunc(clampNumber(videoQuality, 0, 100, DEFAULT_VIDEO_QUALITY));
|
|
317
303
|
const normalizedCompression = Math.trunc(clampNumber(videoCompressionLevel, 0, 6, DEFAULT_VIDEO_COMPRESSION_LEVEL));
|
|
@@ -331,16 +317,7 @@ export async function convertToWebp(inputPath, mediaType, userId, uniqueId, opti
|
|
|
331
317
|
ffmpegArgs.push('-vcodec', 'libwebp', '-loop', '0', '-preset', 'default', '-an');
|
|
332
318
|
|
|
333
319
|
if (mediaType === 'video') {
|
|
334
|
-
ffmpegArgs.push(
|
|
335
|
-
'-vsync',
|
|
336
|
-
'0',
|
|
337
|
-
'-lossless',
|
|
338
|
-
'0',
|
|
339
|
-
'-q:v',
|
|
340
|
-
String(normalizedQuality),
|
|
341
|
-
'-compression_level',
|
|
342
|
-
String(normalizedCompression),
|
|
343
|
-
);
|
|
320
|
+
ffmpegArgs.push('-vsync', '0', '-lossless', '0', '-q:v', String(normalizedQuality), '-compression_level', String(normalizedCompression));
|
|
344
321
|
} else {
|
|
345
322
|
ffmpegArgs.push('-lossless', '1');
|
|
346
323
|
}
|
|
@@ -24,10 +24,7 @@ const STICKER_WEB_ORIGIN = resolveStickerWebOrigin();
|
|
|
24
24
|
function normalizeBasePath(value, fallback) {
|
|
25
25
|
const raw = String(value || '').trim() || fallback;
|
|
26
26
|
const withLeadingSlash = raw.startsWith('/') ? raw : `/${raw}`;
|
|
27
|
-
const withoutTrailingSlash =
|
|
28
|
-
withLeadingSlash.length > 1 && withLeadingSlash.endsWith('/')
|
|
29
|
-
? withLeadingSlash.slice(0, -1)
|
|
30
|
-
: withLeadingSlash;
|
|
27
|
+
const withoutTrailingSlash = withLeadingSlash.length > 1 && withLeadingSlash.endsWith('/') ? withLeadingSlash.slice(0, -1) : withLeadingSlash;
|
|
31
28
|
return withoutTrailingSlash || fallback;
|
|
32
29
|
}
|
|
33
30
|
|
|
@@ -45,14 +42,7 @@ function normalizeOrigin(value) {
|
|
|
45
42
|
}
|
|
46
43
|
|
|
47
44
|
function resolveStickerWebOrigin() {
|
|
48
|
-
const candidates = [
|
|
49
|
-
process.env.STICKER_WEB_ORIGIN,
|
|
50
|
-
process.env.APP_BASE_URL,
|
|
51
|
-
process.env.PUBLIC_BASE_URL,
|
|
52
|
-
process.env.SITE_URL,
|
|
53
|
-
process.env.WEB_URL,
|
|
54
|
-
process.env.BASE_URL,
|
|
55
|
-
];
|
|
45
|
+
const candidates = [process.env.STICKER_WEB_ORIGIN, process.env.APP_BASE_URL, process.env.PUBLIC_BASE_URL, process.env.SITE_URL, process.env.WEB_URL, process.env.BASE_URL];
|
|
56
46
|
|
|
57
47
|
for (const candidate of candidates) {
|
|
58
48
|
const normalized = normalizeOrigin(candidate);
|
|
@@ -71,9 +61,15 @@ function buildPackWebUrl(packKey) {
|
|
|
71
61
|
}
|
|
72
62
|
|
|
73
63
|
function isPackPubliclyVisible(pack) {
|
|
74
|
-
const visibility = String(pack?.visibility || '')
|
|
75
|
-
|
|
76
|
-
|
|
64
|
+
const visibility = String(pack?.visibility || '')
|
|
65
|
+
.trim()
|
|
66
|
+
.toLowerCase();
|
|
67
|
+
const status = String(pack?.status || 'published')
|
|
68
|
+
.trim()
|
|
69
|
+
.toLowerCase();
|
|
70
|
+
const packStatus = String(pack?.pack_status || 'ready')
|
|
71
|
+
.trim()
|
|
72
|
+
.toLowerCase();
|
|
77
73
|
return (visibility === 'public' || visibility === 'unlisted') && status === 'published' && packStatus === 'ready';
|
|
78
74
|
}
|
|
79
75
|
|
|
@@ -218,10 +214,7 @@ function buildAutoPackNoticeText(result, commandPrefix = DEFAULT_COMMAND_PREFIX)
|
|
|
218
214
|
const countLabel = itemCount > 0 ? ` (${itemCount}/${AUTO_PACK_MAX_ITEMS})` : '';
|
|
219
215
|
|
|
220
216
|
if (result.status === 'duplicate') {
|
|
221
|
-
const duplicateLines = [
|
|
222
|
-
`ℹ️ Essa figurinha já estava no pack automático *${packName}*.`,
|
|
223
|
-
`Use *${commandPrefix}pack info ${packIdentifier}* para ver o pack ou *${commandPrefix}pack send ${packIdentifier}* para enviar.`,
|
|
224
|
-
];
|
|
217
|
+
const duplicateLines = [`ℹ️ Essa figurinha já estava no pack automático *${packName}*.`, `Use *${commandPrefix}pack info ${packIdentifier}* para ver o pack ou *${commandPrefix}pack send ${packIdentifier}* para enviar.`];
|
|
225
218
|
if (packWebUrl) {
|
|
226
219
|
duplicateLines.push(`🌐 Link do pack no site: ${packWebUrl}`);
|
|
227
220
|
} else {
|
|
@@ -230,11 +223,7 @@ function buildAutoPackNoticeText(result, commandPrefix = DEFAULT_COMMAND_PREFIX)
|
|
|
230
223
|
return duplicateLines.join('\n');
|
|
231
224
|
}
|
|
232
225
|
|
|
233
|
-
const savedLines = [
|
|
234
|
-
`📦 Figurinha salva automaticamente no pack *${packName}*${countLabel}.\n\n`,
|
|
235
|
-
`Dica: use *${commandPrefix}pack list* para gerenciar seus packs.`,
|
|
236
|
-
`Para enviar agora: *${commandPrefix}pack send ${packCommandTarget}*.`,
|
|
237
|
-
];
|
|
226
|
+
const savedLines = [`📦 Figurinha salva automaticamente no pack *${packName}*${countLabel}.\n\n`, `Dica: use *${commandPrefix}pack list* para gerenciar seus packs.`, `Para enviar agora: *${commandPrefix}pack send ${packCommandTarget}*.`];
|
|
238
227
|
if (packWebUrl) {
|
|
239
228
|
savedLines.push(`🌐 Abrir no site: ${packWebUrl}`);
|
|
240
229
|
} else {
|
|
@@ -32,10 +32,7 @@ const STICKER_WEB_ORIGIN = resolveStickerWebOrigin();
|
|
|
32
32
|
function normalizeBasePath(value, fallback) {
|
|
33
33
|
const raw = String(value || '').trim() || fallback;
|
|
34
34
|
const withLeadingSlash = raw.startsWith('/') ? raw : `/${raw}`;
|
|
35
|
-
const withoutTrailingSlash =
|
|
36
|
-
withLeadingSlash.length > 1 && withLeadingSlash.endsWith('/')
|
|
37
|
-
? withLeadingSlash.slice(0, -1)
|
|
38
|
-
: withLeadingSlash;
|
|
35
|
+
const withoutTrailingSlash = withLeadingSlash.length > 1 && withLeadingSlash.endsWith('/') ? withLeadingSlash.slice(0, -1) : withLeadingSlash;
|
|
39
36
|
return withoutTrailingSlash || fallback;
|
|
40
37
|
}
|
|
41
38
|
|
|
@@ -53,15 +50,7 @@ function normalizeOrigin(value) {
|
|
|
53
50
|
}
|
|
54
51
|
|
|
55
52
|
function resolveStickerWebOrigin() {
|
|
56
|
-
const candidates = [
|
|
57
|
-
process.env.STICKER_WEB_ORIGIN,
|
|
58
|
-
process.env.APP_BASE_URL,
|
|
59
|
-
process.env.PUBLIC_BASE_URL,
|
|
60
|
-
process.env.SITE_URL,
|
|
61
|
-
process.env.WEB_URL,
|
|
62
|
-
process.env.BASE_URL,
|
|
63
|
-
process.env.STICKER_DEFAULT_PACK_NAME,
|
|
64
|
-
];
|
|
53
|
+
const candidates = [process.env.STICKER_WEB_ORIGIN, process.env.APP_BASE_URL, process.env.PUBLIC_BASE_URL, process.env.SITE_URL, process.env.WEB_URL, process.env.BASE_URL, process.env.STICKER_DEFAULT_PACK_NAME];
|
|
65
54
|
|
|
66
55
|
for (const candidate of candidates) {
|
|
67
56
|
const normalized = normalizeOrigin(candidate);
|
|
@@ -79,9 +68,15 @@ function buildPackWebUrl(packKey) {
|
|
|
79
68
|
}
|
|
80
69
|
|
|
81
70
|
function isPackPubliclyVisible(pack) {
|
|
82
|
-
const visibility = String(pack?.visibility || '')
|
|
83
|
-
|
|
84
|
-
|
|
71
|
+
const visibility = String(pack?.visibility || '')
|
|
72
|
+
.trim()
|
|
73
|
+
.toLowerCase();
|
|
74
|
+
const status = String(pack?.status || 'published')
|
|
75
|
+
.trim()
|
|
76
|
+
.toLowerCase();
|
|
77
|
+
const packStatus = String(pack?.pack_status || 'ready')
|
|
78
|
+
.trim()
|
|
79
|
+
.toLowerCase();
|
|
85
80
|
return (visibility === 'public' || visibility === 'unlisted') && status === 'published' && packStatus === 'ready';
|
|
86
81
|
}
|
|
87
82
|
|
|
@@ -146,10 +141,7 @@ function buildAutoPackNoticeText(result, commandPrefix = DEFAULT_COMMAND_PREFIX)
|
|
|
146
141
|
const countLabel = itemCount > 0 ? ` (${itemCount}/${AUTO_PACK_MAX_ITEMS})` : '';
|
|
147
142
|
|
|
148
143
|
if (result.status === 'duplicate') {
|
|
149
|
-
const duplicateLines = [
|
|
150
|
-
`ℹ️ Essa figurinha já estava no pack automático *${packName}*.`,
|
|
151
|
-
`Use *${commandPrefix}pack info ${packIdentifier}* para ver o pack ou *${commandPrefix}pack send ${packIdentifier}* para enviar.`,
|
|
152
|
-
];
|
|
144
|
+
const duplicateLines = [`ℹ️ Essa figurinha já estava no pack automático *${packName}*.`, `Use *${commandPrefix}pack info ${packIdentifier}* para ver o pack ou *${commandPrefix}pack send ${packIdentifier}* para enviar.`];
|
|
153
145
|
if (packWebUrl) {
|
|
154
146
|
duplicateLines.push(`🌐 Link do pack no site: ${packWebUrl}`);
|
|
155
147
|
} else {
|
|
@@ -158,11 +150,7 @@ function buildAutoPackNoticeText(result, commandPrefix = DEFAULT_COMMAND_PREFIX)
|
|
|
158
150
|
return duplicateLines.join('\n');
|
|
159
151
|
}
|
|
160
152
|
|
|
161
|
-
const savedLines = [
|
|
162
|
-
`📦 Figurinha salva automaticamente no pack *${packName}*${countLabel}.\n\n`,
|
|
163
|
-
`Dica: use *${commandPrefix}pack list* para gerenciar seus packs.`,
|
|
164
|
-
`Para enviar agora: *${commandPrefix}pack send ${packCommandTarget}*.`,
|
|
165
|
-
];
|
|
153
|
+
const savedLines = [`📦 Figurinha salva automaticamente no pack *${packName}*${countLabel}.\n\n`, `Dica: use *${commandPrefix}pack list* para gerenciar seus packs.`, `Para enviar agora: *${commandPrefix}pack send ${packCommandTarget}*.`];
|
|
166
154
|
if (packWebUrl) {
|
|
167
155
|
savedLines.push(`🌐 Abrir no site: ${packWebUrl}`);
|
|
168
156
|
} else {
|
|
@@ -10,7 +10,10 @@ const AUTO_COLLECT_ENABLED = process.env.STICKER_PACK_AUTO_COLLECT_ENABLED !== '
|
|
|
10
10
|
const AUTO_PACK_NAME_MAX_LENGTH = 120;
|
|
11
11
|
const AUTO_PACK_DESCRIPTION_MARKER = '[auto-pack:collector]';
|
|
12
12
|
const AUTO_PACK_DESCRIPTION_TEXT = 'Coleção automática de figurinhas criadas pelo usuário.';
|
|
13
|
-
const normalizeVisibility = (value) =>
|
|
13
|
+
const normalizeVisibility = (value) =>
|
|
14
|
+
String(value || '')
|
|
15
|
+
.trim()
|
|
16
|
+
.toLowerCase();
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* Escapa texto para uso seguro em RegExp.
|
|
@@ -26,7 +29,10 @@ const escapeRegex = (value) => String(value || '').replace(/[.*+?^${}()|[\]\\]/g
|
|
|
26
29
|
* @param {unknown} value Valor de entrada.
|
|
27
30
|
* @returns {string} Texto sem diacríticos.
|
|
28
31
|
*/
|
|
29
|
-
const removeDiacritics = (value) =>
|
|
32
|
+
const removeDiacritics = (value) =>
|
|
33
|
+
String(value || '')
|
|
34
|
+
.normalize('NFD')
|
|
35
|
+
.replace(/[\u0300-\u036f]/g, '');
|
|
30
36
|
|
|
31
37
|
/**
|
|
32
38
|
* Gera nome de pack automático válido no padrão aceito.
|
|
@@ -51,7 +57,13 @@ const isThemeCurationAutoPack = (pack) => {
|
|
|
51
57
|
if (!pack || typeof pack !== 'object') return false;
|
|
52
58
|
const description = String(pack.description || '').toLowerCase();
|
|
53
59
|
if (description.includes('[auto-theme:') || description.includes('[auto-tag:')) return true;
|
|
54
|
-
if (
|
|
60
|
+
if (
|
|
61
|
+
String(pack.name || '')
|
|
62
|
+
.trim()
|
|
63
|
+
.toLowerCase()
|
|
64
|
+
.startsWith('[auto]')
|
|
65
|
+
)
|
|
66
|
+
return true;
|
|
55
67
|
return Boolean(String(pack.pack_theme_key || '').trim());
|
|
56
68
|
};
|
|
57
69
|
|
|
@@ -225,10 +237,7 @@ export function createAutoPackCollector(options = {}) {
|
|
|
225
237
|
}
|
|
226
238
|
|
|
227
239
|
const managedAutoPacks = packs.filter((entry) => isAutoCollectorPack(entry));
|
|
228
|
-
const preferredPack =
|
|
229
|
-
managedAutoPacks.find((entry) => normalizeVisibility(entry?.visibility) === AUTO_PACK_TARGET_VISIBILITY)
|
|
230
|
-
|| managedAutoPacks[0]
|
|
231
|
-
|| null;
|
|
240
|
+
const preferredPack = managedAutoPacks.find((entry) => normalizeVisibility(entry?.visibility) === AUTO_PACK_TARGET_VISIBILITY) || managedAutoPacks[0] || null;
|
|
232
241
|
|
|
233
242
|
if (preferredPack) {
|
|
234
243
|
const ensuredPack = await ensureAutoPackVisibility({ ownerJid, pack: preferredPack });
|
|
@@ -4,7 +4,9 @@ import { executeQuery, TABLES } from '../../../database/index.js';
|
|
|
4
4
|
import { normalizeDomainEventPayload } from './domainEvents.js';
|
|
5
5
|
|
|
6
6
|
const normalizeStatus = (value) => {
|
|
7
|
-
const normalized = String(value || '')
|
|
7
|
+
const normalized = String(value || '')
|
|
8
|
+
.trim()
|
|
9
|
+
.toLowerCase();
|
|
8
10
|
if (['pending', 'processing', 'completed', 'failed'].includes(normalized)) return normalized;
|
|
9
11
|
return null;
|
|
10
12
|
};
|
|
@@ -35,12 +37,7 @@ const clampInt = (value, fallback, min, max) => {
|
|
|
35
37
|
return Math.max(min, Math.min(max, Math.floor(numeric)));
|
|
36
38
|
};
|
|
37
39
|
|
|
38
|
-
const CLAIM_LOCK_TIMEOUT_SECONDS = clampInt(
|
|
39
|
-
process.env.DOMAIN_EVENT_OUTBOX_LOCK_TIMEOUT_SECONDS,
|
|
40
|
-
15 * 60,
|
|
41
|
-
30,
|
|
42
|
-
24 * 60 * 60,
|
|
43
|
-
);
|
|
40
|
+
const CLAIM_LOCK_TIMEOUT_SECONDS = clampInt(process.env.DOMAIN_EVENT_OUTBOX_LOCK_TIMEOUT_SECONDS, 15 * 60, 30, 24 * 60 * 60);
|
|
44
41
|
|
|
45
42
|
const normalizeRow = (row) => {
|
|
46
43
|
if (!row) return null;
|
|
@@ -88,28 +85,13 @@ export async function enqueueDomainEvent(eventPayload, connection = null) {
|
|
|
88
85
|
priority = GREATEST(priority, VALUES(priority)),
|
|
89
86
|
available_at = LEAST(available_at, VALUES(available_at)),
|
|
90
87
|
updated_at = CURRENT_TIMESTAMP`,
|
|
91
|
-
[
|
|
92
|
-
normalized.event_type,
|
|
93
|
-
normalized.aggregate_type,
|
|
94
|
-
normalized.aggregate_id,
|
|
95
|
-
JSON.stringify(normalized.payload ?? {}),
|
|
96
|
-
normalized.priority,
|
|
97
|
-
normalized.idempotency_key,
|
|
98
|
-
normalized.available_at,
|
|
99
|
-
normalized.max_attempts,
|
|
100
|
-
],
|
|
88
|
+
[normalized.event_type, normalized.aggregate_type, normalized.aggregate_id, JSON.stringify(normalized.payload ?? {}), normalized.priority, normalized.idempotency_key, normalized.available_at, normalized.max_attempts],
|
|
101
89
|
connection,
|
|
102
90
|
);
|
|
103
91
|
return true;
|
|
104
92
|
}
|
|
105
93
|
|
|
106
|
-
export async function claimDomainEvent(
|
|
107
|
-
{
|
|
108
|
-
eventTypes = [],
|
|
109
|
-
allowRetryFailed = true,
|
|
110
|
-
} = {},
|
|
111
|
-
connection = null,
|
|
112
|
-
) {
|
|
94
|
+
export async function claimDomainEvent({ eventTypes = [], allowRetryFailed = true } = {}, connection = null) {
|
|
113
95
|
const workerToken = randomUUID();
|
|
114
96
|
const statusClause = allowRetryFailed
|
|
115
97
|
? `(status = 'pending'
|
|
@@ -119,9 +101,15 @@ export async function claimDomainEvent(
|
|
|
119
101
|
OR (status = 'processing' AND locked_at <= (UTC_TIMESTAMP() - INTERVAL ${CLAIM_LOCK_TIMEOUT_SECONDS} SECOND)))`;
|
|
120
102
|
|
|
121
103
|
const normalizedTypes = Array.from(
|
|
122
|
-
new Set(
|
|
123
|
-
.
|
|
124
|
-
|
|
104
|
+
new Set(
|
|
105
|
+
(Array.isArray(eventTypes) ? eventTypes : [])
|
|
106
|
+
.map((type) =>
|
|
107
|
+
String(type || '')
|
|
108
|
+
.trim()
|
|
109
|
+
.toUpperCase(),
|
|
110
|
+
)
|
|
111
|
+
.filter(Boolean),
|
|
112
|
+
),
|
|
125
113
|
);
|
|
126
114
|
|
|
127
115
|
let eventTypeClause = '';
|
|
@@ -184,18 +172,14 @@ export async function completeDomainEvent(eventId, connection = null) {
|
|
|
184
172
|
return true;
|
|
185
173
|
}
|
|
186
174
|
|
|
187
|
-
export async function failDomainEvent(
|
|
188
|
-
eventId,
|
|
189
|
-
{
|
|
190
|
-
error = null,
|
|
191
|
-
retryDelaySeconds = 0,
|
|
192
|
-
} = {},
|
|
193
|
-
connection = null,
|
|
194
|
-
) {
|
|
175
|
+
export async function failDomainEvent(eventId, { error = null, retryDelaySeconds = 0 } = {}, connection = null) {
|
|
195
176
|
if (!eventId) return false;
|
|
196
177
|
|
|
197
178
|
const safeDelay = clampInt(retryDelaySeconds, 0, 0, 86400 * 7);
|
|
198
|
-
const message =
|
|
179
|
+
const message =
|
|
180
|
+
String(error || '')
|
|
181
|
+
.trim()
|
|
182
|
+
.slice(0, 255) || null;
|
|
199
183
|
|
|
200
184
|
await executeQuery(
|
|
201
185
|
`UPDATE ${TABLES.DOMAIN_EVENT_OUTBOX}
|
|
@@ -32,16 +32,7 @@ const normalizeIdempotencyKey = (value) =>
|
|
|
32
32
|
.replace(/[^a-zA-Z0-9_:-]/g, '')
|
|
33
33
|
.slice(0, 180);
|
|
34
34
|
|
|
35
|
-
export const normalizeDomainEventPayload = ({
|
|
36
|
-
eventType,
|
|
37
|
-
aggregateType,
|
|
38
|
-
aggregateId,
|
|
39
|
-
payload = null,
|
|
40
|
-
priority = 50,
|
|
41
|
-
availableAt = null,
|
|
42
|
-
idempotencyKey = '',
|
|
43
|
-
maxAttempts = 10,
|
|
44
|
-
} = {}) => {
|
|
35
|
+
export const normalizeDomainEventPayload = ({ eventType, aggregateType, aggregateId, payload = null, priority = 50, availableAt = null, idempotencyKey = '', maxAttempts = 10 } = {}) => {
|
|
45
36
|
const normalizedType = normalizeType(eventType);
|
|
46
37
|
if (!normalizedType) return null;
|
|
47
38
|
const normalizedAggregateType = normalizeAggregateType(aggregateType);
|
|
@@ -52,7 +43,7 @@ export const normalizeDomainEventPayload = ({
|
|
|
52
43
|
event_type: normalizedType,
|
|
53
44
|
aggregate_type: normalizedAggregateType,
|
|
54
45
|
aggregate_id: normalizedAggregateId,
|
|
55
|
-
payload: payload && typeof payload === 'object' ? payload : payload ?? null,
|
|
46
|
+
payload: payload && typeof payload === 'object' ? payload : (payload ?? null),
|
|
56
47
|
priority: Math.max(1, Math.min(100, Number(priority) || 50)),
|
|
57
48
|
available_at: availableAt ? new Date(availableAt) : null,
|
|
58
49
|
idempotency_key: normalizeIdempotencyKey(idempotencyKey) || null,
|