@kaikybrofc/omnizap-system 2.2.2 → 2.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,6 +33,12 @@ Use as rotas abaixo para consumir o bloco já renderizado com dados do sistema:
33
33
  - JSON: `GET /api/sticker-packs/readme-summary`
34
34
  - Markdown: `GET /api/sticker-packs/readme-markdown`
35
35
 
36
+ Para atualizar este `README.md` automaticamente com o conteúdo renderizado:
37
+
38
+ ```bash
39
+ npm run readme:sync-snapshot
40
+ ```
41
+
36
42
  Conteúdo incluído no snapshot:
37
43
 
38
44
  - total de usuários (`lid_map`)
@@ -44,6 +50,94 @@ Conteúdo incluído no snapshot:
44
50
 
45
51
  Atualização em cache: **30 minutos** por padrão (`README_SUMMARY_CACHE_SECONDS=1800`).
46
52
 
53
+ <!-- README_SNAPSHOT:START -->
54
+ ## OmniZap System Snapshot
55
+
56
+ Atualizado em: **2026-02-28T01:11:03.592Z**
57
+ Janela de atualização: **1800 segundos**
58
+
59
+ ### Totais do sistema
60
+ - Usuários (lid_map): **5.502**
61
+ - Grupos: **116**
62
+ - Packs: **295**
63
+ - Stickers: **6.313**
64
+ - Mensagens registradas: **438.964**
65
+
66
+ ### Tipos de mensagem mais usados (amostra de 25.000 mensagens)
67
+ 1. `texto` - **16.530**
68
+ 2. `figurinha` - **4.262**
69
+ 3. `reacao` - **1.619**
70
+ 4. `imagem` - **1.326**
71
+ 5. `outros` - **799**
72
+ 6. `video` - **245**
73
+ 7. `audio` - **213**
74
+ 8. `documento` - **6**
75
+
76
+ ### Comandos disponíveis
77
+ - `/add @user`
78
+ - `/addmode`
79
+ - `/autorequests`
80
+ - `/autosticker`
81
+ - `/ban @user`
82
+ - `/captcha`
83
+ - `/cat`
84
+ - `/catimg`
85
+ - `/catprompt`
86
+ - `/catprompt reset`
87
+ - `/dado`
88
+ - `/down @user`
89
+ - `/farewell`
90
+ - `/groups`
91
+ - `/info`
92
+ - `/invite`
93
+ - `/join`
94
+ - `/leave`
95
+ - `/menu anime`
96
+ - `/menu figurinhas`
97
+ - `/menu ia`
98
+ - `/menu midia`
99
+ - `/menu quote`
100
+ - `/menu stats`
101
+ - `/menuadm`
102
+ - `/metadata`
103
+ - `/newgroup`
104
+ - `/noticias`
105
+ - `/nsfw`
106
+ - `/pack add`
107
+ - `/pack create "Meu Pack"`
108
+ - `/pack list`
109
+ - `/pack send`
110
+ - `/ping`
111
+ - `/play`
112
+ - `/playvid`
113
+ - `/prefix`
114
+ - `/premium`
115
+ - `/quote`
116
+ - `/ranking`
117
+ - `/rankingglobal`
118
+ - `/requests`
119
+ - `/revoke`
120
+ - `/s`
121
+ - `/semmsg`
122
+ - `/setdesc`
123
+ - `/setgroup`
124
+ - `/setsubject`
125
+ - `/st`
126
+ - `/stb`
127
+ - `/sticker`
128
+ - `/stickertext`
129
+ - `/stickertextblink`
130
+ - `/stickertextwhite`
131
+ - `/stw`
132
+ - `/temp`
133
+ - `/tiktok`
134
+ - `/toimg`
135
+ - `/up @user`
136
+ - `/updaterequests`
137
+ - `/user perfil`
138
+ - `/welcome`
139
+ <!-- README_SNAPSHOT:END -->
140
+
47
141
  ## Recursos principais
48
142
 
49
143
  - Gerenciamento de grupos (admin, boas-vindas, despedida, anti-link, captcha).
