aunubaileys 1.0.42 → 1.0.44

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
@@ -64,6 +64,14 @@ Everything else is pure upstream. When upstream moves, we rebase the patch layer
64
64
 
65
65
 
66
66
 
67
+ ### 🆕 What's new in 1.0.44 / Baru di 1.0.44
68
+
69
+ - 🖼️ **A third image backend: `@napi-rs/image`** in `getImageProcessingLibrary`, between sharp and jimp (priority: sharp → @napi-rs/image → jimp). `extractImageThumb` and `generateProfilePicture` gain a napi branch (Transformer: metadata + resize + quality-50 JPEG, matching the existing branches), and the package now declares `@napi-rs/image ^1.12.0` as an optional peer dependency. Consumers without sharp get a fast native path instead of falling back to jimp. Follows @itsliaaa/baileys.
70
+
71
+ ### 🆕 What's new in 1.0.43 / Baru di 1.0.43
72
+
73
+ - 🎬 **Video thumbnails now invoke FFmpeg via `spawn` with an argument array** instead of a shell-executed command string (`exec`). `extractVideoThumb` builds the invocation as data rather than shell text, so a file path can no longer smuggle shell commands into it; the function signature and behaviour are unchanged (file output, same caller in `generateThumbnail`). The pattern follows @itsliaaa/baileys; their pipe-to-buffer redesign was **not** adopted because it would change this function's public behaviour.
74
+
67
75
  ### 🆕 What's new in 1.0.42 / Baru di 1.0.42
68
76
 
69
77
  - 🧑‍💻 **Full rich responses: highlighted code blocks + tables** — completing the simple `aiRich` branch that has existed since the 1.0.2–1.0.4 era. Send `{ code, language }`, `{ table, title }`, `{ links }`, or prebuilt `{ richResponse }` submessages and the message routes to the new rich response builder (`lib/Utils/rich-message-utils.js`, exported: `tokenizeCode`, `prepareRichResponseMessage`, `toUnified`): code is tokenized per language (keyword tables for 12 languages + a lexer) into highlight blocks, tables become header + body rows, and the `unifiedResponse` rendering payload is assembled automatically. Two adaptations from the source (@itsliaaa/baileys), recorded plainly: **(1)** the source's donation-link fallbacks are removed — a link without a `url` is skipped and no third-party label/URL is ever injected; **(2)** the 6.7.24 proto has **no** `botForwardedMessage` field and no `BotMetadata.verificationMetadata`/`botResponseId`, so on this base the rich response is sent as the Message's own `richResponseMessage` field (the same shape as the existing `aiRich` branch) and the v7 bot-proof apparatus is not fabricated; the enums follow this proto's nested layout.
@@ -1,6 +1,6 @@
1
1
  import { Boom } from '@hapi/boom';
2
2
  import axios, {} from 'axios';
3
- import { exec } from 'child_process';
3
+ import { spawn } from 'child_process';
4
4
  import * as Crypto from 'crypto';
5
5
  import { once } from 'events';
6
6
  import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs';
@@ -16,10 +16,14 @@ import { generateMessageIDV2 } from './generics.js';
16
16
  const getTmpFilesDirectory = () => tmpdir();
