@oxidezap/baileyrs 0.2.5 → 0.2.6
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 +17 -2
- package/lib/Socket/events.js +48 -8
- package/lib/Socket/index.js +5 -0
- package/lib/Socket/unsupported-config.d.ts +82 -0
- package/lib/Socket/unsupported-config.js +162 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -226,8 +226,23 @@ A few behaviors that differ from upstream — almost always to your advantage:
|
|
|
226
226
|
[When `connecting` lasts minutes](#when-connecting-lasts-minutes): a
|
|
227
227
|
readiness timeout written for upstream's `connecting` misreads this one.
|
|
228
228
|
- **No `getMessage` / `cachedGroupMetadata` polyfill required.** The Rust
|
|
229
|
-
side caches group metadata and message keys natively
|
|
230
|
-
|
|
229
|
+
side caches group metadata and message keys natively, and nothing here calls
|
|
230
|
+
either hook: a `cachedGroupMetadata` carried over from upstream never runs,
|
|
231
|
+
and neither does a `getMessage`. Passing them is harmless — the whole
|
|
232
|
+
`SocketConfig` shape is accepted so a migration needs no edits — but they are
|
|
233
|
+
not overrides, so delete them rather than maintain them. Every socket warns once
|
|
234
|
+
at construction naming any option in that group it received; that list is the
|
|
235
|
+
authority — the type system requires each `SocketConfig` member to be
|
|
236
|
+
classified, so it cannot fall behind — and it also covers `keepAliveIntervalMs`,
|
|
237
|
+
`markOnlineOnConnect`, `maxMsgRetryCount`, `msgRetryCounterCache`,
|
|
238
|
+
`retryRequestDelayMs`, `fireInitQueries`, `syncFullHistory`,
|
|
239
|
+
`shouldSyncHistoryMessage`, `generateHighQualityLinkPreview`,
|
|
240
|
+
`linkPreviewImageThumbnailWidth`, `enableAutoSessionRecreation`,
|
|
241
|
+
`enableRecentMessageCache`, `appStateMacVerification`,
|
|
242
|
+
`patchMessageBeforeSending`, `customUploadHosts`, `countryCode`,
|
|
243
|
+
`connectTimeoutMs`, `qrTimeout`, `printQRInTerminal`, `ignoreOfflineMessages`,
|
|
244
|
+
`downloadHistory`, `agent`, `fetchAgent`, `mobile`, `mediaCache`,
|
|
245
|
+
`userDevicesCache`, `callOfferCache` and `placeholderResendCache`.
|
|
231
246
|
- **`Boom` ships in the box.** baileyrs exports its own
|
|
232
247
|
`@hapi/boom`-compatible `Boom`, so the existing
|
|
233
248
|
`(err as Boom).output.statusCode` pattern works unchanged. If your
|
package/lib/Socket/events.js
CHANGED
|
@@ -161,6 +161,12 @@ const emitClose = ({ ctx, callbacks, historySync }, reason, statusCode, data) =>
|
|
|
161
161
|
* state upstream itself uses while a connection is being (re)established, so
|
|
162
162
|
* consumers read this as `open → connecting → open` and stay out of the way.
|
|
163
163
|
*/
|
|
164
|
+
/**
|
|
165
|
+
* `<stream:error code="429">` — the server rate limiting this session. The one
|
|
166
|
+
* stream error the engine forwards that is not a preserved connection; see the
|
|
167
|
+
* `streamError` dispatcher.
|
|
168
|
+
*/
|
|
169
|
+
const RATE_LIMITED_STREAM_ERROR = '429';
|
|
164
170
|
const emitRetrying = (ctx) => ctx.ev.emit('connection.update', {
|
|
165
171
|
connection: 'connecting',
|
|
166
172
|
// Same shape upstream's own `connecting` always carries. Without the
|
|
@@ -298,15 +304,49 @@ const DISPATCHERS = {
|
|
|
298
304
|
const status = mapConnectFailureToDisconnect(evt.reason);
|
|
299
305
|
emitClose(dispatchCtx, evt.message ?? 'Connection failure', status);
|
|
300
306
|
},
|
|
301
|
-
// NOT a close
|
|
302
|
-
// `<stream:error>` branch — an unknown code, an `<ack/>` it still owes the
|
|
303
|
-
// server, or `<xml-not-well-formed>` — and it keeps or deliberately recycles
|
|
304
|
-
// the connection in every one of those. This used to report
|
|
307
|
+
// NOT a close, in either branch below. This used to report
|
|
305
308
|
// `DisconnectReason.badSession`, the code bots use to wipe credentials and
|
|
306
|
-
// re-pair, so a routine stream recycle could destroy a working session.
|
|
307
|
-
//
|
|
308
|
-
//
|
|
309
|
-
|
|
309
|
+
// re-pair, so a routine stream recycle could destroy a working session.
|
|
310
|
+
//
|
|
311
|
+
// Two kinds of event arrive here, and they are not interchangeable:
|
|
312
|
+
//
|
|
313
|
+
// - the engine's catch-all `<stream:error>` branch — an unknown code, an
|
|
314
|
+
// `<ack/>` it still owes the server, or `<xml-not-well-formed>` — where
|
|
315
|
+
// it keeps or deliberately recycles the connection. Nothing to publish:
|
|
316
|
+
// the recycle reaches the consumer as a `disconnected` of its own.
|
|
317
|
+
//
|
|
318
|
+
// - `429`, which is a *rejected session*, not a preserved connection.
|
|
319
|
+
// `client/node_io.rs` clears `is_logged_in`, adds five rungs to the
|
|
320
|
+
// Fibonacci backoff and suppresses the reset that would undo them, then
|
|
321
|
+
// dispatches this event so an embedder can act on it — the core's comment
|
|
322
|
+
// says as much ("An embedder has none, so report the rate limit through
|
|
323
|
+
// `StreamError`"). It falls through the handler's `should_disconnect`
|
|
324
|
+
// block, so the transport is still up at this instant and the socket
|
|
325
|
+
// would keep reporting `open` until the server ends the stream.
|
|
326
|
+
//
|
|
327
|
+
// `connecting` for 429 is not a new state: it is the one this library
|
|
328
|
+
// already defines for "the engine is restoring the connection", and the one
|
|
329
|
+
// the next server frame produces anyway. Publishing it here just moves it to
|
|
330
|
+
// the moment the engine already knows, instead of the round trip that
|
|
331
|
+
// confirms it. The coded errors that *are* terminal (401/409/515/516) never
|
|
332
|
+
// reach this dispatcher; they emit `loggedOut` / `streamReplaced` instead.
|
|
333
|
+
streamError: (evt, { ctx, callbacks }) => {
|
|
334
|
+
if (evt.code === RATE_LIMITED_STREAM_ERROR) {
|
|
335
|
+
ctx.logger.warn({ code: evt.code }, 'stream error: the server rate limited this session; the engine will retry with an extended backoff');
|
|
336
|
+
// `connecting` promises the engine is restoring this connection.
|
|
337
|
+
// Under `setAutoReconnect(false)` it will not — the run loop breaks
|
|
338
|
+
// on the pass after the disconnect that follows — so publishing it
|
|
339
|
+
// would leave a retrying state nobody resolves. Silence, not a
|
|
340
|
+
// close: the engine still dispatches `Disconnected` when the server
|
|
341
|
+
// ends the stream, and that dispatcher already turns it into a
|
|
342
|
+
// terminal close under this flag. Closing here too would publish two
|
|
343
|
+
// for one failure, the second after teardown had already run.
|
|
344
|
+
if (callbacks?.isAutoReconnectEnabled?.() !== false)
|
|
345
|
+
emitRetrying(ctx);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
ctx.logger.warn({ code: evt.code }, 'stream error; the connection is preserved');
|
|
349
|
+
},
|
|
310
350
|
streamReplaced: (_, dispatchCtx) => emitClose(dispatchCtx, 'Connection replaced', DisconnectReason.connectionReplaced),
|
|
311
351
|
// Carries the wire code (405), not `DisconnectReason.badSession`. Upstream
|
|
312
352
|
// does the same for stream errors — `+node.attrs.code` first, `badSession`
|
package/lib/Socket/index.js
CHANGED
|
@@ -28,6 +28,7 @@ import { makeChatActionMethods } from './chat-actions.js';
|
|
|
28
28
|
import { makeContactMethods } from './contacts.js';
|
|
29
29
|
import { makeCommunityMethods } from './communities.js';
|
|
30
30
|
import { makeBridgeClientOwner } from './bridge-client-owner.js';
|
|
31
|
+
import { warnUnsupportedConfig } from './unsupported-config.js';
|
|
31
32
|
import { wrapBridgeClient } from './bridge-error-boundary.js';
|
|
32
33
|
import { makeTerminalCloseReporter } from './terminal-close-reporter.js';
|
|
33
34
|
import { makeEventHandlers } from './events.js';
|
|
@@ -74,6 +75,10 @@ const browserToPlatformType = (browser) => {
|
|
|
74
75
|
const makeWASocket = (config) => {
|
|
75
76
|
const fullConfig = { ...DEFAULT_CONNECTION_CONFIG, ...config };
|
|
76
77
|
const { logger } = fullConfig;
|
|
78
|
+
// Against `config`, not `fullConfig`: only what this caller actually passed
|
|
79
|
+
// is worth naming. Merging the defaults first would report every unsupported
|
|
80
|
+
// option on every socket, including the ones nobody chose.
|
|
81
|
+
warnUnsupportedConfig(config, logger);
|
|
77
82
|
const auth = normalizeSocketAuthenticationState(fullConfig.auth);
|
|
78
83
|
const getExposedKeys = makeLazyTransactionKeyStore(auth.keys, logger, fullConfig.transactionOpts);
|
|
79
84
|
const ev = makeEventBuffer(logger);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options `SocketConfig` accepts that nothing on this side reads.
|
|
3
|
+
*
|
|
4
|
+
* Being a drop-in replacement means accepting the whole upstream shape, so none
|
|
5
|
+
* of these throws and none of them ever will. But the Rust engine owns
|
|
6
|
+
* keepalive, retry, history sync, link previews and its own message and group
|
|
7
|
+
* caches, so for these keys there is no reader to hand the value to — and a
|
|
8
|
+
* consumer that passes one is describing behaviour it will not get.
|
|
9
|
+
*
|
|
10
|
+
* That gap is expensive precisely because it is quiet. Two shapes found in a
|
|
11
|
+
* production bot, both dead for months, both looking deliberate:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* cachedGroupMetadata: async jid => myOwnCache.get(jid) // never called
|
|
15
|
+
* getMessage: async key => myStore.get(key.id) // never called
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* `enableRecentMessageCache: true` is worse: it names a cache the consumer
|
|
19
|
+
* believes it turned on.
|
|
20
|
+
*
|
|
21
|
+
* The list is deliberately hand-maintained rather than derived. Deriving it
|
|
22
|
+
* (scanning for reads) would quietly go wrong in both directions — an option
|
|
23
|
+
* read through a computed key would look unsupported, and one only mentioned in
|
|
24
|
+
* a type would look supported. A test anchors every entry to `SocketConfig`, so
|
|
25
|
+
* an option that starts being read here fails the audit for whoever removes it.
|
|
26
|
+
*/
|
|
27
|
+
export declare const UNSUPPORTED_CONFIG_KEYS: readonly ["keepAliveIntervalMs", "maxMsgRetryCount", "msgRetryCounterCache", "retryRequestDelayMs", "fireInitQueries", "markOnlineOnConnect", "syncFullHistory", "shouldSyncHistoryMessage", "generateHighQualityLinkPreview", "linkPreviewImageThumbnailWidth", "enableAutoSessionRecreation", "enableRecentMessageCache", "appStateMacVerification", "cachedGroupMetadata", "getMessage", "patchMessageBeforeSending", "customUploadHosts", "countryCode", "connectTimeoutMs", "qrTimeout", "agent", "fetchAgent", "mobile", "printQRInTerminal", "ignoreOfflineMessages", "downloadHistory", "mediaCache", "userDevicesCache", "callOfferCache", "placeholderResendCache"];
|
|
28
|
+
/**
|
|
29
|
+
* The other half: options something on this side actually reads.
|
|
30
|
+
*
|
|
31
|
+
* Only here to make the classification total. Nothing consumes this list at
|
|
32
|
+
* runtime; its job is to let the assertion below fail the build when a new
|
|
33
|
+
* member of `SocketConfig` belongs to neither list — which is exactly how the
|
|
34
|
+
* first version of the catalog shipped twelve keys short.
|
|
35
|
+
*/
|
|
36
|
+
export declare const READ_CONFIG_KEYS: readonly ["waWebSocketUrl", "options", "logger", "version", "browser", "pushName", "auth", "cache", "deviceProps", "wantedPreKeyCount", "emitOwnEvents", "shouldIgnoreJid", "defaultQueryTimeoutMs", "transactionOpts", "makeSignalRepository"];
|
|
37
|
+
/**
|
|
38
|
+
* Which unsupported options this caller actually passed.
|
|
39
|
+
*
|
|
40
|
+
* Only own, non-`undefined` properties count: spreading a partial config
|
|
41
|
+
* commonly leaves `{ getMessage: undefined }` behind, and warning about a key
|
|
42
|
+
* whose value is absent would be noise about nothing.
|
|
43
|
+
*
|
|
44
|
+
* @param config the object handed to `makeWASocket`, before defaults are merged
|
|
45
|
+
* @returns the offending keys, in catalog order (stable across consumers)
|
|
46
|
+
*/
|
|
47
|
+
export declare const unsupportedConfigKeys: (config: object) => string[];
|
|
48
|
+
/**
|
|
49
|
+
* Say once per socket, at construction, which unsupported options this caller
|
|
50
|
+
* passed.
|
|
51
|
+
*
|
|
52
|
+
* Per socket, not per process: a replacement socket built after a terminal
|
|
53
|
+
* close carries its own configuration decision, and `Socket/internals.ts`
|
|
54
|
+
* already warns "once per socket rather than per call" for its own no-ops.
|
|
55
|
+
*
|
|
56
|
+
* `warn` and not `error`: nothing is broken.
|
|
57
|
+
*
|
|
58
|
+
* A socket must never fail to build over a diagnostic. That guarantee is
|
|
59
|
+
* unconditional, so the guard covers the whole of it — the reading as well as
|
|
60
|
+
* the writing:
|
|
61
|
+
*
|
|
62
|
+
* - the optional chaining, for a logger with no `warn` (a minimal one in a
|
|
63
|
+
* test, say);
|
|
64
|
+
* - the `try` around the logging call, for a logger whose `warn` throws — a
|
|
65
|
+
* synchronous transport failing there would take down `makeWASocket` itself;
|
|
66
|
+
* - the same `try` around the inspection, because telling a passed option from
|
|
67
|
+
* a spread leftover means reading `config[key]`, and reading fires getters. A
|
|
68
|
+
* config with a throwing accessor, or a proxy with a throwing trap, would
|
|
69
|
+
* otherwise fail construction from outside the logging call.
|
|
70
|
+
*
|
|
71
|
+
* All of it only ever bites consumers who passed an inert option, which is the
|
|
72
|
+
* one group this warning exists to help. The failure is swallowed rather than
|
|
73
|
+
* reported, because the only thing left to report it with is the logger that
|
|
74
|
+
* just threw.
|
|
75
|
+
*
|
|
76
|
+
* @param config the object handed to `makeWASocket`, before defaults are merged
|
|
77
|
+
* @param logger the socket's logger
|
|
78
|
+
*/
|
|
79
|
+
export declare const warnUnsupportedConfig: (config: object, logger: {
|
|
80
|
+
warn?: (payload: object, message: string) => void;
|
|
81
|
+
}) => void;
|
|
82
|
+
//# sourceMappingURL=unsupported-config.d.ts.map
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options `SocketConfig` accepts that nothing on this side reads.
|
|
3
|
+
*
|
|
4
|
+
* Being a drop-in replacement means accepting the whole upstream shape, so none
|
|
5
|
+
* of these throws and none of them ever will. But the Rust engine owns
|
|
6
|
+
* keepalive, retry, history sync, link previews and its own message and group
|
|
7
|
+
* caches, so for these keys there is no reader to hand the value to — and a
|
|
8
|
+
* consumer that passes one is describing behaviour it will not get.
|
|
9
|
+
*
|
|
10
|
+
* That gap is expensive precisely because it is quiet. Two shapes found in a
|
|
11
|
+
* production bot, both dead for months, both looking deliberate:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* cachedGroupMetadata: async jid => myOwnCache.get(jid) // never called
|
|
15
|
+
* getMessage: async key => myStore.get(key.id) // never called
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* `enableRecentMessageCache: true` is worse: it names a cache the consumer
|
|
19
|
+
* believes it turned on.
|
|
20
|
+
*
|
|
21
|
+
* The list is deliberately hand-maintained rather than derived. Deriving it
|
|
22
|
+
* (scanning for reads) would quietly go wrong in both directions — an option
|
|
23
|
+
* read through a computed key would look unsupported, and one only mentioned in
|
|
24
|
+
* a type would look supported. A test anchors every entry to `SocketConfig`, so
|
|
25
|
+
* an option that starts being read here fails the audit for whoever removes it.
|
|
26
|
+
*/
|
|
27
|
+
export const UNSUPPORTED_CONFIG_KEYS = [
|
|
28
|
+
// The engine runs its own keepalive (WA Web's idle-ping + dead-socket
|
|
29
|
+
// watchdog) and its own Fibonacci reconnect ladder.
|
|
30
|
+
'keepAliveIntervalMs',
|
|
31
|
+
// Retry of an undecryptable message is engine-side, keyed off its own store
|
|
32
|
+
// of sent messages; there is nothing for a consumer counter to count.
|
|
33
|
+
'maxMsgRetryCount',
|
|
34
|
+
'msgRetryCounterCache',
|
|
35
|
+
'retryRequestDelayMs',
|
|
36
|
+
// The engine decides its own post-login queries.
|
|
37
|
+
'fireInitQueries',
|
|
38
|
+
// Presence is explicit here: call `sendPresenceUpdate` after `open`.
|
|
39
|
+
'markOnlineOnConnect',
|
|
40
|
+
// History sync is driven by the engine.
|
|
41
|
+
'syncFullHistory',
|
|
42
|
+
'shouldSyncHistoryMessage',
|
|
43
|
+
// Link previews are not generated on this side.
|
|
44
|
+
'generateHighQualityLinkPreview',
|
|
45
|
+
'linkPreviewImageThumbnailWidth',
|
|
46
|
+
// Session recreation and the recent-message cache are engine-side, and
|
|
47
|
+
// configured through `cache` (CacheConfig), not through these flags.
|
|
48
|
+
'enableAutoSessionRecreation',
|
|
49
|
+
'enableRecentMessageCache',
|
|
50
|
+
// App-state MAC verification happens in the engine.
|
|
51
|
+
'appStateMacVerification',
|
|
52
|
+
// The engine resolves group metadata and sent messages from its own stores;
|
|
53
|
+
// these two are the ones consumers most often carry over from upstream and
|
|
54
|
+
// keep believing in.
|
|
55
|
+
'cachedGroupMetadata',
|
|
56
|
+
'getMessage',
|
|
57
|
+
// Upstream hooks with no counterpart on this side.
|
|
58
|
+
'patchMessageBeforeSending',
|
|
59
|
+
'customUploadHosts',
|
|
60
|
+
'countryCode',
|
|
61
|
+
// Timeouts and transport knobs the engine owns. `connectTimeoutMs` is the
|
|
62
|
+
// one to point at: `Socket/internals.ts` already documented that it "reaches
|
|
63
|
+
// neither the transport nor the core", and it was still missing from the
|
|
64
|
+
// first version of this list. Proxy and TLS configuration goes through
|
|
65
|
+
// `options.dispatcher`, which is read — `agent` and `fetchAgent` are not.
|
|
66
|
+
'connectTimeoutMs',
|
|
67
|
+
'qrTimeout',
|
|
68
|
+
'agent',
|
|
69
|
+
'fetchAgent',
|
|
70
|
+
'mobile',
|
|
71
|
+
// The QR is published on `connection.update`; drawing it is the consumer's.
|
|
72
|
+
'printQRInTerminal',
|
|
73
|
+
// Offline delivery is the engine's, and history sync is driven by it too.
|
|
74
|
+
'ignoreOfflineMessages',
|
|
75
|
+
'downloadHistory',
|
|
76
|
+
// Caches the engine keeps natively, in Rust, keyed off its own stores.
|
|
77
|
+
'mediaCache',
|
|
78
|
+
'userDevicesCache',
|
|
79
|
+
'callOfferCache',
|
|
80
|
+
'placeholderResendCache'
|
|
81
|
+
];
|
|
82
|
+
/**
|
|
83
|
+
* The other half: options something on this side actually reads.
|
|
84
|
+
*
|
|
85
|
+
* Only here to make the classification total. Nothing consumes this list at
|
|
86
|
+
* runtime; its job is to let the assertion below fail the build when a new
|
|
87
|
+
* member of `SocketConfig` belongs to neither list — which is exactly how the
|
|
88
|
+
* first version of the catalog shipped twelve keys short.
|
|
89
|
+
*/
|
|
90
|
+
export const READ_CONFIG_KEYS = [
|
|
91
|
+
'waWebSocketUrl',
|
|
92
|
+
'options',
|
|
93
|
+
'logger',
|
|
94
|
+
'version',
|
|
95
|
+
'browser',
|
|
96
|
+
'pushName',
|
|
97
|
+
'auth',
|
|
98
|
+
'cache',
|
|
99
|
+
'deviceProps',
|
|
100
|
+
'wantedPreKeyCount',
|
|
101
|
+
'emitOwnEvents',
|
|
102
|
+
'shouldIgnoreJid',
|
|
103
|
+
'defaultQueryTimeoutMs',
|
|
104
|
+
'transactionOpts',
|
|
105
|
+
'makeSignalRepository'
|
|
106
|
+
];
|
|
107
|
+
const _everyConfigKeyIsClassified = true;
|
|
108
|
+
void _everyConfigKeyIsClassified;
|
|
109
|
+
/**
|
|
110
|
+
* Which unsupported options this caller actually passed.
|
|
111
|
+
*
|
|
112
|
+
* Only own, non-`undefined` properties count: spreading a partial config
|
|
113
|
+
* commonly leaves `{ getMessage: undefined }` behind, and warning about a key
|
|
114
|
+
* whose value is absent would be noise about nothing.
|
|
115
|
+
*
|
|
116
|
+
* @param config the object handed to `makeWASocket`, before defaults are merged
|
|
117
|
+
* @returns the offending keys, in catalog order (stable across consumers)
|
|
118
|
+
*/
|
|
119
|
+
export const unsupportedConfigKeys = (config) => UNSUPPORTED_CONFIG_KEYS.filter(key => Object.hasOwn(config, key) && config[key] !== undefined);
|
|
120
|
+
/**
|
|
121
|
+
* Say once per socket, at construction, which unsupported options this caller
|
|
122
|
+
* passed.
|
|
123
|
+
*
|
|
124
|
+
* Per socket, not per process: a replacement socket built after a terminal
|
|
125
|
+
* close carries its own configuration decision, and `Socket/internals.ts`
|
|
126
|
+
* already warns "once per socket rather than per call" for its own no-ops.
|
|
127
|
+
*
|
|
128
|
+
* `warn` and not `error`: nothing is broken.
|
|
129
|
+
*
|
|
130
|
+
* A socket must never fail to build over a diagnostic. That guarantee is
|
|
131
|
+
* unconditional, so the guard covers the whole of it — the reading as well as
|
|
132
|
+
* the writing:
|
|
133
|
+
*
|
|
134
|
+
* - the optional chaining, for a logger with no `warn` (a minimal one in a
|
|
135
|
+
* test, say);
|
|
136
|
+
* - the `try` around the logging call, for a logger whose `warn` throws — a
|
|
137
|
+
* synchronous transport failing there would take down `makeWASocket` itself;
|
|
138
|
+
* - the same `try` around the inspection, because telling a passed option from
|
|
139
|
+
* a spread leftover means reading `config[key]`, and reading fires getters. A
|
|
140
|
+
* config with a throwing accessor, or a proxy with a throwing trap, would
|
|
141
|
+
* otherwise fail construction from outside the logging call.
|
|
142
|
+
*
|
|
143
|
+
* All of it only ever bites consumers who passed an inert option, which is the
|
|
144
|
+
* one group this warning exists to help. The failure is swallowed rather than
|
|
145
|
+
* reported, because the only thing left to report it with is the logger that
|
|
146
|
+
* just threw.
|
|
147
|
+
*
|
|
148
|
+
* @param config the object handed to `makeWASocket`, before defaults are merged
|
|
149
|
+
* @param logger the socket's logger
|
|
150
|
+
*/
|
|
151
|
+
export const warnUnsupportedConfig = (config, logger) => {
|
|
152
|
+
try {
|
|
153
|
+
const options = unsupportedConfigKeys(config);
|
|
154
|
+
if (!options.length)
|
|
155
|
+
return;
|
|
156
|
+
logger?.warn?.({ options }, 'these options are accepted for upstream compatibility but nothing reads them here: the engine owns that behaviour');
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// See above: nothing here is worth failing a socket over.
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
//# sourceMappingURL=unsupported-config.js.map
|