@realvare/based 2.7.62 → 2.7.71

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.
Files changed (57) hide show
  1. package/README.MD +1062 -282
  2. package/WAProto/WAProto.proto +1073 -244
  3. package/WAProto/index.d.ts +16282 -8183
  4. package/WAProto/index.js +76605 -50628
  5. package/engine-requirements.js +10 -10
  6. package/lib/Defaults/baileys-version.json +1 -1
  7. package/lib/Defaults/index.d.ts +4 -2
  8. package/lib/Defaults/index.js +8 -6
  9. package/lib/Signal/Group/ciphertext-message.d.ts +1 -1
  10. package/lib/Signal/Group/ciphertext-message.js +1 -1
  11. package/lib/Signal/Group/sender-message-key.d.ts +1 -1
  12. package/lib/Signal/Group/sender-message-key.js +1 -1
  13. package/lib/Signal/libsignal.d.ts +1 -1
  14. package/lib/Socket/business.d.ts +1 -1
  15. package/lib/Socket/business.js +1 -1
  16. package/lib/Socket/chats.d.ts +4 -1
  17. package/lib/Socket/chats.js +213 -36
  18. package/lib/Socket/groups.js +87 -15
  19. package/lib/Socket/index.js +9 -0
  20. package/lib/Socket/messages-interactive.js +259 -0
  21. package/lib/Socket/messages-recv.js +1473 -1228
  22. package/lib/Socket/messages-send.js +437 -469
  23. package/lib/Socket/socket.js +143 -26
  24. package/lib/Socket/usync.js +57 -4
  25. package/lib/Store/make-in-memory-store.js +28 -15
  26. package/lib/Types/Auth.d.ts +4 -0
  27. package/lib/Types/Message.d.ts +316 -6
  28. package/lib/Types/Message.js +1 -1
  29. package/lib/Types/Socket.d.ts +2 -0
  30. package/lib/Utils/cache-manager.d.ts +16 -0
  31. package/lib/Utils/cache-manager.js +22 -5
  32. package/lib/Utils/chat-utils.js +17 -13
  33. package/lib/Utils/decode-wa-message.js +1 -11
  34. package/lib/Utils/event-buffer.js +103 -2
  35. package/lib/Utils/generics.js +5 -6
  36. package/lib/Utils/index.d.ts +5 -0
  37. package/lib/Utils/index.js +3 -0
  38. package/lib/Utils/jid-validation.d.ts +2 -0
  39. package/lib/Utils/jid-validation.js +43 -10
  40. package/lib/Utils/link-preview.js +38 -28
  41. package/lib/Utils/messages-media.d.ts +1 -1
  42. package/lib/Utils/messages-media.js +22 -53
  43. package/lib/Utils/messages.js +653 -65
  44. package/lib/Utils/performance-config.d.ts +2 -0
  45. package/lib/Utils/performance-config.js +16 -7
  46. package/lib/Utils/process-message.js +124 -12
  47. package/lib/Utils/rate-limiter.js +15 -20
  48. package/lib/WABinary/generic-utils.js +5 -1
  49. package/lib/WABinary/jid-utils.d.ts +1 -0
  50. package/lib/WABinary/jid-utils.js +265 -5
  51. package/lib/WAUSync/Protocols/USyncContactProtocol.js +75 -5
  52. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +59 -6
  53. package/lib/WAUSync/USyncQuery.js +64 -6
  54. package/lib/index.d.ts +1 -0
  55. package/lib/index.js +5 -4
  56. package/package.json +10 -15
  57. package/WAProto/index.ts.ts +0 -53473
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.makeEventBuffer = void 0;
7
7
  const events_1 = __importDefault(require("events"));
8
8
  const Types_1 = require("../Types");
9
+ const WABinary_1 = require("../WABinary");
9
10
  const generics_1 = require("./generics");
10
11
  const messages_1 = require("./messages");
11
12
  const process_message_1 = require("./process-message");
@@ -87,6 +88,7 @@ const makeEventBuffer = (logger) => {
87
88
  };
88
89
  },