@@ -150,6 +244,7 @@ Variáveis legadas foram mantidas por compatibilidade (`QUOTE_API_URL`, `WAIFU_A
150
244
  - `npm run pm2:prod`: sobe com PM2 usando `ecosystem.prod.config.cjs`.
151
245
  - `npm run deploy`: deploy automático de `public/` com cache-bust, backup, validação e reload do Nginx.
152
246
  - `npm run deploy:dry-run`: simula o deploy sem publicar/recarregar serviços.
247
+ - `npm run readme:sync-snapshot`: sincroniza o bloco dinâmico do README consumindo `/api/sticker-packs/readme-markdown`.
153
248
  - `npm run release`: release completo com versão unificada (npmjs + GitHub Packages + GitHub Release) e verificação final.
154
249
  - `npm run release:minor`: bump `minor` + deploy + publish do package.
155
250
  - `npm run release:major`: bump `major` + deploy + publish do package.
@@ -256,6 +351,9 @@ Variáveis do fluxo de release (git):
256
351
  - `RELEASE_GIT_BRANCH` (opcional; vazio usa branch atual)
257
352
  - `RELEASE_GIT_PRE_COMMIT_MESSAGE` (default: `chore(release): auto-commit before release`)
258
353
  - `RELEASE_GIT_COMMIT_VERSION` (default: `1`) - commita alteração da versão após sucesso
354
+ - `RELEASE_README_SYNC` (default: `1`) - sincroniza bloco dinâmico do README via API antes do commit/tag
355
+ - `RELEASE_README_SYNC_REQUIRED` (default: `0`) - se `1`, falha o release quando a sincronização do README falhar
356
+ - `RELEASE_README_SYNC_COMMAND` (default: `npm run readme:sync-snapshot`) - comando customizável para sincronização
259
357
  - `RELEASE_GIT_VERSION_COMMIT_PREFIX` (default: `chore(release): v`)
260
358
  - `RELEASE_GIT_TAG_CREATE` (default: `1`) - cria tag `vX.Y.Z` no release
261
359
  - `RELEASE_GIT_TAG_PUSH` (default: `1`) - envia a tag para o remoto
@@ -5778,7 +5778,7 @@ const extractCommandsFromMenuLine = (line, commandPrefix) => {
5778
5778
  const tokens = withoutPrefix.split(/\s+/).filter(Boolean);
5779
5779
  const selectedTokens = [];
5780
5780
  for (const token of tokens) {
5781
- if (/^[<[(]/.test(token)) break;
5781
+ if (!/^[a-z0-9_-]+$/i.test(token)) break;
5782
5782
  selectedTokens.push(token);
5783
5783
  }
5784
5784
  if (!selectedTokens.length) return '';
@@ -5813,32 +5813,35 @@ const collectAvailableMenuCommands = (commandPrefix = README_COMMAND_PREFIX) =>
5813
5813
  };
5814
5814
 
5815
5815
  const renderReadmeSnapshotMarkdown = ({ generatedAt, totals, topMessageTypes, commands }) => {
5816
- const typeLines = topMessageTypes.length
5817
- ? topMessageTypes.map((entry, index) => `${index + 1}. \`${entry.type}\` - **${formatPtBrInteger(entry.total)}**`)
5818
- : ['1. `outros` - **0**'];
5816
+ const typeRows = topMessageTypes.length
5817
+ ? topMessageTypes.map((entry) => `| \`${entry.type}\` | ${formatPtBrInteger(entry.total)} |`)
5818
+ : ['| `outros` | 0 |'];
5819
5819
 
5820
- const commandLines = commands.length
5821
- ? commands.map((command) => `- \`${command}\``)
5822
- : ['- Nenhum comando identificado no menu atual.'];
5820
+ const commandInline = commands.length ? commands.map((command) => `\`${command}\``).join(' · ') : 'Nenhum comando identificado no menu atual.';
5823
5821
 
