diff options
| author | Elvis Claros Castro <elvis@claros.ar> | 2026-09-26 19:26:33 -0300 |
|---|---|---|
| committer | Elvis Claros Castro <elvis@claros.ar> | 2026-09-26 19:26:33 -0300 |
| commit | d80640d01eeb84907e36ff4af33add9081eda17c (patch) | |
| tree | 27698b34e06e28d111c2196700015d9c82f78274 /src/config.js | |
| download | wa-cli-main.tar.gz wa-cli-main.zip | |
Diffstat (limited to 'src/config.js')
| -rw-r--r-- | src/config.js | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/config.js b/src/config.js new file mode 100644 index 0000000..d29ada4 --- /dev/null +++ b/src/config.js @@ -0,0 +1,82 @@ +// Paths, accounts and user config. +// +// Everything follows XDG, split per account (like gws with several accounts): +// config ~/.config/wa-cli/config.json, hooks/ +// session ~/.local/share/wa-cli/<account>/ (LocalAuth: Chrome profile) +// state ~/.local/state/wa-cli/<account>/ (pid, daemon log) +// media ~/.local/share/wa-cli/<account>/media/ +// socket $XDG_RUNTIME_DIR/wa-cli/<account>.sock + +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; + +const env = process.env; +const HOME = os.homedir(); +const XDG_CONFIG = env.XDG_CONFIG_HOME || path.join(HOME, '.config'); +const XDG_DATA = env.XDG_DATA_HOME || path.join(HOME, '.local/share'); +const XDG_STATE = env.XDG_STATE_HOME || path.join(HOME, '.local/state'); +const XDG_CACHE = env.XDG_CACHE_HOME || path.join(HOME, '.cache'); +const RUNTIME = env.XDG_RUNTIME_DIR || path.join(os.tmpdir(), `wa-cli-${process.getuid()}`); + +const ACCOUNT_RE = /^[A-Za-z0-9_-]+$/; + +export const VERSION = JSON.parse( + fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8'), +).version; + +export function accountName(flag) { + const name = flag || env.WA_CLI_ACCOUNT || 'default'; + if (!ACCOUNT_RE.test(name)) { + throw Object.assign(new Error(`invalid account name: ${name} (only [A-Za-z0-9_-])`), { code: 'EINVAL' }); + } + return name; +} + +export function paths(account) { + const configDir = env.WA_CLI_CONFIG_DIR || path.join(XDG_CONFIG, 'wa-cli'); + const dataDir = path.join(env.WA_CLI_DATA_DIR || path.join(XDG_DATA, 'wa-cli'), account); + const stateDir = path.join(XDG_STATE, 'wa-cli', account); + return { + configDir, + configFile: path.join(configDir, 'config.json'), + hooksDir: path.join(configDir, 'hooks'), + dataDir, + mediaDir: path.join(dataDir, 'media'), + stateDir, + pidFile: path.join(stateDir, 'daemon.pid'), + logFile: path.join(stateDir, 'daemon.log'), + cacheDir: path.join(XDG_CACHE, 'wa-cli'), + socket: env.WA_CLI_SOCKET || path.join(RUNTIME, 'wa-cli', `${account}.sock`), + }; +} + +const DEFAULTS = { + autostart: true, // the CLI starts the daemon if it is not running + readyTimeoutMs: 120000, // how long a command waits for the session to be ready + startTimeoutMs: 180000, // if WhatsApp Web does not load within this time, the daemon exits (and is restarted) + hooks: true, // ejecutar ~/.config/wa-cli/hooks/<evento> + hookTimeoutMs: 60000, + browserName: 'wa-cli', // shows as "wa-cli (Linux)" under Linked devices + deviceName: 'Linux', + puppeteer: { headless: true }, +}; + +// config.json: { ...globals, "accounts": { "<account>": { ...overrides } } } +export function loadConfig(account) { + const p = paths(account); + let file = {}; + try { + file = JSON.parse(fs.readFileSync(p.configFile, 'utf8')); + } catch (e) { + if (e.code !== 'ENOENT') { + throw Object.assign(new Error(`${p.configFile}: ${e.message}`), { code: 'EINVAL' }); + } + } + const { accounts = {}, ...global } = file; + const cfg = { ...DEFAULTS, ...global, ...(accounts[account] || {}) }; + cfg.puppeteer = { ...DEFAULTS.puppeteer, ...global.puppeteer, ...accounts[account]?.puppeteer }; + cfg.wamail = { ...global.wamail, ...accounts[account]?.wamail }; + if (env.WA_CLI_AUTOSTART !== undefined) cfg.autostart = !/^(0|false|no)$/i.test(env.WA_CLI_AUTOSTART); + return cfg; +} |