89
90
  emit(event, evData) {
91
+ normalizeEventJids(evData);
90
92
  if (buffersInProgress && BUFFERABLE_EVENT_SET.has(event)) {
91
93
  append(data, historyCache, event, evData, logger);
92
94
  return true;
@@ -116,6 +118,62 @@ const makeEventBuffer = (logger) => {
116
118
  };
117
119
  };
118
120
  exports.makeEventBuffer = makeEventBuffer;
121
+ const LID_FIELD_DENYLIST = new Set([
122
+ 'remoteLid',
123
+ 'participantLid',
124
+ 'subjectOwnerLid',
125
+ 'ownerLid',
126
+ 'descOwnerLid',
127
+ 'lid',
128
+ ]);
129
+ const shouldNormalizeField = (key) => {
130
+ if (!key || typeof key !== 'string') {
131
+ return true;
132
+ }
133
+ if (LID_FIELD_DENYLIST.has(key)) {
134
+ return false;
135
+ }
136
+ if (key.endsWith('Lid')) {
137
+ return false;
138
+ }
139
+ return true;
140
+ };
141
+ const normalizeEventJids = (data) => {
142
+ try {
143
+ normalizeAny(data, undefined);
144
+ }
145
+ catch (_e) {
146
+ }
147
+ };
148
+ const normalizeAny = (value, key) => {
149
+ if (typeof value === 'string') {
150
+ if ((0, WABinary_1.isLid)(value) && shouldNormalizeField(key)) {
151
+ return (0, WABinary_1.lidToJid)(value) || value;
152
+ }
153
+ return value;
154
+ }
155
+ if (!value || typeof value !== 'object') {
156
+ return value;
157
+ }
158
+ if (Array.isArray(value)) {
159
+ for (let i = 0; i < value.length; i++) {
160
+ const v = value[i];
161
+ const nv = normalizeAny(v, undefined);
162
+ if (nv !== v) {
163
+ value[i] = nv;
164
+ }
165
+ }
166
+ return value;
167
+ }
168
+ for (const k of Object.keys(value)) {
169
+ const v = value[k];
170
+ const nv = normalizeAny(v, k);
171
+ if (nv !== v) {
172
+ value[k] = nv;
173
+ }
174
+ }
175
+ return value;
176
+ };
119
177
  const makeBufferData = () => {
120
178
  return {
121
179
  historySets: {
@@ -274,6 +332,10 @@ function append(data, historyCache, event, eventData, logger) {
274
332
  case 'contacts.update':
275
333
  const contactUpdates = eventData;
276
334
  for (const update of contactUpdates) {
335
+ // Skip if update is undefined or has no id
336
+ if (!update || !update.id) {
337
+ continue;
338
+ }
277
339
  const id = update.id;
278
340
  // merge into prior upsert
279
341
  const upsert = data.historySets.contacts[id] || data.contactUpserts[id];
@@ -358,7 +420,31 @@ function append(data, historyCache, event, eventData, logger) {
358
420
  }
359
421
  }
360
422
  else {
361
- // TODO: add support
423
+ // Handle delete all messages from a specific chat
424
+ const { jid } = deleteData;
425
+ // Remove all messages, updates, and reactions for this chat
426
+ for (const keyStr in data.messageUpserts) {
427
+ if (keyStr.includes(jid)) {
428
+ delete data.messageUpserts[keyStr];
429
+ }
430
+ }
431
+ for (const keyStr in data.messageUpdates) {
432
+ if (keyStr.includes(jid)) {
433
+ delete data.messageUpdates[keyStr];
434
+ }
435
+ }
436
+ for (const keyStr in data.messageReactions) {
437
+ if (keyStr.includes(jid)) {
438
+ delete data.messageReactions[keyStr];
439
+ }
440
+ }
441
+ for (const keyStr in data.messageDeletes) {
442
+ if (keyStr.includes(jid)) {
443
+ delete data.messageDeletes[keyStr];
444
+ }
445
+ }
446
+ // Store the delete all event
447
+ data.messageDeletes[`all:${jid}`] = { jid, all: true };
362
448
  }
363
449
  break;
364
450
  case 'messages.reaction':
@@ -394,6 +480,10 @@ function append(data, historyCache, event, eventData, logger) {
394
480
  case 'groups.update':
395
481
  const groupUpdates = eventData;
396
482
  for (const update of groupUpdates) {
483
+ // Skip if update is undefined or has no id
484
+ if (!update || !update.id) {
485
+ continue;
486
+ }
397
487
  const id = update.id;
398
488
  const groupUpdate = data.groupUpdates[id] || {};
399
489
  if (!data.groupUpdates[id]) {
@@ -477,7 +567,18 @@ function consolidateEvents(data) {
477
567
  }
478
568
  const messageDeleteList = Object.values(data.messageDeletes);
479
569
  if (messageDeleteList.length) {
480
- map['messages.delete'] = { keys: messageDeleteList };
570
+ // Separate individual message deletions from delete all events
571
+ const individualDeletes = messageDeleteList.filter(item => !('all' in item && item.all));
572
+ const deleteAllEvents = messageDeleteList.filter(item => ('all' in item && item.all));
573
+
574
+ if (individualDeletes.length) {
575
+ map['messages.delete'] = { keys: individualDeletes };
576
+ }
577
+
578
+ // Emit delete all events separately
579
+ for (const deleteAllEvent of deleteAllEvents) {
580
+ map[`messages.delete.all.${deleteAllEvent.jid}`] = { jid: deleteAllEvent.jid, all: true };
581
+ }
481
582
  }
482
583
  const messageReactionList = Object.values(data.messageReactions).flatMap(({ key, reactions }) => reactions.flatMap(reaction => ({ key, reaction })));
483
584
  if (messageReactionList.length) {
@@ -66,11 +66,10 @@ const PLATFORM_MAP = {
66
66
  'sunos': 'Solaris'
67
67
  };
68
68
  exports.Browsers = {
69
- ubuntu: (browser) => ['Ubuntu', browser, '22.04.4'],
70
- macOS: (browser) => ['Mac OS', browser, '14.4.1'],
71
- baileys: (browser) => ['Baileys', browser, '6.5.0'],
72
- windows: (browser) => ['Windows', browser, '10.0.22631'],
73
- /** The appropriate browser based on your OS & release */
69
+ ubuntu: (browser) => ['Ubuntu', browser, '24.04.1'],
70
+ macOS: (browser) => ['Mac OS', browser, '15.2.0'],
71
+ baileys: (browser) => ['Baileys', browser, '6.7.9'],
72
+ windows: (browser) => ['Windows', browser, '10.0.26100'],
74
73
  appropriate: (browser) => [PLATFORM_MAP[(0, os_1.platform)()] || 'Ubuntu', browser, (0, os_1.release)()]
75
74
  };
76
75
  const getPlatformId = (browser) => {
@@ -259,7 +258,7 @@ const printQRIfNecessaryListener = (ev, logger) => {
259
258
  };
260
259
  exports.printQRIfNecessaryListener = printQRIfNecessaryListener;
261
260
  const fetchLatestBaileysVersion = async (options = {}) => {
262
- const URL = 'https://github.com/realvare/baileyz/lib/Defaults/baileys-version.json';
261
+ const URL = 'https://github.com/realvare/based/lib/Defaults/baileys-version.json';
263
262
  try {
264
263
  const result = await axios_1.default.get(URL, {
265
264
  ...options,
@@ -15,3 +15,8 @@ export * from './use-multi-file-auth-state';
15
15
  export * from './link-preview';
16
16
  export * from './event-buffer';
17
17
  export * from './process-message';
18
+ export * from './performance-config';
19
+ export { isValidJid, normalizeJid } from './jid-validation';
20
+ export * from './newsletter-utils';
21
+ export * from './logger';
22
+ export * from './cache-manager';
@@ -32,4 +32,7 @@ __exportStar(require("./link-preview"), exports);
32
32
  __exportStar(require("./event-buffer"), exports);
33
33
  __exportStar(require("./process-message"), exports);
34
34
  __exportStar(require("./performance-config"), exports);
35
+ __exportStar(require("./jid-validation"), exports);
35
36
  __exportStar(require("./newsletter-utils"), exports);
37
+ __exportStar(require("./logger"), exports);
38
+ __exportStar(require("./cache-manager"), exports);
@@ -0,0 +1,2 @@
1
+ export declare const isValidJid: (jid: string) => boolean;
2
+ export declare const normalizeJid: (jid: string) => string;
@@ -37,8 +37,9 @@ const normalizeJid = (jid) => {
37
37
  if (!jid) return jid;
38
38
 
39
39
  // Convert LID to standard JID format
40
- if (jid.endsWith('@lid')) {
41
- return jid.replace('@lid', '@s.whatsapp.net');
40
+ if ((0, WABinary_1.isLid)(jid)) {
41
+ const converted = (0, WABinary_1.lidToJid)(jid);
42
+ return converted || jid;
42
43
  }
43
44
 
44
45
  // Ensure consistent format
@@ -55,25 +56,56 @@ exports.normalizeJid = normalizeJid;
55
56
  const getSenderLid = (msg) => {
56
57
  try {
57
58
  if (!msg || typeof msg !== 'object') {
58
- return { jid: undefined, lid: undefined, isValid: false };
59
+ return {
60
+ jid: '',
61
+ lid: '',
62
+ isValid: false,
63
+ user: '',
64
+ timestamp: Date.now(),
65
+ error: 'Invalid message object'
66
+ };
59
67
  }
60
68
 
61
69
  // Extract from different possible fields
62
70
  const jid = msg.key?.remoteJid || msg.remoteJid || msg.from;
63
71
  const lid = msg.key?.participant || msg.participant || msg.lid;
64
72
 
73
+ if (!jid || typeof jid !== 'string') {
74
+ return {
75
+ jid: '',
76
+ lid: typeof lid === 'string' ? lid : '',
77
+ isValid: false,
78
+ user: '',
79
+ timestamp: Date.now(),
80
+ error: 'Missing or invalid JID'
81
+ };
82
+ }
83
+
65
84
  // Validate and normalize
66
85
  const normalizedJid = normalizeJid(jid);
67
86
  const isValid = isValidJid(normalizedJid);
68
87
 
88
+ const decoded = (0, WABinary_1.jidDecode)(normalizedJid);
89
+ const user = decoded?.user || normalizedJid.split('@')[0] || '';
90
+
69
91
  return {
70
92
  jid: normalizedJid,
71
- lid: lid,
72
- isValid: isValid
93
+ lid: typeof lid === 'string' ? lid : '',
94
+ isValid: isValid,
95
+ user,
96
+ timestamp: Date.now(),
97
+ ...(isValid ? {} : { error: 'Invalid JID format' })
73
98
  };
74
99
  } catch (error) {
75
100
  performance_config_1.Logger.error('Error in getSenderLid:', error);
76
- return { jid: undefined, lid: undefined, isValid: false };
101
+ return {
102
+ jid: '',
103
+ lid: '',
104
+ isValid: false,
105
+ user: '',
106
+ timestamp: Date.now(),
107
+ error: 'Error extracting sender information'
108
+ };
77
109
  }
78
110
  };
79
111
 
@@ -88,9 +120,10 @@ const toJid = (lid) => {
88
120
  if (!lid) return lid;
89
121
 
90
122
  try {
91
- // Simple conversion from LID to JID format
92
- if (lid.endsWith('@lid')) {
93
- return lid.replace('@lid', '@s.whatsapp.net');
123
+ // Convert LID to JID format
124
+ if ((0, WABinary_1.isLid)(lid)) {
125
+ const converted = (0, WABinary_1.lidToJid)(lid);
126
+ return converted || lid;
94
127
  }
95
128
 
96
129
  // If already in JID format, return as-is
@@ -142,7 +175,7 @@ const validateJid = (jid) => {
142
175
  return { isValid: false, error: `Invalid domain: ${domain}` };
143
176
  }
144
177
 
145
- return { isValid: true, error: null };
178
+ return { isValid: true };
146
179
 
147
180
  } catch (error) {
148
181
  performance_config_1.Logger.error('Error in validateJid:', error);
@@ -70,46 +70,56 @@ const getUrlInfo = async (text, opts = {
70
70
  }) => {
71
71
  var _a;
72
72
  try {
73
- // retries
74
- const retries = 0;
75
- const maxRetry = 5;
76
- const { getLinkPreview } = await Promise.resolve().then(() => __importStar(require('link-preview-js')));
73
+ const { unfurl } = await Promise.resolve().then(() => __importStar(require('unfurl.js')));
77
74
  let previewLink = text;
78
75
  if (!text.startsWith('https://') && !text.startsWith('http://')) {
79
76
  previewLink = 'https://' + previewLink;
80
77
  }
81
- const info = await getLinkPreview(previewLink, {
82
- ...opts.fetchOpts,
83
- followRedirects: 'follow',
84
- handleRedirects: (baseURL, forwardedURL) => {
85
- const urlObj = new URL(baseURL);
86
- const forwardedURLObj = new URL(forwardedURL);
87
- if (retries >= maxRetry) {
88
- return false;
78
+ const requestHeaders = (() => {
79
+ const headers = opts.fetchOpts?.headers;
80
+ if (!headers || typeof headers !== 'object') {
81
+ return undefined;
82
+ }
83
+ const out = {};
84
+ for (const [key, value] of Object.entries(headers)) {
85
+ if (typeof value === 'undefined' || value === null) {
86
+ continue;
89
87
  }
90
- if (forwardedURLObj.hostname === urlObj.hostname
91
- || forwardedURLObj.hostname === 'www.' + urlObj.hostname
92
- || 'www.' + forwardedURLObj.hostname === urlObj.hostname) {
93
- retries + 1;
94
- return true;
88
+ if (Array.isArray(value)) {
89
+ out[key] = value.map(v => v.toString()).join(', ');
95
90
  }
96
91
  else {
97
- return false;
92
+ out[key] = value.toString();
98
93
  }
99
- },
100
- headers: opts.fetchOpts
94
+ }
95
+ return out;
96
+ })();
97
+ const info = await unfurl(previewLink, {
98
+ timeout: opts.fetchOpts?.timeout,
99
+ headers: requestHeaders,
100
+ follow: 5
101
101
  });
102
- if (info && 'title' in info && info.title) {
103
- const [image] = info.images;
104
- opts.logger?.debug({ url: previewLink, title: info.title, imageCount: info.images.length }, 'Fetched link preview info');
102
+ const title = info?.title || info?.open_graph?.title || info?.twitter_card?.title;
103
+ if (title) {
104
+ const images = [];
105
+ if (info?.open_graph?.images?.length) {
106
+ images.push(...info.open_graph.images.map(img => img === null || img === void 0 ? void 0 : img.url).filter(Boolean));
107
+ }
108
+ if (info?.twitter_card?.images?.length) {
109
+ images.push(...info.twitter_card.images.map(img => img === null || img === void 0 ? void 0 : img.url).filter(Boolean));
110
+ }
111
+ const [image] = images;
112
+ const description = info?.description || info?.open_graph?.description || info?.twitter_card?.description;
113
+ const canonicalUrl = info?.canonical_url || info?.open_graph?.url || previewLink;
114
+ opts.logger?.debug({ url: previewLink, title, imageCount: images.length }, 'Fetched link preview info');
105
115
  const urlInfo = {
106
- 'canonical-url': info.url,
116
+ 'canonical-url': canonicalUrl,
107
117
  'matched-text': text,
108
- title: info.title,
109
- description: info.description,
118
+ title,
119
+ description,
110
120
  originalThumbnailUrl: image
111
121
  };
112
- if (opts.uploadImage) {
122
+ if (opts.uploadImage && image) {
113
123
  const { imageMessage } = await (0, messages_1.prepareWAMessageMedia)({ image: { url: image } }, {
114
124
  upload: opts.uploadImage,
115
125
  mediaTypeOverride: 'thumbnail-link',
@@ -134,7 +144,7 @@ const getUrlInfo = async (text, opts = {
134
144
  }
135
145
  }
136
146
  catch (error) {
137
- if (!error.message.includes('receive a valid')) {
147
+ if (!error.message.includes('receive a valid') && !error.message.includes('Invalid URL')) {
138
148
  throw error;
139
149
  }
140
150
  }
@@ -16,7 +16,7 @@ export declare function vid2jpg(videoUrl: string): Promise<string>;
16
16
  * Modified for customization and improvements
17
17
  */
18
18
  export declare const extractVideoThumb: (videoPath: string) => Promise<Buffer<ArrayBufferLike>>;
19
- export declare const extractImageThumb: (bufferOrFilePath: Readable | Buffer | string, width?: number) => Promise<{
19
+ export declare const extractImageThumb: (bufferOrFilePath: Readable | Buffer | string, width?: number, quality?: number) => Promise<{
20
20
  buffer: Buffer<ArrayBufferLike>;
21
21
  original: {
22
22
  width: number;
@@ -63,24 +63,11 @@ const crypto_1 = require("./crypto");
63
63
  const generics_1 = require("./generics");
64
64
  const getTmpFilesDirectory = () => (0, os_1.tmpdir)();
65
65
  const getImageProcessingLibrary = async () => {
66
- const [_jimp, sharp] = await Promise.all([
67
- (async () => {
68
- const jimp = await (Promise.resolve().then(() => __importStar(require('jimp'))).catch(() => { }));
69
- return jimp;
70
- })(),
71
- (async () => {
72
- const sharp = await (Promise.resolve().then(() => __importStar(require('sharp'))).catch(() => { }));
73
- return sharp;
74
- })()
75
- ]);
76
- if (sharp) {
77
- return { sharp };
78
- }
79
- const jimp = (_jimp === null || _jimp === void 0 ? void 0 : _jimp.default) || _jimp;
66
+ const jimp = await (Promise.resolve().then(() => __importStar(require('jimp'))).catch(() => { }));
80
67
  if (jimp) {
81
- return { jimp };
68
+ return { jimp: jimp.default || jimp };
82
69
  }
83
- throw new boom_1.Boom('No image processing library available');
70
+ throw new boom_1.Boom('Jimp image processing library not available');
84
71
  };
85
72
  const hkdfInfoKey = (type) => {
86
73
  const hkdfInfo = Defaults_1.MEDIA_HKDF_KEY_MAPPING[type];
@@ -273,46 +260,25 @@ const extractVideoThumb = async (videoPath, time = '00:00:00', size = { width: 2
273
260
  });
274
261
  };
275
262
  exports.extractVideoThumb = extractVideoThumb;
276
- const extractImageThumb = async (bufferOrFilePath, width = 32) => {
277
- var _a, _b;
263
+ const extractImageThumb = async (bufferOrFilePath, width = 32, quality = 50) => {
278
264
  if (bufferOrFilePath instanceof stream_1.Readable) {
279
265
  bufferOrFilePath = await (0, exports.toBuffer)(bufferOrFilePath);
280
266
  }
281
267
  const lib = await getImageProcessingLibrary();
282
- if ('sharp' in lib && typeof ((_a = lib.sharp) === null || _a === void 0 ? void 0 : _a.default) === 'function') {
283
- const img = lib.sharp.default(bufferOrFilePath);
284
- const dimensions = await img.metadata();
285
- const buffer = await img
286
- .resize(width)
287
- .jpeg({ quality: 50 })
288
- .toBuffer();
289
- return {
290
- buffer,
291
- original: {
292
- width: dimensions.width,
293
- height: dimensions.height,
294
- },
295
- };
296
- }
297
- else if ('jimp' in lib && typeof ((_b = lib.jimp) === null || _b === void 0 ? void 0 : _b.read) === 'function') {
298
- const { read, MIME_JPEG, RESIZE_BILINEAR, AUTO } = lib.jimp;
299
- const jimp = await read(bufferOrFilePath);
300
- const dimensions = {
301
- width: jimp.getWidth(),
302
- height: jimp.getHeight()
303
- };
304
- const buffer = await jimp
305
- .quality(50)
306
- .resize(width, AUTO, RESIZE_BILINEAR)
307
- .getBufferAsync(MIME_JPEG);
308
- return {
309
- buffer,
310
- original: dimensions
311
- };
312
- }
313
- else {
314
- throw new boom_1.Boom('No image processing library available');
315
- }
268
+ const { read, MIME_JPEG, RESIZE_BILINEAR, AUTO } = lib.jimp;
269
+ const jimp = await read(bufferOrFilePath);
270
+ const dimensions = {
271
+ width: jimp.getWidth(),
272
+ height: jimp.getHeight()
273
+ };
274
+ const buffer = await jimp
275
+ .quality(quality)
276
+ .resize(width, AUTO, RESIZE_BILINEAR)
277
+ .getBufferAsync(MIME_JPEG);
278
+ return {
279
+ buffer,
280
+ original: dimensions
281
+ };
316
282
  };
317
283
  exports.extractImageThumb = extractImageThumb;
318
284
  const encodeBase64EncodedStringForUpload = (b64) => (encodeURIComponent(b64
@@ -424,6 +390,9 @@ const getStream = async (item, opts) => {
424
390
  if ('stream' in item) {
425
391
  return { stream: item.stream, type: 'readable' };
426
392
  }
393
+ if (!item || !item.url) {
394
+ throw new Error('Invalid media item: missing url property');
395
+ }
427
396
  if (item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) {
428
397
  return { stream: await (0, exports.getHttpStream)(item.url, opts), type: 'remote' };
429
398
  }
@@ -876,4 +845,4 @@ const MEDIA_RETRY_STATUS_MAP = {
876
845
  };
877
846
  function __importStar(arg0) {
878
847
  throw new Error('Function not implemented.');
879
- }
848
+ }