5824
5822
  return [
5825
- '## OmniZap System Snapshot',
5823
+ '### Snapshot do Sistema',
5826
5824
  '',
5827
- `Atualizado em: **${generatedAt}**`,
5828
- `Janela de atualização: **${README_SUMMARY_CACHE_SECONDS} segundos**`,
5825
+ `> Atualizado em \`${generatedAt}\` | cache \`${README_SUMMARY_CACHE_SECONDS}s\``,
5829
5826
  '',
5830
- '### Totais do sistema',
5831
- `- Usuários (lid_map): **${formatPtBrInteger(totals.total_users)}**`,
5832
- `- Grupos: **${formatPtBrInteger(totals.total_groups)}**`,
5833
- `- Packs: **${formatPtBrInteger(totals.total_packs)}**`,
5834
- `- Stickers: **${formatPtBrInteger(totals.total_stickers)}**`,
5835
- `- Mensagens registradas: **${formatPtBrInteger(totals.total_messages)}**`,
5827
+ '| Métrica | Valor |',
5828
+ '| --- | ---: |',
5829
+ `| Usuários (lid_map) | ${formatPtBrInteger(totals.total_users)} |`,
5830
+ `| Grupos | ${formatPtBrInteger(totals.total_groups)} |`,
5831
+ `| Packs | ${formatPtBrInteger(totals.total_packs)} |`,
5832
+ `| Stickers | ${formatPtBrInteger(totals.total_stickers)} |`,
5833
+ `| Mensagens registradas | ${formatPtBrInteger(totals.total_messages)} |`,
5836
5834
  '',
5837
- `### Tipos de mensagem mais usados (amostra de ${formatPtBrInteger(totals.message_types_sample_size)} mensagens)`,
5838
- ...typeLines,
5835
+ `#### Tipos de mensagem mais usados (amostra: ${formatPtBrInteger(totals.message_types_sample_size)})`,
5836
+ '| Tipo | Total |',
5837
+ '| --- | ---: |',
5838
+ ...typeRows,
5839
5839
  '',
5840
- '### Comandos disponíveis',
5841
- ...commandLines,
5840
+ `<details><summary>Comandos disponíveis (${formatPtBrInteger(commands.length)})</summary>`,
5841
+ '',
5842
+ commandInline,
5843
+ '',
5844
+ '</details>',
5842
5845
  '',
5843
5846
  ].join('\n');
5844
5847
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaikybrofc/omnizap-system",
3
- "version": "2.2.2",
3
+ "version": "2.2.3",
4
4
  "description": "Sistema profissional de automação WhatsApp com tecnologia Baileys",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
@@ -58,6 +58,7 @@
58
58
  "pm2:prod": "pm2 start ecosystem.prod.config.cjs",
59
59
  "deploy": "bash ./scripts/deploy.sh",
60
60
  "deploy:dry-run": "DEPLOY_DRY_RUN=1 bash ./scripts/deploy.sh",
61
+ "readme:sync-snapshot": "node ./scripts/sync-readme-snapshot.mjs",
61
62
  "release": "bash ./scripts/release.sh",
62
63
  "release:minor": "RELEASE_TYPE=minor bash ./scripts/release.sh",
63
64
  "release:major": "RELEASE_TYPE=major bash ./scripts/release.sh",
@@ -28,6 +28,9 @@ RELEASE_GITHUB_RELEASE_INCLUDE_CHANGED_FILES="${RELEASE_GITHUB_RELEASE_INCLUDE_C
28
28
  RELEASE_GITHUB_RELEASE_MAX_FILES="${RELEASE_GITHUB_RELEASE_MAX_FILES:-300}"
29
29
  RELEASE_REQUIRE_DUAL_PUBLISH="${RELEASE_REQUIRE_DUAL_PUBLISH:-1}"
30
30
  RELEASE_VERIFY_UNIFIED_VERSION="${RELEASE_VERIFY_UNIFIED_VERSION:-1}"
31
+ RELEASE_README_SYNC="${RELEASE_README_SYNC:-1}"
32
+ RELEASE_README_SYNC_REQUIRED="${RELEASE_README_SYNC_REQUIRED:-0}"
33
+ RELEASE_README_SYNC_COMMAND="${RELEASE_README_SYNC_COMMAND:-npm run readme:sync-snapshot}"
31
34
  RELEASE_VERIFY_PRIMARY_REGISTRY="${RELEASE_VERIFY_PRIMARY_REGISTRY:-${DEPLOY_PACKAGE_REGISTRY:-https://npm.pkg.github.com}}"
32
35
  RELEASE_VERIFY_SECONDARY_REGISTRY="${RELEASE_VERIFY_SECONDARY_REGISTRY:-${DEPLOY_PACKAGE_SECONDARY_REGISTRY:-https://registry.npmjs.org}}"
33
36
  RELEASE_VERIFY_PRIMARY_TOKEN_KEYS="${RELEASE_VERIFY_PRIMARY_TOKEN_KEYS:-DEPLOY_PACKAGE_TOKEN,DEPLOY_GITHUB_TOKEN,GITHUB_TOKEN,GH_TOKEN,NPM_TOKEN,NODE_AUTH_TOKEN}"
