miaw-core 1.9.0 → 1.10.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/.env.example +59 -0
- package/CHANGELOG.md +150 -0
- package/README.md +13 -1
- package/bin/miaw-cli.ts +50 -4
- package/dist/cli/commands/commands-index.d.ts +1 -0
- package/dist/cli/commands/commands-index.d.ts.map +1 -1
- package/dist/cli/commands/commands-index.js +1 -0
- package/dist/cli/commands/commands-index.js.map +1 -1
- package/dist/cli/commands/index.d.ts +6 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +45 -2
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/proxy.d.ts +59 -0
- package/dist/cli/commands/proxy.d.ts.map +1 -0
- package/dist/cli/commands/proxy.js +418 -0
- package/dist/cli/commands/proxy.js.map +1 -0
- package/dist/cli/repl.d.ts +4 -0
- package/dist/cli/repl.d.ts.map +1 -1
- package/dist/cli/repl.js +43 -3
- package/dist/cli/repl.js.map +1 -1
- package/dist/cli/utils/proxy-config.d.ts +46 -0
- package/dist/cli/utils/proxy-config.d.ts.map +1 -0
- package/dist/cli/utils/proxy-config.js +93 -0
- package/dist/cli/utils/proxy-config.js.map +1 -0
- package/dist/client/MiawClient.d.ts +8 -0
- package/dist/client/MiawClient.d.ts.map +1 -1
- package/dist/client/MiawClient.js +71 -10
- package/dist/client/MiawClient.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/proxy-agent.d.ts +47 -11
- package/dist/utils/proxy-agent.d.ts.map +1 -1
- package/dist/utils/proxy-agent.js +65 -12
- package/dist/utils/proxy-agent.js.map +1 -1
- package/dist/utils/proxy-loader.d.ts +114 -0
- package/dist/utils/proxy-loader.d.ts.map +1 -0
- package/dist/utils/proxy-loader.js +379 -0
- package/dist/utils/proxy-loader.js.map +1 -0
- package/dist/utils/proxy-rotator.d.ts +126 -0
- package/dist/utils/proxy-rotator.d.ts.map +1 -0
- package/dist/utils/proxy-rotator.js +0 -0
- package/dist/utils/proxy-rotator.js.map +1 -0
- package/docs/BAILEYS_VS_MIAW_COMPARISON.md +8 -6
- package/docs/CLI.md +158 -1
- package/docs/DEFERRED_FEATURES.md +67 -0
- package/docs/DEPLOYMENT_PROXY.md +145 -0
- package/docs/PROXY.md +617 -0
- package/docs/USAGE.md +34 -63
- package/package.json +3 -2
- package/docs/PROXY_SUPPORT_PLAN.md +0 -1442
package/.env.example
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# miaw-core / miaw-cli runtime configuration
|
|
2
|
+
#
|
|
3
|
+
# Copy to .env and edit. Every value here is optional — each has a default and
|
|
4
|
+
# each can also be supplied as a CLI flag. Flags win over environment variables.
|
|
5
|
+
#
|
|
6
|
+
# cp .env.example .env
|
|
7
|
+
#
|
|
8
|
+
# .env is gitignored. Prefer this file over CLI flags for anything containing a
|
|
9
|
+
# password: flags land in your shell history and in the process list, where any
|
|
10
|
+
# other user on the machine can read them.
|
|
11
|
+
|
|
12
|
+
# ─── Instance ────────────────────────────────────────────────────────────────
|
|
13
|
+
|
|
14
|
+
# Instance ID. Sessions are isolated per instance. (flag: --instance-id)
|
|
15
|
+
MIAW_INSTANCE_ID=default
|
|
16
|
+
|
|
17
|
+
# Where session credentials are stored, as {MIAW_SESSION_PATH}/{MIAW_INSTANCE_ID}/
|
|
18
|
+
# (flag: --session-path)
|
|
19
|
+
MIAW_SESSION_PATH=./sessions-cli
|
|
20
|
+
|
|
21
|
+
# ─── Proxy (all optional; added in v1.10.0) ──────────────────────────────────
|
|
22
|
+
|
|
23
|
+
# A single proxy for this instance. (flag: --proxy)
|
|
24
|
+
# Schemes: http, https, socks4, socks4a, socks5, socks5h
|
|
25
|
+
#
|
|
26
|
+
# Prefer the h/a variants (socks5h, socks4a): plain socks5/socks4 resolve DNS
|
|
27
|
+
# locally, so the destination hostname leaks to your resolver even though the
|
|
28
|
+
# connection itself is tunnelled.
|
|
29
|
+
#
|
|
30
|
+
# Passwords containing @ : / ? # or % must be percent-encoded here
|
|
31
|
+
# ("p@ss#1" becomes "p%40ss%231"), or use the ProxyConfig object form in code.
|
|
32
|
+
#
|
|
33
|
+
# MIAW_PROXY=socks5h://user:password@proxy.example.com:1080
|
|
34
|
+
|
|
35
|
+
# A proxy list file instead of a single proxy — TXT (one per line) or JSON
|
|
36
|
+
# array. One proxy is selected per process using MIAW_PROXY_STRATEGY.
|
|
37
|
+
# Ignored when MIAW_PROXY is also set. (flag: --proxy-file)
|
|
38
|
+
#
|
|
39
|
+
# See examples/proxies.example.txt for the format.
|
|
40
|
+
#
|
|
41
|
+
# MIAW_PROXY_FILE=./proxies.txt
|
|
42
|
+
|
|
43
|
+
# How a proxy is picked from MIAW_PROXY_FILE. (flag: --proxy-strategy)
|
|
44
|
+
# deterministic same instanceId always maps to the same proxy [default]
|
|
45
|
+
# round-robin next in the list, wrapping
|
|
46
|
+
# random uniform random
|
|
47
|
+
# weighted random, biased by each entry's weight=
|
|
48
|
+
#
|
|
49
|
+
# Leave this as deterministic for anything with a persisted WhatsApp session.
|
|
50
|
+
# WhatsApp treats a session's source IP as a trust signal, so a session whose
|
|
51
|
+
# egress IP jumps between runs looks like an account takeover. Rotation is for
|
|
52
|
+
# spreading instances across proxies, never for rotating a live session's IP.
|
|
53
|
+
#
|
|
54
|
+
# MIAW_PROXY_STRATEGY=deterministic
|
|
55
|
+
|
|
56
|
+
# ─── Logging ─────────────────────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
# Verbose Baileys logging. (flag: --debug)
|
|
59
|
+
# DEBUG=false
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,113 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.10.0] - 2026-07-29
|
|
9
|
+
|
|
10
|
+
**Proxy files, rotation, and CLI diagnostics** - builds on the v1.3.0 proxy core.
|
|
11
|
+
All additive; no breaking changes.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`socks5h://` and `socks4a://` support.** These resolve DNS *at the proxy*;
|
|
16
|
+
plain `socks5://` / `socks4://` resolve locally, so the destination hostname still
|
|
17
|
+
leaks to your DNS resolver even though the connection is tunnelled. Both variants
|
|
18
|
+
were previously rejected as unsupported protocols despite the underlying agent
|
|
19
|
+
supporting them.
|
|
20
|
+
- **Proxy list files** - `loadProxyList()` / `loadProxyListSync()` / `parseProxyList()`
|
|
21
|
+
read TXT (one per line, `#`/`;` comments, optional `weight=` and `label=` tokens,
|
|
22
|
+
scheme-less `host:port[:user:pass]` vendor forms) or JSON (array of strings and/or
|
|
23
|
+
objects, or a `{ "proxies": [...] }` wrapper). Format is auto-detected by extension
|
|
24
|
+
then by content. `validateProxyList()` partitions a list; `watchProxyList()` hot-reloads
|
|
25
|
+
a file.
|
|
26
|
+
- **`ProxyRotator`** - `round-robin`, `random`, `weighted`, and `deterministic`
|
|
27
|
+
strategies, plus `ProxyRotator.fromFile()`, `setProxies()`, `getStats()`, and `close()`.
|
|
28
|
+
It returns a `ProxyPoolEntry` you pass to `new MiawClient({ proxy })`, so `getProxyInfo()`
|
|
29
|
+
and proxy validation keep working for rotated instances.
|
|
30
|
+
- **`maskProxyUrl()`** - exported credential masking; `getProxyInfo()` now uses it.
|
|
31
|
+
- **CLI**: `proxy list` (alias `ls`), `proxy test <url>`, `proxy test-all`. These need
|
|
32
|
+
**no WhatsApp connection** - they probe the proxy through the same agent Baileys uses,
|
|
33
|
+
so you can validate a proxy before spending a pairing attempt on it. `proxy test-all`
|
|
34
|
+
exits non-zero if any proxy fails, so it can gate a deploy.
|
|
35
|
+
- **CLI global flags**: `--proxy-file <path>`, `--proxy-strategy <strategy>`
|
|
36
|
+
(default `deterministic`; `instance` accepted as an alias). Env fallbacks:
|
|
37
|
+
`MIAW_PROXY`, `MIAW_PROXY_FILE`, `MIAW_PROXY_STRATEGY`.
|
|
38
|
+
- **[.env.example](./.env.example)** - documents every `MIAW_*` runtime variable,
|
|
39
|
+
including `MIAW_INSTANCE_ID` and `MIAW_SESSION_PATH`, which the CLI has always
|
|
40
|
+
read but which were never written down anywhere.
|
|
41
|
+
- **[docs/DEPLOYMENT_PROXY.md](./docs/DEPLOYMENT_PROXY.md)** - operational notes for
|
|
42
|
+
deploying with proxies: why `instanceId` must be stable across rollouts, treating
|
|
43
|
+
proxy files as secrets, ConfigMap-safe hot reload, egress firewall rules, and the
|
|
44
|
+
sticky-session requirement.
|
|
45
|
+
- **[docs/PROXY.md](./docs/PROXY.md)** - dedicated proxy guide covering configuration,
|
|
46
|
+
proxy files, rotation, CLI diagnostics, troubleshooting, security, and provider
|
|
47
|
+
selection. Replaces the internal `docs/PROXY_SUPPORT_PLAN.md`, which is removed.
|
|
48
|
+
- 97 new tests (42 loader, 33 rotator, 22 CLI). The CLI proxy tests are the first in
|
|
49
|
+
`tests/integration/cli/` that run without a WhatsApp session.
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- **Media uploads through a proxy were broken and always had been** (since v1.3.0).
|
|
54
|
+
`fetchAgent` was set to an undici `ProxyAgent`, but Baileys declares it as an
|
|
55
|
+
`https.Agent` and its Node upload path hands it to `https.request({ agent })`, which
|
|
56
|
+
cannot use a Dispatcher. Every `sendImage`/`sendVideo`/`sendDocument` through a proxy
|
|
57
|
+
failed with "Media upload failed on all hosts". `fetchAgent` is now the same
|
|
58
|
+
`http.Agent` as `wsAgent`. **Uploads are consequently proxied on SOCKS too**, which
|
|
59
|
+
the previous documentation said was impossible.
|
|
60
|
+
- **Media downloads were never proxied.** Baileys downloads with
|
|
61
|
+
`fetch(url, { dispatcher })` and never wires a proxy into that path, and
|
|
62
|
+
`downloadMedia()` passed no options — so every download revealed the real IP
|
|
63
|
+
regardless of proxy settings. It now passes an undici Dispatcher explicitly.
|
|
64
|
+
This works for HTTP/HTTPS proxies; SOCKS downloads remain direct because undici
|
|
65
|
+
has no SOCKS transport.
|
|
66
|
+
- `proxy test` reported a **407 Proxy Authentication Required as success**. A 407 comes
|
|
67
|
+
from the proxy itself and means the tunnel was refused, so nothing ever reached
|
|
68
|
+
WhatsApp - but the probe counted any HTTP status as reachable. `proxy test-all` would
|
|
69
|
+
therefore green-light a proxy list with wrong credentials, defeating the pre-flight
|
|
70
|
+
check it exists to provide. It now fails with `EPROXYAUTH` and a non-zero exit code.
|
|
71
|
+
- Proxy credentials leaked in two places: `MiawClient` interpolated the raw proxy URL,
|
|
72
|
+
password included, into its "Invalid proxy configuration" error (which lands in logs
|
|
73
|
+
and stack traces), and the CLI printed the raw `--proxy` URL to the REPL startup
|
|
74
|
+
banner. Both are masked now.
|
|
75
|
+
|
|
76
|
+
### Notes
|
|
77
|
+
|
|
78
|
+
- `--proxy-strategy` defaults to `deterministic` so a given `instanceId` keeps a stable
|
|
79
|
+
egress IP across runs. **Rotation is for distributing instances across proxies, never
|
|
80
|
+
for rotating a live session's IP** - WhatsApp treats a session's source IP as a trust
|
|
81
|
+
signal, and churning it looks like account takeover.
|
|
82
|
+
- Deterministic selection uses rendezvous hashing rather than `hash % length`, so adding
|
|
83
|
+
or removing a proxy remaps only the instances that were on it. Under modulo, one edit
|
|
84
|
+
to your proxy file would change the egress IP of every live session at once.
|
|
85
|
+
- SOCKS proxies still route media over a direct connection: Node's `fetch()` requires an
|
|
86
|
+
undici dispatcher and undici has no SOCKS transport. `proxy list` and `proxy test`
|
|
87
|
+
report this per proxy. See [docs/PROXY.md](./docs/PROXY.md).
|
|
88
|
+
|
|
89
|
+
## [1.9.2] - 2026-07-09
|
|
90
|
+
|
|
91
|
+
**CommonJS-consumer fix** - Let `require()` resolve the package.
|
|
92
|
+
|
|
93
|
+
### Fixed
|
|
94
|
+
|
|
95
|
+
- The `exports` map only declared the `import` condition, so CommonJS /
|
|
96
|
+
`require()` resolution (e.g. `ts-node` compiling to CJS) failed with
|
|
97
|
+
`ERR_PACKAGE_PATH_NOT_EXPORTED`. Added a `default` condition pointing at the
|
|
98
|
+
same ESM build; on Node >=22.12 `require(esm)` now resolves it. The package
|
|
99
|
+
stays ESM-only — no separate CJS build was added.
|
|
100
|
+
|
|
101
|
+
## [1.9.1] - 2026-07-07
|
|
102
|
+
|
|
103
|
+
**Message receipts** - Observe delivery/read/played status of messages you send.
|
|
104
|
+
|
|
105
|
+
### Added
|
|
106
|
+
|
|
107
|
+
- New `message_receipt` event (`MessageReceiptUpdate`) surfaced from Baileys'
|
|
108
|
+
`message-receipt.update`: `{ messageId, chatId, recipientId, type, timestamp, fromMe }`
|
|
109
|
+
where `type` is `'delivery' | 'read' | 'played'` (derived from the receipt
|
|
110
|
+
timestamps). This is the observe half of read-receipts — `markAsRead` sends
|
|
111
|
+
them, `message_receipt` now reports incoming ones.
|
|
112
|
+
- Added `docs/DEFERRED_FEATURES.md` tracking the remaining deferred backlog
|
|
113
|
+
(group/community admin, privacy & blocklist, calls, leftover message types).
|
|
114
|
+
|
|
8
115
|
## [1.9.0] - 2026-07-07
|
|
9
116
|
|
|
10
117
|
**Communities** - Wrap Baileys' `community*` API (communities are hubs that link
|
|
@@ -314,6 +421,49 @@ unchanged.
|
|
|
314
421
|
|
|
315
422
|
---
|
|
316
423
|
|
|
424
|
+
## [1.3.0] - 2026-03-13
|
|
425
|
+
|
|
426
|
+
**Proxy support** - route a WhatsApp connection through a proxy, per instance.
|
|
427
|
+
|
|
428
|
+
_Backfilled: this release shipped in commit `8def495` but was never recorded here._
|
|
429
|
+
|
|
430
|
+
### Added
|
|
431
|
+
|
|
432
|
+
- `proxy` option on `MiawClientOptions`, accepting a URL string or a `ProxyConfig`
|
|
433
|
+
object (`{ url, username?, password? }`). Supports HTTP, HTTPS, SOCKS4, and SOCKS5.
|
|
434
|
+
- `createProxyAgents()` and `validateProxyConfig()` in `src/utils/proxy-agent.ts`.
|
|
435
|
+
Dual-agent approach: `https-proxy-agent` / `socks-proxy-agent` for the WebSocket
|
|
436
|
+
transport, `undici`'s `ProxyAgent` for media upload/download.
|
|
437
|
+
- `agent` and `fetchAgent` escape-hatch options for supplying custom transports.
|
|
438
|
+
- `MiawClient.getProxyInfo()` for inspecting the active proxy.
|
|
439
|
+
- `--proxy <url>` CLI flag.
|
|
440
|
+
|
|
441
|
+
### Notes
|
|
442
|
+
|
|
443
|
+
- SOCKS proxies tunnel the WebSocket but not media transfers: Node's `fetch()` needs an
|
|
444
|
+
undici dispatcher and undici has no SOCKS transport, so media falls back to a direct
|
|
445
|
+
connection.
|
|
446
|
+
|
|
447
|
+
## [1.2.0] - 2026-01-20
|
|
448
|
+
|
|
449
|
+
**Code quality release** - configurable timeouts, validation utilities, and type safety.
|
|
450
|
+
|
|
451
|
+
_Backfilled: this release shipped in commit `2e922d2` but was never recorded here._
|
|
452
|
+
|
|
453
|
+
### Added
|
|
454
|
+
|
|
455
|
+
- Configurable timeouts and exported `TIMEOUTS` / `THRESHOLDS` constants.
|
|
456
|
+
- Validation utilities and type-guard helpers (`isError`, `getErrorMessage`,
|
|
457
|
+
`isBaileysMessage`, `isBaileysMessageUpsert`).
|
|
458
|
+
- Custom logger support.
|
|
459
|
+
- CLI: `send video`, `send audio`, `media download`; topic-specific help sub-commands
|
|
460
|
+
and expanded autocomplete.
|
|
461
|
+
|
|
462
|
+
### Changed
|
|
463
|
+
|
|
464
|
+
- Type-safety improvements throughout; 14 of 15 issues from the code review report
|
|
465
|
+
resolved. No breaking changes.
|
|
466
|
+
|
|
317
467
|
## [1.1.0] - 2026-01-02
|
|
318
468
|
|
|
319
469
|
**Baileys v7 Migration** - ESM-only release with improved session stability
|
package/README.md
CHANGED
|
@@ -28,6 +28,9 @@ For a detailed comparison, see [Baileys vs Miaw Core Comparison](./docs/BAILEYS_
|
|
|
28
28
|
|
|
29
29
|
- **[CLI Guide](./docs/CLI.md)** - Command-line interface usage
|
|
30
30
|
- **[Usage Guide](./docs/USAGE.md)** - Complete guide for all current features
|
|
31
|
+
- **[Proxy Guide](./docs/PROXY.md)** - Proxies, proxy list files, and rotation strategies
|
|
32
|
+
- **[Proxy Deployment Notes](./docs/DEPLOYMENT_PROXY.md)** - Operational guidance for deploying with proxies
|
|
33
|
+
- **[LID Resolution](./docs/LID_RESOLUTION.md)** - Working with privacy-masked (`@lid`) JIDs
|
|
31
34
|
- **[Baileys Comparison](./docs/BAILEYS_VS_MIAW_COMPARISON.md)** - Feature comparison with raw Baileys
|
|
32
35
|
- **[Migration Guide](./docs/MIGRATION.md)** - Upgrading between versions
|
|
33
36
|
- **[Test Coverage](./docs/TEST_COVERAGE_ANALYSIS.md)** - API coverage analysis
|
|
@@ -41,6 +44,7 @@ For a detailed comparison, see [Baileys vs Miaw Core Comparison](./docs/BAILEYS_
|
|
|
41
44
|
- **Auto-Reconnection** - Handles connection drops and reconnects automatically
|
|
42
45
|
- **Session Management** - File-based session storage with automatic persistence
|
|
43
46
|
- **Multiple Instances** - Run multiple WhatsApp connections in a single process
|
|
47
|
+
- **Proxy Support** - HTTP/HTTPS/SOCKS proxies, proxy list files, and per-instance rotation
|
|
44
48
|
- **TypeScript Support** - Full type definitions for excellent IDE experience
|
|
45
49
|
- **Event-Driven** - Easy-to-use event system for messages and connection states
|
|
46
50
|
- **Normalized Messages** - Simplified message format, no more complex Baileys structures
|
|
@@ -177,7 +181,7 @@ npm run test:watch
|
|
|
177
181
|
npm run test:coverage
|
|
178
182
|
```
|
|
179
183
|
|
|
180
|
-
## Current Capabilities (v1.
|
|
184
|
+
## Current Capabilities (v1.10.0)
|
|
181
185
|
|
|
182
186
|
Built on **Baileys v7.0.0-rc13** - the latest WhatsApp Web protocol implementation.
|
|
183
187
|
|
|
@@ -193,6 +197,14 @@ Built on **Baileys v7.0.0-rc13** - the latest WhatsApp Web protocol implementati
|
|
|
193
197
|
- ✅ TypeScript support
|
|
194
198
|
- ✅ Error handling
|
|
195
199
|
|
|
200
|
+
### Networking
|
|
201
|
+
|
|
202
|
+
- ✅ HTTP / HTTPS / SOCKS4 / SOCKS5 proxies, per instance
|
|
203
|
+
- ✅ Proxy list files (TXT / JSON) with validation and hot reload
|
|
204
|
+
- ✅ Rotation strategies (round-robin, random, weighted, deterministic-per-instance)
|
|
205
|
+
- ✅ `miaw-cli proxy test` connectivity diagnostics — no WhatsApp connection needed
|
|
206
|
+
- ⚠️ SOCKS proxies: media *downloads* use a direct connection ([details](./docs/PROXY.md#️-socks-media-downloads-use-a-direct-connection))
|
|
207
|
+
|
|
196
208
|
### Advanced Messaging
|
|
197
209
|
|
|
198
210
|
- ✅ Reply/quote messages
|
package/bin/miaw-cli.ts
CHANGED
|
@@ -17,6 +17,11 @@ import { runRepl } from "../src/cli/repl.js";
|
|
|
17
17
|
import { runCommand } from "../src/cli/commands/index.js";
|
|
18
18
|
import { initializeCLICleanup } from "../src/cli/utils/cleanup.js";
|
|
19
19
|
import { getErrorMessage } from "../src/utils/type-guards.js";
|
|
20
|
+
import { maskProxyUrl } from "../src/utils/proxy-agent.js";
|
|
21
|
+
import {
|
|
22
|
+
parseProxyStrategy,
|
|
23
|
+
selectProxyForInstance,
|
|
24
|
+
} from "../src/cli/utils/proxy-config.js";
|
|
20
25
|
|
|
21
26
|
// Initialize CLI cleanup handlers for graceful shutdown
|
|
22
27
|
initializeCLICleanup();
|
|
@@ -28,6 +33,10 @@ dotenv.config({ path: ".env.test" });
|
|
|
28
33
|
// Default configuration
|
|
29
34
|
const DEFAULT_INSTANCE_ID = process.env.MIAW_INSTANCE_ID || "default";
|
|
30
35
|
const DEFAULT_SESSION_PATH = process.env.MIAW_SESSION_PATH || "./sessions-cli";
|
|
36
|
+
// Proxy credentials belong in .env, not in shell history.
|
|
37
|
+
const DEFAULT_PROXY = process.env.MIAW_PROXY || undefined;
|
|
38
|
+
const DEFAULT_PROXY_FILE = process.env.MIAW_PROXY_FILE || undefined;
|
|
39
|
+
const DEFAULT_PROXY_STRATEGY_ENV = process.env.MIAW_PROXY_STRATEGY || undefined;
|
|
31
40
|
|
|
32
41
|
/**
|
|
33
42
|
* Parse CLI arguments
|
|
@@ -78,7 +87,10 @@ USAGE:
|
|
|
78
87
|
GLOBAL FLAGS:
|
|
79
88
|
--instance-id <id> Instance ID (default: "default")
|
|
80
89
|
--session-path <path> Session directory
|
|
81
|
-
--proxy <url> Proxy URL (http
|
|
90
|
+
--proxy <url> Proxy URL (http/https/socks4/socks4a/socks5/socks5h)
|
|
91
|
+
--proxy-file <path> Proxy list file (.txt one-per-line, or .json array)
|
|
92
|
+
--proxy-strategy <strategy> Pick from --proxy-file: round-robin | random |
|
|
93
|
+
weighted | deterministic (default: deterministic)
|
|
82
94
|
--json Output as JSON
|
|
83
95
|
--debug Enable verbose logging
|
|
84
96
|
|
|
@@ -93,6 +105,7 @@ COMMANDS:
|
|
|
93
105
|
profile Profile management (picture, name, status)
|
|
94
106
|
label Label management - WhatsApp Business (list, chats, add, chat)
|
|
95
107
|
catalog Catalog management - WhatsApp Business (list, collections, product)
|
|
108
|
+
proxy Inspect and test proxies (list, test, test-all) - no connection needed
|
|
96
109
|
|
|
97
110
|
COMMON OPTIONS:
|
|
98
111
|
--limit N Limit number of results
|
|
@@ -103,6 +116,8 @@ EXAMPLES:
|
|
|
103
116
|
miaw-cli send text 6281234567890 "Hello"
|
|
104
117
|
miaw-cli group participants add 120363xxx@g.us 628xxx
|
|
105
118
|
miaw-cli contact add 6281234567890 "John Doe"
|
|
119
|
+
miaw-cli proxy test socks5://proxy.example.com:1080
|
|
120
|
+
miaw-cli --instance-id bot-3 --proxy-file ./proxies.txt get groups
|
|
106
121
|
|
|
107
122
|
REPL MODE:
|
|
108
123
|
Run 'miaw-cli' without arguments to start interactive mode.
|
|
@@ -132,8 +147,35 @@ async function main() {
|
|
|
132
147
|
const jsonOutput = flags.json === true;
|
|
133
148
|
const debugMode = flags.debug === true;
|
|
134
149
|
|
|
135
|
-
// Extract proxy flag
|
|
136
|
-
const
|
|
150
|
+
// Extract proxy flags (CLI flag wins over the MIAW_PROXY* env fallbacks)
|
|
151
|
+
const explicitProxy = (flags.proxy as string | undefined) || DEFAULT_PROXY;
|
|
152
|
+
const proxyFile = (flags["proxy-file"] as string | undefined) || DEFAULT_PROXY_FILE;
|
|
153
|
+
|
|
154
|
+
let proxyStrategy;
|
|
155
|
+
try {
|
|
156
|
+
proxyStrategy = parseProxyStrategy(
|
|
157
|
+
(flags["proxy-strategy"] as string | undefined) || DEFAULT_PROXY_STRATEGY_ENV
|
|
158
|
+
);
|
|
159
|
+
} catch (error: unknown) {
|
|
160
|
+
console.error(`❌ ${getErrorMessage(error)}`);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Precedence: an explicit --proxy always wins; otherwise a --proxy-file
|
|
165
|
+
// selects one proxy for this process. The default strategy is
|
|
166
|
+
// deterministic so a given instanceId keeps a stable egress IP across
|
|
167
|
+
// invocations - round-robin here would silently rotate a live session's IP.
|
|
168
|
+
let proxyUrl = explicitProxy;
|
|
169
|
+
if (explicitProxy && proxyFile) {
|
|
170
|
+
console.log("⚠️ --proxy overrides --proxy-file");
|
|
171
|
+
} else if (!explicitProxy && proxyFile) {
|
|
172
|
+
try {
|
|
173
|
+
proxyUrl = await selectProxyForInstance(proxyFile, proxyStrategy, instanceId);
|
|
174
|
+
} catch (error: unknown) {
|
|
175
|
+
console.error(`❌ Failed to select a proxy from ${proxyFile}: ${getErrorMessage(error)}`);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
137
179
|
|
|
138
180
|
// Create client configuration
|
|
139
181
|
const clientConfig = {
|
|
@@ -141,6 +183,8 @@ async function main() {
|
|
|
141
183
|
sessionPath,
|
|
142
184
|
debug: debugMode,
|
|
143
185
|
...(proxyUrl && { proxy: proxyUrl }),
|
|
186
|
+
...(proxyFile && { proxyFile }),
|
|
187
|
+
proxyStrategy,
|
|
144
188
|
};
|
|
145
189
|
|
|
146
190
|
// No command provided - start REPL
|
|
@@ -148,7 +192,7 @@ async function main() {
|
|
|
148
192
|
console.log(`\n🚀 Starting miaw-cli REPL...`);
|
|
149
193
|
console.log(`📂 Instance: ${instanceId}`);
|
|
150
194
|
console.log(`📂 Session: ${sessionPath}`);
|
|
151
|
-
if (proxyUrl) console.log(`🌐 Proxy: ${proxyUrl}`);
|
|
195
|
+
if (proxyUrl) console.log(`🌐 Proxy: ${maskProxyUrl(proxyUrl)}`);
|
|
152
196
|
console.log(`🔧 Debug: ${debugMode ? "ON" : "OFF"}\n`);
|
|
153
197
|
|
|
154
198
|
try {
|
|
@@ -166,6 +210,8 @@ async function main() {
|
|
|
166
210
|
clientConfig,
|
|
167
211
|
jsonOutput,
|
|
168
212
|
flags,
|
|
213
|
+
...(proxyFile && { proxyFile }),
|
|
214
|
+
proxyStrategy,
|
|
169
215
|
});
|
|
170
216
|
|
|
171
217
|
if (!success) {
|
|
@@ -13,6 +13,7 @@ export { cmdCommunityList, cmdCommunityInfo, cmdCommunityCreate, cmdCommunityLea
|
|
|
13
13
|
export { cmdMediaDownload } from "./media.js";
|
|
14
14
|
export { cmdGroupList, cmdGroupInfo, cmdGroupParticipants, cmdGroupInviteLink, cmdGroupCreate, cmdGroupLeave, cmdGroupInviteAccept, cmdGroupInviteRevoke, cmdGroupInviteInfo, cmdGroupParticipantsAdd, cmdGroupParticipantsRemove, cmdGroupParticipantsPromote, cmdGroupParticipantsDemote, cmdGroupNameSet, cmdGroupDescriptionSet, cmdGroupPictureSet, } from "./group.js";
|
|
15
15
|
export { cmdCheck, } from "./misc.js";
|
|
16
|
+
export { cmdProxyList, cmdProxyTest, cmdProxyTestAll, } from "./proxy.js";
|
|
16
17
|
export { cmdContactList, cmdContactInfo, cmdContactBusiness, cmdContactPicture, cmdContactAdd, cmdContactRemove, } from "./contact.js";
|
|
17
18
|
export { cmdProfilePictureSet, cmdProfilePictureRemove, cmdProfileNameSet, cmdProfileStatusSet, } from "./profile.js";
|
|
18
19
|
export { cmdLabelAdd, cmdLabelChats, cmdLabelChatAdd, cmdLabelChatRemove, } from "./label.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands-index.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/commands-index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,aAAa,EACb,cAAc,EACd,YAAY,EACZ,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,aAAa,GACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,eAAe,EACf,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,QAAQ,GACT,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"commands-index.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/commands-index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,aAAa,EACb,cAAc,EACd,YAAY,EACZ,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,aAAa,GACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,eAAe,EACf,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,QAAQ,GACT,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,cAAc,CAAC"}
|
|
@@ -13,6 +13,7 @@ export { cmdCommunityList, cmdCommunityInfo, cmdCommunityCreate, cmdCommunityLea
|
|
|
13
13
|
export { cmdMediaDownload } from "./media.js";
|
|
14
14
|
export { cmdGroupList, cmdGroupInfo, cmdGroupParticipants, cmdGroupInviteLink, cmdGroupCreate, cmdGroupLeave, cmdGroupInviteAccept, cmdGroupInviteRevoke, cmdGroupInviteInfo, cmdGroupParticipantsAdd, cmdGroupParticipantsRemove, cmdGroupParticipantsPromote, cmdGroupParticipantsDemote, cmdGroupNameSet, cmdGroupDescriptionSet, cmdGroupPictureSet, } from "./group.js";
|
|
15
15
|
export { cmdCheck, } from "./misc.js";
|
|
16
|
+
export { cmdProxyList, cmdProxyTest, cmdProxyTestAll, } from "./proxy.js";
|
|
16
17
|
export { cmdContactList, cmdContactInfo, cmdContactBusiness, cmdContactPicture, cmdContactAdd, cmdContactRemove, } from "./contact.js";
|
|
17
18
|
export { cmdProfilePictureSet, cmdProfilePictureRemove, cmdProfileNameSet, cmdProfileStatusSet, } from "./profile.js";
|
|
18
19
|
export { cmdLabelAdd, cmdLabelChats, cmdLabelChatAdd, cmdLabelChatRemove, } from "./label.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands-index.js","sourceRoot":"","sources":["../../../src/cli/commands/commands-index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,aAAa,EACb,cAAc,EACd,YAAY,EACZ,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,aAAa,GACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,eAAe,EACf,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,QAAQ,GACT,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"commands-index.js","sourceRoot":"","sources":["../../../src/cli/commands/commands-index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,aAAa,EACb,cAAc,EACd,YAAY,EACZ,WAAW,EACX,cAAc,EACd,mBAAmB,EACnB,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,aAAa,GACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,eAAe,EACf,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,QAAQ,GACT,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,cAAc,CAAC"}
|
|
@@ -8,11 +8,17 @@ export interface CommandContext {
|
|
|
8
8
|
instanceId: string;
|
|
9
9
|
sessionPath: string;
|
|
10
10
|
debug?: boolean;
|
|
11
|
+
/** Set by bin/miaw-cli.ts from --proxy or a --proxy-file selection. */
|
|
12
|
+
proxy?: string;
|
|
11
13
|
};
|
|
12
14
|
jsonOutput?: boolean;
|
|
13
15
|
flags?: {
|
|
14
16
|
[key: string]: string | boolean;
|
|
15
17
|
};
|
|
18
|
+
/** Proxy list file from --proxy-file, for the `proxy` commands. */
|
|
19
|
+
proxyFile?: string;
|
|
20
|
+
/** Selection strategy from --proxy-strategy. */
|
|
21
|
+
proxyStrategy?: string;
|
|
16
22
|
}
|
|
17
23
|
/**
|
|
18
24
|
* Run a command
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyHH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,uEAAuE;QACvE,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC5C,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA2hCpE"}
|
|
@@ -33,7 +33,10 @@ cmdProfilePictureSet, cmdProfilePictureRemove, cmdProfileNameSet, cmdProfileStat
|
|
|
33
33
|
// Label commands (Business)
|
|
34
34
|
cmdLabelAdd, cmdLabelChats, cmdLabelChatAdd, cmdLabelChatRemove,
|
|
35
35
|
// Catalog commands (Business)
|
|
36
|
-
cmdCatalogList, cmdCatalogCollections, cmdCatalogProductCreate, cmdCatalogProductUpdate, cmdCatalogProductDelete,
|
|
36
|
+
cmdCatalogList, cmdCatalogCollections, cmdCatalogProductCreate, cmdCatalogProductUpdate, cmdCatalogProductDelete,
|
|
37
|
+
// Proxy commands (no connection required)
|
|
38
|
+
cmdProxyList, cmdProxyTest, cmdProxyTestAll, } from "./commands-index.js";
|
|
39
|
+
import { resolveProxyFile } from "../utils/proxy-config.js";
|
|
37
40
|
/**
|
|
38
41
|
* Run a command
|
|
39
42
|
*/
|
|
@@ -93,6 +96,46 @@ export async function runCommand(command, args, context) {
|
|
|
93
96
|
return false;
|
|
94
97
|
}
|
|
95
98
|
}
|
|
99
|
+
// Proxy commands (don't require connection - they probe the proxy directly).
|
|
100
|
+
// Must stay ABOVE getOrCreateClient() so no client is ever constructed.
|
|
101
|
+
if (command === "proxy") {
|
|
102
|
+
const subCommand = parsedArgs._[0] || "";
|
|
103
|
+
const subArgs = parsedArgs._.slice(1);
|
|
104
|
+
const proxyFile = resolveProxyFile(parsedArgs, context.flags, context.proxyFile);
|
|
105
|
+
// Flags arrive from two different places: one-shot mode strips every
|
|
106
|
+
// --flag in bin/miaw-cli.ts before calling runCommand (so they land in
|
|
107
|
+
// context.flags), while the REPL passes the raw tokenized line (so they
|
|
108
|
+
// land in parsedArgs). Both must be read or the flag silently no-ops.
|
|
109
|
+
const showIp = parsedArgs.ip === true || context.flags?.ip === true;
|
|
110
|
+
const rawTimeout = parsedArgs.timeout ?? context.flags?.timeout;
|
|
111
|
+
const timeoutMs = typeof rawTimeout === "number"
|
|
112
|
+
? rawTimeout
|
|
113
|
+
: typeof rawTimeout === "string" && /^\d+$/.test(rawTimeout)
|
|
114
|
+
? Number(rawTimeout)
|
|
115
|
+
: undefined;
|
|
116
|
+
const probeOptions = {
|
|
117
|
+
showIp,
|
|
118
|
+
...(timeoutMs !== undefined && { timeoutMs }),
|
|
119
|
+
};
|
|
120
|
+
switch (subCommand) {
|
|
121
|
+
case "ls":
|
|
122
|
+
case "list":
|
|
123
|
+
return await cmdProxyList(proxyFile, jsonOutput);
|
|
124
|
+
case "test":
|
|
125
|
+
return await cmdProxyTest(subArgs[0] || context.flags?.proxy || clientConfig.proxy, probeOptions, jsonOutput);
|
|
126
|
+
case "test-all":
|
|
127
|
+
return await cmdProxyTestAll(proxyFile, probeOptions, jsonOutput);
|
|
128
|
+
default:
|
|
129
|
+
if (!subCommand) {
|
|
130
|
+
console.log("Usage: proxy <command>");
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
console.log(`❌ Unknown proxy command: ${subCommand}`);
|
|
134
|
+
}
|
|
135
|
+
console.log("Commands: list, test, test-all");
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
96
139
|
// Create or get cached client for commands that need connection
|
|
97
140
|
const client = getOrCreateClient(clientConfig);
|
|
98
141
|
// Get commands
|
|
@@ -940,7 +983,7 @@ export async function runCommand(command, args, context) {
|
|
|
940
983
|
* Parse command arguments.
|
|
941
984
|
* Only auto-converts known numeric flags to numbers; all others stay as strings.
|
|
942
985
|
*/
|
|
943
|
-
const NUMERIC_FLAGS = new Set(["limit", "count", "cursor"]);
|
|
986
|
+
const NUMERIC_FLAGS = new Set(["limit", "count", "cursor", "timeout"]);
|
|
944
987
|
function parseCommandArgs(args) {
|
|
945
988
|
const parsed = { _: [] };
|
|
946
989
|
for (let i = 0; i < args.length; i++) {
|