17
17
  export const getImageProcessingLibrary = async () => {
18
18
  //@ts-ignore
19
- const [jimp, sharp] = await Promise.all([import('jimp').catch(() => { }), import('sharp').catch(() => { })]);
19
+ const [jimp, sharp, image] = await Promise.all([import('jimp').catch(() => { }), import('sharp').catch(() => { }), import('@napi-rs/image').catch(() => { })]);
20
20
  if (sharp) {
21
21
  return { sharp };
22
22
  }
23
+ // AunuBaileys: backend @napi-rs/image (dari @itsliaaa/baileys) — di atas jimp
24
+ if (image) {
25
+ return { image };
26
+ }
23
27
  if (jimp) {
24
28
  return { jimp };
25
29
  }
@@ -85,13 +89,26 @@ export async function getMediaKeys(buffer, mediaType) {
85
89
  }
86
90
  /** Extracts video thumb using FFMPEG */
87
91
  const extractVideoThumb = async (path, destPath, time, size) => new Promise((resolve, reject) => {
88
- const cmd = `ffmpeg -ss ${time} -i ${path} -y -vf scale=${size.width}:-1 -vframes 1 -f image2 ${destPath}`;
89
- exec(cmd, err => {
90
- if (err) {
91
- reject(err);
92
+ // AunuBaileys: spawn dengan array argumen, tanpa shell (dari @itsliaaa/baileys) —
93
+ // path/waktu/ukuran tidak lagi diinterpolasi ke string perintah shell
94
+ const ffmpeg = spawn('ffmpeg', [
95
+ '-ss', String(time),
96
+ '-i', path,
97
+ '-y',
98
+ '-vf', `scale=${size.width}:-1`,
99
+ '-vframes', '1',
100
+ '-f', 'image2',
101
+ destPath
102
+ ], { stdio: ['ignore', 'ignore', 'pipe'] });
103
+ const stderrChunks = [];
104
+ ffmpeg.stderr.on('data', (chunk) => stderrChunks.push(chunk));
105
+ ffmpeg.on('error', reject);
106
+ ffmpeg.on('close', (code) => {
107
+ if (code === 0) {
108
+ resolve();
92
109
  }
93
110
  else {
94
- resolve();
111
+ reject(new Error(`ffmpeg exited with code ${code}: ${Buffer.concat(stderrChunks).toString('utf8').trim()}`));
95
112
  }
96
113
  });
97
114
  });
@@ -114,6 +131,22 @@ export const extractImageThumb = async (bufferOrFilePath, width = 32) => {
114
131
  }
115
132
  };
116
133
  }
134
+ else if ('image' in lib && lib.image?.Transformer) {
135
+ // AunuBaileys: backend @napi-rs/image
136
+ if (!Buffer.isBuffer(bufferOrFilePath)) {
137
+ bufferOrFilePath = await fs.readFile(bufferOrFilePath);
138
+ }
139
+ const img = new lib.image.Transformer(bufferOrFilePath);
140
+ const dimensions = await img.metadata();
141
+ const buffer = await img.resize(width, undefined, 0).jpeg(50);
142
+ return {
143
+ buffer,
144
+ original: {
145
+ width: dimensions.width,
146
+ height: dimensions.height
147
+ }
148
+ };
149
+ }
117
150
  else if ('jimp' in lib && (typeof lib.jimp?.Jimp === 'object' || typeof lib.jimp?.Jimp === 'function')) {
118
151
  // AunuBaileys: jimp v1 mengekspos Jimp sebagai class (function), bukan object
119
152
  const jimp = await lib.jimp.Jimp.read(bufferOrFilePath);
@@ -157,6 +190,10 @@ export const generateProfilePicture = async (mediaUpload, dimensions) => {
157
190
  })
158
191
  .toBuffer();
159
192
  }
193
+ else if ('image' in lib && lib.image?.Transformer) {
194
+ // AunuBaileys: backend @napi-rs/image
195
+ img = new lib.image.Transformer(buffer).resize(w, h, 0).jpeg(50);
196
+ }
160
197
  else if ('jimp' in lib && (typeof lib.jimp?.Jimp === 'object' || typeof lib.jimp?.Jimp === 'function')) {
161
198
  // AunuBaileys: jimp v1 mengekspos Jimp sebagai class (function), bukan object
162
199
  const jimp = await lib.jimp.Jimp.read(buffer);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "aunubaileys",
3
3
  "type": "module",
4
- "version": "1.0.42",
4
+ "version": "1.0.44",
5
5
  "description": "AunuBaileys \u2014 a WhatsApp Web API for bots that never sleep. Full upstream power with the beloved in-memory store restored and pairing that just works. Forged by AunuCore.",
6
6
  "keywords": [
7
7
  "whatsapp",
@@ -83,7 +83,8 @@
83
83
  "audio-decode": "^2.1.3",
84
84
  "jimp": "^1.6.0",
85
85
  "link-preview-js": "^3.0.0",
86
- "sharp": "*"
86
+ "sharp": "*",
87
+ "@napi-rs/image": "^1.12.0"
87
88
  },
88
89
  "peerDependenciesMeta": {
89
90
  "audio-decode": {