@@ -439,6 +442,20 @@ if ! (
439
442
  exit 1
440
443
  fi
441
444
 
445
+ if [ "$RELEASE_README_SYNC" = "1" ]; then
446
+ log "Sincronizando bloco dinâmico do README"
447
+ if ! (
448
+ cd "$PROJECT_ROOT" &&
449
+ bash -lc "$RELEASE_README_SYNC_COMMAND"
450
+ ); then
451
+ if [ "$RELEASE_README_SYNC_REQUIRED" = "1" ]; then
452
+ printf '[release] Falha ao sincronizar README e RELEASE_README_SYNC_REQUIRED=1.\n' >&2
453
+ exit 1
454
+ fi
455
+ log "Falha ao sincronizar README. Continuando release (RELEASE_README_SYNC_REQUIRED=0)."
456
+ fi
457
+ fi
458
+
442
459
  if [ "$RELEASE_GIT_COMMIT_VERSION" = "1" ]; then
443
460
  commit_and_push_if_dirty "${RELEASE_GIT_VERSION_COMMIT_PREFIX}${new_version}"
444
461
  fi
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import dotenv from 'dotenv';
7
+
8
+ dotenv.config({ path: '.env' });
9
+
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
12
+ const projectRoot = path.resolve(__dirname, '..');
13
+
14
+ const START_MARKER = '<!-- README_SNAPSHOT:START -->';
15
+ const END_MARKER = '<!-- README_SNAPSHOT:END -->';
16
+
17
+ const readmePath = path.resolve(projectRoot, process.env.README_SNAPSHOT_TARGET_PATH || 'README.md');
18
+ const siteOrigin = String(process.env.SITE_ORIGIN || 'https://omnizap.shop').trim().replace(/\/+$/, '');
19
+ const sourceUrl = String(process.env.README_SNAPSHOT_SOURCE_URL || `${siteOrigin}/api/sticker-packs/readme-markdown`).trim();
20
+ const timeoutMs = Math.max(1000, Number(process.env.README_SNAPSHOT_TIMEOUT_MS) || 15000);
21
+
22
+ const escapeRegExp = (value) => String(value || '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
23
+
24
+ const fetchWithTimeout = async (url, timeout) => {
25
+ const controller = new AbortController();
26
+ const timer = setTimeout(() => controller.abort(), timeout);
27
+ try {
28
+ const response = await fetch(url, {
29
+ method: 'GET',
30
+ headers: { 'User-Agent': 'omnizap-readme-sync/1.0' },
31
+ signal: controller.signal,
32
+ });
33
+ if (!response.ok) {
34
+ throw new Error(`HTTP ${response.status} ao buscar snapshot`);
35
+ }
36
+ const content = String(await response.text()).trim();
37
+ if (!content) {
38
+ throw new Error('Snapshot markdown vazio');
39
+ }
40
+ return content;
41
+ } finally {
42
+ clearTimeout(timer);
43
+ }
44
+ };
45
+
46
+ const syncReadmeSnapshot = async () => {
47
+ const markdown = await fetchWithTimeout(sourceUrl, timeoutMs);
48
+ const readme = await fs.readFile(readmePath, 'utf8');
49
+
50
+ const blockRegex = new RegExp(`${escapeRegExp(START_MARKER)}[\\s\\S]*?${escapeRegExp(END_MARKER)}`, 'm');
51
+ if (!blockRegex.test(readme)) {
52
+ throw new Error(`Marcadores não encontrados em ${path.relative(projectRoot, readmePath)} (${START_MARKER} ... ${END_MARKER})`);
53
+ }
54
+
55
+ const replacement = `${START_MARKER}\n${markdown}\n${END_MARKER}`;
56
+ const nextReadme = readme.replace(blockRegex, replacement);
57
+
58
+ if (nextReadme === readme) {
59
+ console.log('[readme-sync] Snapshot já está atualizado.');
60
+ return;
61
+ }
62
+
63
+ await fs.writeFile(readmePath, nextReadme, 'utf8');
64
+ console.log(`[readme-sync] README atualizado com snapshot de ${sourceUrl}`);
65
+ };
66
+
67
+ syncReadmeSnapshot().catch((error) => {
68
+ console.error(`[readme-sync] Falha: ${error?.message || error}`);
69
+ process.exit(1);
70
+ });
71
+