@open-wa/wa-automate 5.3.0 → 5.5.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/dist/index.cjs CHANGED
@@ -1,19 +1,72 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_cli_runtime = require("./cli-runtime-BHx1nVhT.cjs");
2
+ const require_cli_runtime = require("./cli-runtime-BRj_LUIT.cjs");
3
3
  let _open_wa_api = require("@open-wa/api");
4
4
  let node_path = require("node:path");
5
5
  let _open_wa_logger = require("@open-wa/logger");
6
6
  let _open_wa_session_sync = require("@open-wa/session-sync");
7
7
  let _open_wa_core = require("@open-wa/core");
8
- let _open_wa_client = require("@open-wa/client");
9
- let _open_wa_driver_lightpanda = require("@open-wa/driver-lightpanda");
10
- let _open_wa_driver_puppeteer = require("@open-wa/driver-puppeteer");
11
8
  let _open_wa_config = require("@open-wa/config");
12
- let node_fs = require("node:fs");
13
- let node_crypto = require("node:crypto");
14
- let node_os = require("node:os");
9
+ let _open_wa_schema = require("@open-wa/schema");
10
+ //#region src/server/lifecycle-manager.ts
11
+ var APILifecycleManager = class {
12
+ config;
13
+ server;
14
+ _sessionConnected = false;
15
+ constructor(config) {
16
+ this.config = config;
17
+ }
18
+ async initialize() {
19
+ const sink = require_cli_runtime.getCliOutputSink();
20
+ switch (this.config.apiLifecycle) {
21
+ case "immediate":
22
+ sink.status({
23
+ phase: "server.starting",
24
+ sessionId: this.config.sessionId,
25
+ detail: "Starting full API immediately"
26
+ });
27
+ await this.startFullAPI();
28
+ break;
29
+ case "post-connection":
30
+ this.waitForConnection();
31
+ break;
32
+ case "hybrid":
33
+ sink.status({
34
+ phase: "server.starting",
35
+ sessionId: this.config.sessionId,
36
+ detail: "Starting minimal API (QR only)"
37
+ });
38
+ await this.startMinimalAPI();
39
+ }
40
+ }
41
+ async waitForConnection() {
42
+ require_cli_runtime.getCliOutputSink().write({
43
+ level: "info",
44
+ message: "Waiting for session connection before starting API..."
45
+ });
46
+ }
47
+ async startFullAPI() {
48
+ require_cli_runtime.getCliOutputSink().write({
49
+ level: "info",
50
+ message: "Starting full API immediately..."
51
+ });
52
+ this.server = new require_cli_runtime.WAServer(this.config);
53
+ await this.server.start();
54
+ }
55
+ async startMinimalAPI() {
56
+ require_cli_runtime.getCliOutputSink().write({
57
+ level: "info",
58
+ message: "Starting minimal API (QR only)..."
59
+ });
60
+ this.server = new require_cli_runtime.WAServer(this.config);
61
+ await this.server.start();
62
+ }
63
+ async stop() {
64
+ if (this.server) await this.server.stop();
65
+ }
66
+ };
67
+ //#endregion
15
68
  //#region src/session/SessionArchiveManager.ts
16
- var SessionArchiveManager = class SessionArchiveManager {
69
+ var SessionArchiveManager = class {
17
70
  config;
18
71
  logger = (0, _open_wa_logger.createLogger)({ component: "SessionArchiveManager" });
19
72
  localCompression;
@@ -76,17 +129,6 @@ var SessionArchiveManager = class SessionArchiveManager {
76
129
  if (!this.s3Sync) return null;
77
130
  return this.s3Sync.getDownloadUrl(filename, expiresIn);
78
131
  }
79
- static createFromConfig(config) {
80
- if (!config.legacyDataDirAuth) throw new Error("Profile archives require legacyDataDirAuth: true; compact sessions sync through the client");
81
- if (!config.s3Sync) throw new Error("Session archive management requires s3Sync configuration");
82
- return new SessionArchiveManager({
83
- sessionId: config.sessionId,
84
- dataDir: config.userDataDir || config.sessionDataPath || "./.wwebjs",
85
- s3Config: config.s3Sync,
86
- syncInterval: config.s3Sync.syncInterval,
87
- watchLocalChanges: config.s3Sync.enableLocalCompression !== false
88
- });
89
- }
90
132
  get archivePath() {
91
133
  return (0, node_path.join)((0, node_path.dirname)(this.config.dataDir), `${this.config.sessionId}.data.zst`);
92
134
  }
@@ -101,303 +143,34 @@ var SessionArchiveManager = class SessionArchiveManager {
101
143
  }
102
144
  };
103
145
  //#endregion
104
- //#region src/server/lifecycle-manager.ts
105
- var APILifecycleManager = class {
106
- config;
107
- server;
108
- sessionArchiveManager;
109
- _sessionConnected = false;
110
- constructor(config) {
111
- this.config = config;
112
- if (config.legacyDataDirAuth && config.s3Sync) this.sessionArchiveManager = SessionArchiveManager.createFromConfig(config);
113
- }
114
- async initialize() {
115
- const sink = require_cli_runtime.getCliOutputSink();
116
- switch (this.config.apiLifecycle) {
117
- case "immediate":
118
- sink.status({
119
- phase: "server.starting",
120
- sessionId: this.config.sessionId,
121
- detail: "Starting full API immediately"
122
- });
123
- await this.startFullAPI();
124
- break;
125
- case "post-connection":
126
- this.waitForConnection();
127
- break;
128
- case "hybrid":
129
- sink.status({
130
- phase: "server.starting",
131
- sessionId: this.config.sessionId,
132
- detail: "Starting minimal API (QR only)"
133
- });
134
- await this.startMinimalAPI();
135
- }
136
- if (this.sessionArchiveManager) await this.sessionArchiveManager.start();
137
- }
138
- async waitForConnection() {
139
- require_cli_runtime.getCliOutputSink().write({
140
- level: "info",
141
- message: "Waiting for session connection before starting API..."
142
- });
143
- }
144
- async startFullAPI() {
145
- require_cli_runtime.getCliOutputSink().write({
146
- level: "info",
147
- message: "Starting full API immediately..."
148
- });
149
- this.server = new require_cli_runtime.WAServer(this.config);
150
- await this.server.start();
151
- }
152
- async startMinimalAPI() {
153
- require_cli_runtime.getCliOutputSink().write({
154
- level: "info",
155
- message: "Starting minimal API (QR only)..."
156
- });
157
- this.server = new require_cli_runtime.WAServer(this.config);
158
- await this.server.start();
159
- }
160
- async stop() {
161
- if (this.sessionArchiveManager) await this.sessionArchiveManager.stop();
162
- if (this.server) await this.server.stop();
163
- }
164
- };
165
- //#endregion
166
- //#region src/runtime-client.ts
167
- function readChromePathCache(cacheFilePath) {
168
- try {
169
- if (!(0, node_fs.existsSync)(cacheFilePath)) return;
170
- const raw = JSON.parse((0, node_fs.readFileSync)(cacheFilePath, "utf8"));
171
- if (!raw || typeof raw !== "object") return;
172
- return { executablePath: typeof raw.executablePath === "string" ? raw.executablePath : void 0 };
173
- } catch {
174
- return;
175
- }
176
- }
177
- function writeChromePathCache(executablePath, cacheFilePath) {
178
- (0, node_fs.mkdirSync)((0, node_path.dirname)(cacheFilePath), { recursive: true });
179
- (0, node_fs.writeFileSync)(cacheFilePath, JSON.stringify({
180
- executablePath,
181
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
182
- }, null, 2), "utf8");
183
- }
184
- function clearChromePathCache(cacheFilePath) {
185
- if ((0, node_fs.existsSync)(cacheFilePath)) (0, node_fs.rmSync)(cacheFilePath, { force: true });
186
- }
187
- function isUsableExecutablePath(executablePath) {
188
- return !!executablePath && (0, node_fs.existsSync)(executablePath);
189
- }
190
- function getExplicitUseChromePreference(rawConfigs) {
191
- const explicitConfigSources = [
192
- rawConfigs?.file,
193
- rawConfigs?.env,
194
- rawConfigs?.cli,
195
- rawConfigs?.programmatic
196
- ];
197
- for (let index = explicitConfigSources.length - 1; index >= 0; index -= 1) {
198
- const source = explicitConfigSources[index];
199
- if (source?.useChrome !== void 0) return source.useChrome;
200
- }
201
- }
202
- function shouldPreferLocalChrome(config, rawConfigs, defaultPreference = true) {
203
- if (config.useLightpanda) return false;
204
- if (config.executablePath) return false;
205
- const explicitUseChrome = getExplicitUseChromePreference(rawConfigs);
206
- if (explicitUseChrome !== void 0) return explicitUseChrome;
207
- return defaultPreference;
208
- }
209
- async function resolveExecutablePath(config, options) {
210
- if (config.executablePath) return {
211
- executablePath: config.executablePath,
212
- source: "config"
213
- };
214
- if (!(options.preferLocalChrome ?? config.useChrome)) return { source: "driver_default" };
215
- const cachedPath = readChromePathCache(options.cacheFilePath)?.executablePath;
216
- if (isUsableExecutablePath(cachedPath)) return {
217
- executablePath: cachedPath,
218
- source: "cache"
219
- };
220
- if (cachedPath) clearChromePathCache(options.cacheFilePath);
221
- const { Launcher } = await import("chrome-launcher");
222
- const detectedPath = Launcher.getInstallations().find((installationPath) => isUsableExecutablePath(installationPath));
223
- if (detectedPath) {
224
- writeChromePathCache(detectedPath, options.cacheFilePath);
225
- return {
226
- executablePath: detectedPath,
227
- source: "chrome_installation"
228
- };
229
- }
230
- clearChromePathCache(options.cacheFilePath);
231
- return {
232
- source: "driver_default",
233
- warning: "Chrome resolution warning: no valid local Chrome installation was found. Falling back to Puppeteer/default driver browser resolution."
234
- };
235
- }
236
- function resolveLightpandaExecutablePath(config) {
237
- const executablePath = config.lightpanda?.executablePath;
238
- if (executablePath) return {
239
- executablePath,
240
- source: "lightpanda_config"
241
- };
242
- return { source: "lightpanda_sdk_default" };
243
- }
244
- async function selectRuntimeDriver(config, options) {
245
- if (config.useLightpanda) return {
246
- driver: new _open_wa_driver_lightpanda.LightpandaDriver(),
247
- engineLabel: "Lightpanda",
248
- executableResolution: resolveLightpandaExecutablePath(config),
249
- preferLocalChrome: false
250
- };
251
- const preferLocalChrome = shouldPreferLocalChrome(config, options.rawConfigs, options.defaultPreferLocalChrome ?? true);
252
- const executableResolution = await resolveExecutablePath(config, {
253
- preferLocalChrome,
254
- cacheFilePath: options.cacheFilePath
255
- });
256
- return {
257
- driver: new _open_wa_driver_puppeteer.PuppeteerDriver(),
258
- engineLabel: "Puppeteer",
259
- executableResolution,
260
- preferLocalChrome
261
- };
262
- }
263
- function toCreateClientOptions(config, driverSelection, options = {}) {
264
- return {
265
- sessionId: config.sessionId,
266
- driver: driverSelection.driver,
267
- deleteSessionDataOnLogout: config.deleteSessionDataOnLogout,
268
- killClientOnLogout: config.killClientOnLogout,
269
- legacyDataDirAuth: config.legacyDataDirAuth,
270
- sessionDataPath: config.sessionDataPath,
271
- sessionData: config.sessionData,
272
- skipSessionSave: config.skipSessionSave,
273
- sessionDataBucketAuth: config.sessionDataBucketAuth,
274
- s3Sync: config.s3Sync,
275
- debug: options.debug ?? (config.logLevel === "debug" || config.logConsole),
276
- headless: config.headless,
277
- qrTimeoutMs: typeof config.qrTimeout === "number" ? config.qrTimeout * 1e3 : void 0,
278
- authTimeoutMs: typeof config.authTimeout === "number" ? config.authTimeout * 1e3 : void 0,
279
- executablePath: driverSelection.executableResolution.executablePath,
280
- browserArgs: config.chromiumArgs,
281
- browser: config.browser,
282
- allowDangerousBrowserArgs: config.allowDangerousBrowserArgs,
283
- userDataDir: config.userDataDir,
284
- ephemeral: config.ephemeral,
285
- linkCode: config.linkCode,
286
- qrMax: config.qrMax,
287
- oorTimeoutMs: config.oorTimeout * 1e3,
288
- logConsole: config.logConsole,
289
- logConsoleErrors: config.logConsoleErrors,
290
- blockCrashLogs: config.blockCrashLogs,
291
- blockAssets: config.blockAssets,
292
- safeMode: config.safeMode,
293
- lightpanda: config.useLightpanda ? config.lightpanda : void 0,
294
- licenseKey: config.licenseKey,
295
- patchConfig: {
296
- ghPatch: config.ghPatch,
297
- cachedPatch: config.cachedPatch
298
- }
299
- };
300
- }
301
- /** Private profile storage, stable for this project directory and session name. */
302
- function privateSessionDirectory(sessionId) {
303
- const project = (0, node_crypto.createHash)("sha256").update((0, node_fs.realpathSync)(process.cwd())).digest("hex").slice(0, 24);
304
- const session = (0, node_crypto.createHash)("sha256").update(sessionId).digest("hex").slice(0, 24);
305
- const root = (0, node_path.resolve)((0, node_os.homedir)(), ".open-wa", "sessions");
306
- const directory = (0, node_path.resolve)(root, project, session);
307
- (0, node_fs.mkdirSync)(directory, {
308
- recursive: true,
309
- mode: 448
310
- });
311
- for (const path of [
312
- root,
313
- (0, node_path.dirname)(directory),
314
- directory
315
- ]) (0, node_fs.chmodSync)(path, 448);
316
- return directory;
317
- }
318
- /** Start WhatsApp, display QR login when needed, and return a ready messaging client. */
319
- async function create(options = {}) {
320
- const { driver, sessionData, sessionDataBucketAuth, s3Sync, ...configOverrides } = options;
321
- const { config, rawConfigs } = await (0, _open_wa_config.resolveConfig)({
322
- programmaticOverrides: {
323
- qrTimeout: 0,
324
- ...configOverrides
325
- },
326
- skipConfigFile: true,
327
- skipEnv: true,
328
- includeRawConfigs: true
329
- });
330
- const coreOptions = toCreateClientOptions(config, await selectRuntimeDriver(config, {
331
- rawConfigs,
332
- cacheFilePath: (0, node_path.resolve)(process.cwd(), ".open-wa", "chrome-executable-path.json"),
333
- defaultPreferLocalChrome: false
334
- }));
335
- if (driver) coreOptions.driver = driver;
336
- coreOptions.sessionData = sessionData;
337
- coreOptions.sessionDataBucketAuth = sessionDataBucketAuth;
338
- coreOptions.s3Sync = s3Sync;
339
- if (config.legacyDataDirAuth && !config.ephemeral && configOverrides.userDataDir === void 0 && configOverrides.sessionDataPath === void 0) {
340
- coreOptions.userDataDir = privateSessionDirectory(config.sessionId);
341
- coreOptions.sessionDataPath = coreOptions.userDataDir;
342
- }
343
- const core = await (0, _open_wa_core.createClient)(coreOptions);
344
- const sink = require_cli_runtime.getCliOutputSink();
345
- const onQr = (event) => {
346
- if (config.qrLogSkip || !event.details?.qr) return;
347
- sink.write({
348
- level: "info",
349
- message: "Open WhatsApp on your sending phone: Linked Devices → Link a Device, then scan this QR code."
350
- });
351
- sink.qr({
352
- qr: event.details.qr,
353
- sessionId: config.sessionId
354
- });
355
- };
356
- const onLinkCode = (event) => {
357
- if (event.details?.linkCode && !config.qrLogSkip) sink.write({
358
- level: "info",
359
- message: `Enter this link code on your sending phone: ${event.details.linkCode}`
360
- });
361
- };
362
- core.events.on("launch.auth.qr.generated", onQr);
363
- core.events.on("launch.auth.linkCode.generated", onLinkCode);
364
- let client;
365
- try {
366
- client = new _open_wa_client.Client({
367
- client: core,
368
- transport: core.getTransport()
369
- });
370
- await client.start();
371
- if (core.getState() !== "READY" || !core.getReadiness().exposureSafe) throw new Error("WhatsApp startup finished without a messaging-ready session.");
372
- return client;
373
- } catch (error) {
374
- try {
375
- if (client) await client.stop("startup-failure");
376
- else await core.stop("startup-failure");
377
- } catch {}
378
- throw error;
379
- } finally {
380
- core.events.off("launch.auth.qr.generated", onQr);
381
- core.events.off("launch.auth.linkCode.generated", onLinkCode);
382
- }
146
+ //#region src/index.ts
147
+ async function ensureBrowser(...args) {
148
+ const { ensureBrowser: provisionBrowser } = await import("@open-wa/driver-puppeteer");
149
+ return provisionBrowser(...args);
383
150
  }
384
151
  //#endregion
385
152
  exports.APILifecycleManager = APILifecycleManager;
386
- Object.defineProperty(exports, "Config", {
153
+ Object.defineProperty(exports, "ConfigSchema", {
387
154
  enumerable: true,
388
155
  get: function() {
389
- return _open_wa_config.Config;
156
+ return _open_wa_config.ConfigSchema;
390
157
  }
391
158
  });
392
- Object.defineProperty(exports, "ConfigSchema", {
159
+ Object.defineProperty(exports, "MessageAck", {
393
160
  enumerable: true,
394
161
  get: function() {
395
- return _open_wa_config.ConfigSchema;
162
+ return _open_wa_schema.MessageAck;
396
163
  }
397
164
  });
398
165
  exports.SessionArchiveManager = SessionArchiveManager;
166
+ Object.defineProperty(exports, "SimpleListener", {
167
+ enumerable: true,
168
+ get: function() {
169
+ return _open_wa_schema.SimpleListener;
170
+ }
171
+ });
399
172
  exports.WAServer = require_cli_runtime.WAServer;
400
- exports.create = create;
173
+ exports.create = require_cli_runtime.create;
401
174
  Object.defineProperty(exports, "createApiMiddleware", {
402
175
  enumerable: true,
403
176
  get: function() {
@@ -417,18 +190,26 @@ Object.defineProperty(exports, "createClient", {
417
190
  }
418
191
  });
419
192
  exports.createConsoleOutputSink = require_cli_runtime.createConsoleOutputSink;
420
- Object.defineProperty(exports, "ensureBrowser", {
193
+ exports.ensureBrowser = ensureBrowser;
194
+ Object.defineProperty(exports, "ev", {
421
195
  enumerable: true,
422
196
  get: function() {
423
- return _open_wa_driver_puppeteer.ensureBrowser;
197
+ return _open_wa_core.ev;
424
198
  }
425
199
  });
426
200
  exports.getCliOutputSink = require_cli_runtime.getCliOutputSink;
201
+ Object.defineProperty(exports, "onGlobalEvent", {
202
+ enumerable: true,
203
+ get: function() {
204
+ return _open_wa_core.onGlobalEvent;
205
+ }
206
+ });
427
207
  exports.parseCliArgs = require_cli_runtime.parseCliArgs;
428
208
  exports.resetCliOutputSink = require_cli_runtime.resetCliOutputSink;
429
209
  exports.runCli = require_cli_runtime.main;
430
210
  exports.setCliOutputSink = require_cli_runtime.setCliOutputSink;
431
211
  exports.startCli = require_cli_runtime.start;
212
+ var _open_wa_client = require("@open-wa/client");
432
213
  Object.keys(_open_wa_client).forEach(function(k) {
433
214
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
434
215
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["createLogger","LocalSessionCompression","S3SyncManager","join","dirname","getCliOutputSink","WAServer","existsSync","readFileSync","dirname","LightpandaDriver","PuppeteerDriver","createHash","realpathSync","resolve","homedir","resolveConfig","createCoreClient","getCliOutputSink","Client"],"sources":["../src/session/SessionArchiveManager.ts","../src/server/lifecycle-manager.ts","../src/runtime-client.ts"],"sourcesContent":["import { dirname, join } from 'node:path';\nimport type { Config } from '@open-wa/config';\nimport { createLogger } from '@open-wa/logger';\nimport { LocalSessionCompression, S3SyncManager, type S3Config } from '@open-wa/session-sync';\n\nexport interface SessionArchiveManagerConfig {\n sessionId: string;\n dataDir: string;\n s3Config: S3Config;\n syncInterval?: number;\n watchLocalChanges?: boolean;\n}\n\nexport class SessionArchiveManager {\n private readonly logger = createLogger({ component: 'SessionArchiveManager' });\n private localCompression?: LocalSessionCompression;\n private s3Sync?: S3SyncManager;\n private syncTimer?: NodeJS.Timeout;\n private started = false;\n\n constructor(private readonly config: SessionArchiveManagerConfig) {\n this.logger.info('session_archive_manager_initialized', { sessionId: config.sessionId });\n }\n\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n\n this.localCompression = new LocalSessionCompression({\n sessionPath: this.config.dataDir,\n sessionId: this.config.sessionId,\n outputPath: this.archivePath,\n intervalMs: this.config.syncInterval,\n });\n if (this.config.watchLocalChanges !== false) {\n this.localCompression.start();\n this.logger.info('local_session_compression_started');\n }\n\n this.s3Sync = new S3SyncManager(this.config.s3Config);\n this.startPeriodicSync();\n this.logger.info('s3_session_sync_started');\n }\n\n async stop(): Promise<void> {\n if (this.syncTimer) {\n clearInterval(this.syncTimer);\n this.syncTimer = undefined;\n }\n\n this.localCompression?.stop();\n this.localCompression = undefined;\n this.s3Sync = undefined;\n this.started = false;\n this.logger.info('session_archive_manager_stopped');\n }\n\n async backupSession(): Promise<string | null> {\n if (!this.s3Sync || !this.localCompression) {\n this.logger.warn('session_archive_manager_not_started');\n return null;\n }\n\n try {\n await this.localCompression.compress();\n const filename = await this.s3Sync.backupSession(this.archivePath);\n this.logger.info('session_backed_up', { filename });\n return filename;\n } catch (error) {\n this.logger.error('session_backup_failed', { error });\n throw error;\n }\n }\n\n async restoreSession(filename: string): Promise<void> {\n if (!this.s3Sync) {\n throw new Error('Session archive manager is not started');\n }\n\n const restored = await this.s3Sync.restoreSession(filename, this.config.dataDir);\n if (!restored) {\n throw new Error(`Failed to restore session backup: ${filename}`);\n }\n this.logger.info('session_restored', { filename });\n }\n\n async getSessionBackupUrl(filename: string, expiresIn = 3600): Promise<string | null> {\n if (!this.s3Sync) {\n return null;\n }\n\n return this.s3Sync.getDownloadUrl(filename, expiresIn);\n }\n\n static createFromConfig(config: Config): SessionArchiveManager {\n if (!config.legacyDataDirAuth) {\n throw new Error('Profile archives require legacyDataDirAuth: true; compact sessions sync through the client');\n }\n if (!config.s3Sync) {\n throw new Error('Session archive management requires s3Sync configuration');\n }\n\n return new SessionArchiveManager({\n sessionId: config.sessionId,\n dataDir: config.userDataDir || config.sessionDataPath || './.wwebjs',\n s3Config: config.s3Sync,\n syncInterval: config.s3Sync.syncInterval,\n watchLocalChanges: config.s3Sync.enableLocalCompression !== false,\n });\n }\n\n private get archivePath(): string {\n return join(dirname(this.config.dataDir), `${this.config.sessionId}.data.zst`);\n }\n\n private startPeriodicSync(): void {\n if (!this.s3Sync || this.syncTimer) return;\n\n this.syncTimer = setInterval(() => {\n void this.backupSession().catch((error) => {\n this.logger.error('periodic_session_sync_failed', { error });\n });\n }, this.config.syncInterval ?? 600_000);\n this.syncTimer.unref();\n }\n}\n","import { WAServer } from './hono-server';\nimport type { Config } from '@open-wa/config';\nimport { SessionArchiveManager } from '../session/SessionArchiveManager';\nimport { getCliOutputSink } from '../cli/output-sink';\n\nexport class APILifecycleManager {\n private config: Config;\n private server?: WAServer;\n private sessionArchiveManager?: SessionArchiveManager;\n // @ts-ignore\n private _sessionConnected: boolean = false;\n\n constructor(config: Config) {\n this.config = config;\n \n // Compact checkpoints are synced by the client; profile archives are legacy-only.\n if (config.legacyDataDirAuth && config.s3Sync) {\n this.sessionArchiveManager = SessionArchiveManager.createFromConfig(config);\n }\n }\n\n public async initialize(): Promise<void> {\n const sink = getCliOutputSink();\n switch (this.config.apiLifecycle) {\n case 'immediate':\n sink.status({ phase: 'server.starting', sessionId: this.config.sessionId, detail: 'Starting full API immediately' });\n await this.startFullAPI();\n break;\n case 'post-connection':\n this.waitForConnection();\n break;\n case 'hybrid':\n sink.status({ phase: 'server.starting', sessionId: this.config.sessionId, detail: 'Starting minimal API (QR only)' });\n await this.startMinimalAPI();\n break;\n }\n \n // Start session manager after all other initialization\n if (this.sessionArchiveManager) {\n await this.sessionArchiveManager.start();\n }\n }\n\n private async waitForConnection(): Promise<void> {\n getCliOutputSink().write({ level: 'info', message: 'Waiting for session connection before starting API...' });\n // This will be called by the orchestrator or main entry point when session connects\n }\n\n private async startFullAPI(): Promise<void> {\n getCliOutputSink().write({ level: 'info', message: 'Starting full API immediately...' });\n this.server = new WAServer(this.config);\n await this.server.start();\n }\n\n private async startMinimalAPI(): Promise<void> {\n getCliOutputSink().write({ level: 'info', message: 'Starting minimal API (QR only)...' });\n \n // Create server with full config but we might restrict routes in the future\n // For now, hybrid mode just starts the server, but logic inside routes (like sendText)\n // should check if session is connected before execution.\n // In a more advanced implementation, we would only register public routes here.\n \n this.server = new WAServer(this.config);\n await this.server.start();\n }\n \n public async stop(): Promise<void> {\n // Stop session manager first\n if (this.sessionArchiveManager) {\n await this.sessionArchiveManager.stop();\n }\n \n // Then stop server\n if (this.server) {\n await this.server.stop();\n }\n }\n}\n","import { createClient as createCoreClient, type CreateClientOptions, type OpenWAEventMap } from '@open-wa/core';\nimport { Client } from '@open-wa/client';\nimport { resolveConfig, type PartialConfig, type Config, type TrackedConfig } from '@open-wa/config';\nimport { LightpandaDriver } from '@open-wa/driver-lightpanda';\nimport { PuppeteerDriver } from '@open-wa/driver-puppeteer';\nimport { chmodSync, existsSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs';\nimport { createHash } from 'node:crypto';\nimport { homedir } from 'node:os';\nimport { dirname, resolve } from 'node:path';\nimport { getCliOutputSink } from './cli/output-sink';\n\nexport interface ExecutablePathResolution {\n executablePath?: string;\n source:\n | 'config'\n | 'cache'\n | 'chrome_installation'\n | 'driver_default'\n | 'lightpanda_config'\n | 'lightpanda_sdk_default';\n warning?: string;\n}\n\nexport interface DriverSelection {\n driver: PuppeteerDriver | LightpandaDriver;\n engineLabel: 'Puppeteer' | 'Lightpanda';\n executableResolution: ExecutablePathResolution;\n preferLocalChrome: boolean;\n}\n\nfunction readChromePathCache(cacheFilePath: string): { executablePath?: string } | undefined {\n try {\n if (!existsSync(cacheFilePath)) {\n return undefined;\n }\n\n const raw = JSON.parse(readFileSync(cacheFilePath, 'utf8')) as { executablePath?: string };\n if (!raw || typeof raw !== 'object') {\n return undefined;\n }\n\n return {\n executablePath: typeof raw.executablePath === 'string' ? raw.executablePath : undefined,\n };\n } catch {\n return undefined;\n }\n}\n\nfunction writeChromePathCache(executablePath: string, cacheFilePath: string): void {\n mkdirSync(dirname(cacheFilePath), { recursive: true });\n writeFileSync(cacheFilePath, JSON.stringify({ executablePath, updatedAt: new Date().toISOString() }, null, 2), 'utf8');\n}\n\nfunction clearChromePathCache(cacheFilePath: string): void {\n if (existsSync(cacheFilePath)) {\n rmSync(cacheFilePath, { force: true });\n }\n}\n\nfunction isUsableExecutablePath(executablePath?: string): executablePath is string {\n return !!executablePath && existsSync(executablePath);\n}\n\nfunction getExplicitUseChromePreference(rawConfigs?: TrackedConfig['rawConfigs']): boolean | undefined {\n const explicitConfigSources = [\n rawConfigs?.file,\n rawConfigs?.env,\n rawConfigs?.cli,\n rawConfigs?.programmatic,\n ];\n\n for (let index = explicitConfigSources.length - 1; index >= 0; index -= 1) {\n const source = explicitConfigSources[index];\n if (source?.useChrome !== undefined) {\n return source.useChrome;\n }\n }\n\n return undefined;\n}\n\nexport function shouldPreferLocalChrome(\n config: Config,\n rawConfigs?: TrackedConfig['rawConfigs'],\n defaultPreference = true,\n): boolean {\n if (config.useLightpanda) {\n return false;\n }\n\n if (config.executablePath) {\n return false;\n }\n\n const explicitUseChrome = getExplicitUseChromePreference(rawConfigs);\n if (explicitUseChrome !== undefined) {\n return explicitUseChrome;\n }\n\n return defaultPreference;\n}\n\nexport async function resolveExecutablePath(\n config: Config,\n options: {\n preferLocalChrome?: boolean;\n cacheFilePath: string;\n }\n): Promise<ExecutablePathResolution> {\n if (config.executablePath) {\n return {\n executablePath: config.executablePath,\n source: 'config',\n };\n }\n\n const preferLocalChrome = options.preferLocalChrome ?? config.useChrome;\n if (!preferLocalChrome) {\n return {\n source: 'driver_default',\n };\n }\n\n const cachedPath = readChromePathCache(options.cacheFilePath)?.executablePath;\n if (isUsableExecutablePath(cachedPath)) {\n return {\n executablePath: cachedPath,\n source: 'cache',\n };\n }\n\n if (cachedPath) {\n clearChromePathCache(options.cacheFilePath);\n }\n\n const { Launcher } = await import('chrome-launcher');\n const detectedPath = Launcher.getInstallations().find((installationPath) => isUsableExecutablePath(installationPath));\n\n if (detectedPath) {\n writeChromePathCache(detectedPath, options.cacheFilePath);\n return {\n executablePath: detectedPath,\n source: 'chrome_installation',\n };\n }\n\n clearChromePathCache(options.cacheFilePath);\n\n return {\n source: 'driver_default',\n warning: 'Chrome resolution warning: no valid local Chrome installation was found. Falling back to Puppeteer/default driver browser resolution.',\n };\n}\n\nexport function resolveLightpandaExecutablePath(config: Config): ExecutablePathResolution {\n const executablePath = config.lightpanda?.executablePath;\n if (executablePath) {\n return {\n executablePath,\n source: 'lightpanda_config',\n };\n }\n\n return {\n source: 'lightpanda_sdk_default',\n };\n}\n\nexport async function selectRuntimeDriver(\n config: Config,\n options: {\n rawConfigs?: TrackedConfig['rawConfigs'];\n cacheFilePath: string;\n defaultPreferLocalChrome?: boolean;\n }\n): Promise<DriverSelection> {\n if (config.useLightpanda) {\n return {\n driver: new LightpandaDriver(),\n engineLabel: 'Lightpanda',\n executableResolution: resolveLightpandaExecutablePath(config),\n preferLocalChrome: false,\n };\n }\n\n const preferLocalChrome = shouldPreferLocalChrome(config, options.rawConfigs, options.defaultPreferLocalChrome ?? true);\n const executableResolution = await resolveExecutablePath(config, {\n preferLocalChrome,\n cacheFilePath: options.cacheFilePath,\n });\n\n return {\n driver: new PuppeteerDriver(),\n engineLabel: 'Puppeteer',\n executableResolution,\n preferLocalChrome,\n };\n}\n\nexport function toCreateClientOptions(\n config: Config,\n driverSelection: DriverSelection,\n options: {\n debug?: boolean;\n } = {},\n): CreateClientOptions {\n return {\n sessionId: config.sessionId,\n driver: driverSelection.driver,\n deleteSessionDataOnLogout: config.deleteSessionDataOnLogout,\n killClientOnLogout: config.killClientOnLogout,\n legacyDataDirAuth: config.legacyDataDirAuth,\n sessionDataPath: config.sessionDataPath,\n sessionData: config.sessionData,\n skipSessionSave: config.skipSessionSave,\n sessionDataBucketAuth: config.sessionDataBucketAuth,\n s3Sync: config.s3Sync,\n debug: options.debug ?? (config.logLevel === 'debug' || config.logConsole),\n headless: config.headless,\n qrTimeoutMs: typeof config.qrTimeout === 'number' ? config.qrTimeout * 1000 : undefined,\n authTimeoutMs: typeof config.authTimeout === 'number' ? config.authTimeout * 1000 : undefined,\n executablePath: driverSelection.executableResolution.executablePath,\n browserArgs: config.chromiumArgs,\n browser: config.browser,\n allowDangerousBrowserArgs: config.allowDangerousBrowserArgs,\n userDataDir: config.userDataDir,\n ephemeral: config.ephemeral,\n linkCode: config.linkCode,\n qrMax: config.qrMax,\n oorTimeoutMs: config.oorTimeout * 1000,\n logConsole: config.logConsole,\n logConsoleErrors: config.logConsoleErrors,\n blockCrashLogs: config.blockCrashLogs,\n blockAssets: config.blockAssets,\n safeMode: config.safeMode,\n lightpanda: config.useLightpanda ? config.lightpanda : undefined,\n licenseKey: config.licenseKey as any,\n patchConfig: { ghPatch: config.ghPatch, cachedPatch: config.cachedPatch },\n };\n}\n\n/** Options for the ready-to-use messaging client. */\nexport type CreateOptions = Omit<PartialConfig, 's3Sync'> & {\n s3Sync?: Omit<NonNullable<PartialConfig['s3Sync']>, 'region' | 'syncInterval'> & {\n region?: string;\n syncInterval?: number;\n };\n /** Override the default Puppeteer driver. */\n driver?: CreateClientOptions['driver'];\n};\n\n/** Private profile storage, stable for this project directory and session name. */\nfunction privateSessionDirectory(sessionId: string): string {\n const project = createHash('sha256').update(realpathSync(process.cwd())).digest('hex').slice(0, 24);\n const session = createHash('sha256').update(sessionId).digest('hex').slice(0, 24);\n const root = resolve(homedir(), '.open-wa', 'sessions');\n const directory = resolve(root, project, session);\n mkdirSync(directory, { recursive: true, mode: 0o700 });\n // Protect existing directories too; Chromium stores authentication here.\n for (const path of [root, dirname(directory), directory]) chmodSync(path, 0o700);\n return directory;\n}\n\n/** Start WhatsApp, display QR login when needed, and return a ready messaging client. */\nexport async function create(options: CreateOptions = {}): Promise<Client> {\n const { driver, sessionData, sessionDataBucketAuth, s3Sync, ...configOverrides } = options;\n const { config, rawConfigs } = await resolveConfig({\n programmaticOverrides: {\n qrTimeout: 0, ...configOverrides,\n // Session seeds and bucket credentials bypass tracked/debug config.\n },\n skipConfigFile: true,\n skipEnv: true,\n includeRawConfigs: true,\n });\n\n const driverSelection = await selectRuntimeDriver(config, {\n rawConfigs,\n cacheFilePath: resolve(process.cwd(), '.open-wa', 'chrome-executable-path.json'),\n defaultPreferLocalChrome: false,\n });\n\n const coreOptions = toCreateClientOptions(config, driverSelection);\n if (driver) coreOptions.driver = driver;\n coreOptions.sessionData = sessionData;\n coreOptions.sessionDataBucketAuth = sessionDataBucketAuth;\n coreOptions.s3Sync = s3Sync;\n if (config.legacyDataDirAuth && !config.ephemeral && configOverrides.userDataDir === undefined && configOverrides.sessionDataPath === undefined) {\n coreOptions.userDataDir = privateSessionDirectory(config.sessionId);\n coreOptions.sessionDataPath = coreOptions.userDataDir;\n }\n\n const core = await createCoreClient(coreOptions);\n const sink = getCliOutputSink();\n const onQr = (event: OpenWAEventMap['launch.auth.qr.generated']) => {\n if (config.qrLogSkip || !event.details?.qr) return;\n sink.write({ level: 'info', message: 'Open WhatsApp on your sending phone: Linked Devices → Link a Device, then scan this QR code.' });\n sink.qr({ qr: event.details.qr, sessionId: config.sessionId });\n };\n const onLinkCode = (event: OpenWAEventMap['launch.auth.linkCode.generated']) => {\n if (event.details?.linkCode && !config.qrLogSkip) {\n sink.write({ level: 'info', message: `Enter this link code on your sending phone: ${event.details.linkCode}` });\n }\n };\n core.events.on('launch.auth.qr.generated', onQr);\n core.events.on('launch.auth.linkCode.generated', onLinkCode);\n let client: Client | undefined;\n try {\n client = new Client({ client: core, transport: core.getTransport() });\n await client.start();\n if (core.getState() !== 'READY' || !core.getReadiness().exposureSafe) {\n throw new Error('WhatsApp startup finished without a messaging-ready session.');\n }\n return client;\n } catch (error) {\n try {\n if (client) await client.stop('startup-failure');\n else await core.stop('startup-failure');\n } catch {\n // Keep the startup failure as the actionable error.\n }\n throw error;\n } finally {\n core.events.off('launch.auth.qr.generated', onQr);\n core.events.off('launch.auth.linkCode.generated', onLinkCode);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["getCliOutputSink","WAServer","createLogger","LocalSessionCompression","S3SyncManager","join","dirname"],"sources":["../src/server/lifecycle-manager.ts","../src/session/SessionArchiveManager.ts","../src/index.ts"],"sourcesContent":["import { WAServer } from './hono-server';\nimport type { Config } from '@open-wa/config';\nimport { getCliOutputSink } from '../cli/output-sink';\n\nexport class APILifecycleManager {\n private config: Config;\n private server?: WAServer;\n // @ts-ignore\n private _sessionConnected: boolean = false;\n\n constructor(config: Config) {\n this.config = config;\n }\n\n public async initialize(): Promise<void> {\n const sink = getCliOutputSink();\n switch (this.config.apiLifecycle) {\n case 'immediate':\n sink.status({ phase: 'server.starting', sessionId: this.config.sessionId, detail: 'Starting full API immediately' });\n await this.startFullAPI();\n break;\n case 'post-connection':\n this.waitForConnection();\n break;\n case 'hybrid':\n sink.status({ phase: 'server.starting', sessionId: this.config.sessionId, detail: 'Starting minimal API (QR only)' });\n await this.startMinimalAPI();\n break;\n }\n }\n\n private async waitForConnection(): Promise<void> {\n getCliOutputSink().write({ level: 'info', message: 'Waiting for session connection before starting API...' });\n // This will be called by the orchestrator or main entry point when session connects\n }\n\n private async startFullAPI(): Promise<void> {\n getCliOutputSink().write({ level: 'info', message: 'Starting full API immediately...' });\n this.server = new WAServer(this.config);\n await this.server.start();\n }\n\n private async startMinimalAPI(): Promise<void> {\n getCliOutputSink().write({ level: 'info', message: 'Starting minimal API (QR only)...' });\n \n // Create server with full config but we might restrict routes in the future\n // For now, hybrid mode just starts the server, but logic inside routes (like sendText)\n // should check if session is connected before execution.\n // In a more advanced implementation, we would only register public routes here.\n \n this.server = new WAServer(this.config);\n await this.server.start();\n }\n \n public async stop(): Promise<void> {\n if (this.server) {\n await this.server.stop();\n }\n }\n}\n","import { dirname, join } from 'node:path';\nimport { createLogger } from '@open-wa/logger';\nimport { LocalSessionCompression, S3SyncManager, type S3Config } from '@open-wa/session-sync';\n\nexport interface SessionArchiveManagerConfig {\n sessionId: string;\n dataDir: string;\n s3Config: S3Config;\n syncInterval?: number;\n watchLocalChanges?: boolean;\n}\n\nexport class SessionArchiveManager {\n private readonly logger = createLogger({ component: 'SessionArchiveManager' });\n private localCompression?: LocalSessionCompression;\n private s3Sync?: S3SyncManager;\n private syncTimer?: NodeJS.Timeout;\n private started = false;\n\n constructor(private readonly config: SessionArchiveManagerConfig) {\n this.logger.info('session_archive_manager_initialized', { sessionId: config.sessionId });\n }\n\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n\n this.localCompression = new LocalSessionCompression({\n sessionPath: this.config.dataDir,\n sessionId: this.config.sessionId,\n outputPath: this.archivePath,\n intervalMs: this.config.syncInterval,\n });\n if (this.config.watchLocalChanges !== false) {\n this.localCompression.start();\n this.logger.info('local_session_compression_started');\n }\n\n this.s3Sync = new S3SyncManager(this.config.s3Config);\n this.startPeriodicSync();\n this.logger.info('s3_session_sync_started');\n }\n\n async stop(): Promise<void> {\n if (this.syncTimer) {\n clearInterval(this.syncTimer);\n this.syncTimer = undefined;\n }\n\n this.localCompression?.stop();\n this.localCompression = undefined;\n this.s3Sync = undefined;\n this.started = false;\n this.logger.info('session_archive_manager_stopped');\n }\n\n async backupSession(): Promise<string | null> {\n if (!this.s3Sync || !this.localCompression) {\n this.logger.warn('session_archive_manager_not_started');\n return null;\n }\n\n try {\n await this.localCompression.compress();\n const filename = await this.s3Sync.backupSession(this.archivePath);\n this.logger.info('session_backed_up', { filename });\n return filename;\n } catch (error) {\n this.logger.error('session_backup_failed', { error });\n throw error;\n }\n }\n\n async restoreSession(filename: string): Promise<void> {\n if (!this.s3Sync) {\n throw new Error('Session archive manager is not started');\n }\n\n const restored = await this.s3Sync.restoreSession(filename, this.config.dataDir);\n if (!restored) {\n throw new Error(`Failed to restore session backup: ${filename}`);\n }\n this.logger.info('session_restored', { filename });\n }\n\n async getSessionBackupUrl(filename: string, expiresIn = 3600): Promise<string | null> {\n if (!this.s3Sync) {\n return null;\n }\n\n return this.s3Sync.getDownloadUrl(filename, expiresIn);\n }\n\n private get archivePath(): string {\n return join(dirname(this.config.dataDir), `${this.config.sessionId}.data.zst`);\n }\n\n private startPeriodicSync(): void {\n if (!this.s3Sync || this.syncTimer) return;\n\n this.syncTimer = setInterval(() => {\n void this.backupSession().catch((error) => {\n this.logger.error('periodic_session_sync_failed', { error });\n });\n }, this.config.syncInterval ?? 600_000);\n this.syncTimer.unref();\n }\n}\n","export { WAServer } from './server/hono-server';\nexport { APILifecycleManager } from './server/lifecycle-manager';\nexport { SessionArchiveManager } from './session/SessionArchiveManager';\nexport { main as runCli, start as startCli, parseCliArgs } from './cli-runtime';\nexport type { CliRuntimeResult } from './cli-runtime';\nexport { createConsoleOutputSink, getCliOutputSink, resetCliOutputSink, setCliOutputSink } from './cli/output-sink';\nexport type { CliOutputEntry, CliOutputLevel, CliOutputSink, CliQrPayload, CliStatusUpdate } from './cli/output-sink';\nexport { ConfigSchema } from '@open-wa/config';\nexport type { Config } from '@open-wa/config';\nexport { SimpleListener, MessageAck } from '@open-wa/schema';\nexport { createApiServer, createApiMiddleware } from '@open-wa/api';\nexport * from '@open-wa/client';\nexport { createClient } from '@open-wa/core';\nexport { ev, onGlobalEvent } from '@open-wa/core';\nexport type { CreateClientOptions, OpenWAClient, PortableSessionStatus } from '@open-wa/core';\nexport { create } from './runtime-client';\nexport type { CreateOptions } from './runtime-client';\nexport async function ensureBrowser(...args: Parameters<typeof import('@open-wa/driver-puppeteer').ensureBrowser>): Promise<string> {\n const { ensureBrowser: provisionBrowser } = await import('@open-wa/driver-puppeteer');\n return provisionBrowser(...args);\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -3,15 +3,13 @@ import { Client } from "@open-wa/client";
3
3
  import { createApiMiddleware, createApiServer } from "@open-wa/api";
4
4
  import { Config, Config as Config$1, ConfigSchema, PartialConfig } from "@open-wa/config";
5
5
  import { S3Config } from "@open-wa/session-sync";
6
- import { CreateClientOptions, CreateClientOptions as CreateClientOptions$1, OpenWAClient, PortableSessionStatus, createClient } from "@open-wa/core";
7
- import "@open-wa/driver-lightpanda";
8
- import { ensureBrowser } from "@open-wa/driver-puppeteer";
6
+ import { MessageAck, SimpleListener } from "@open-wa/schema";
7
+ import { CreateClientOptions, CreateClientOptions as CreateClientOptions$1, OpenWAClient, PortableSessionStatus, createClient, ev, onGlobalEvent } from "@open-wa/core";
9
8
  export * from "@open-wa/client";
10
9
  //#region src/server/lifecycle-manager.d.ts
11
10
  export declare class APILifecycleManager {
12
11
  private config;
13
12
  private server?;
14
- private sessionArchiveManager?;
15
13
  private _sessionConnected;
16
14
  constructor(config: Config$1);
17
15
  initialize(): Promise<void>;
@@ -42,7 +40,6 @@ export declare class SessionArchiveManager {
42
40
  backupSession(): Promise<string | null>;
43
41
  restoreSession(filename: string): Promise<void>;
44
42
  getSessionBackupUrl(filename: string, expiresIn?: number): Promise<string | null>;
45
- static createFromConfig(config: Config$1): SessionArchiveManager;
46
43
  private get archivePath();
47
44
  private startPeriodicSync;
48
45
  }
@@ -67,6 +64,7 @@ interface CliOutputSink {
67
64
  write(entry: CliOutputEntry): void;
68
65
  status(update: CliStatusUpdate): void;
69
66
  qr(payload: CliQrPayload): void;
67
+ promptChoice?(question: string, choices: readonly string[]): Promise<number>;
70
68
  }
71
69
  export declare function createConsoleOutputSink(): CliOutputSink;
72
70
  export declare function getCliOutputSink(): CliOutputSink;
@@ -74,7 +72,8 @@ export declare function setCliOutputSink(sink: CliOutputSink): void;
74
72
  export declare function resetCliOutputSink(): void;
75
73
  //#endregion
76
74
  //#region src/runtime-client.d.ts
77
- type CreateOptions = Omit<PartialConfig, 's3Sync'> & {
75
+ type CreateOptions = Omit<PartialConfig, 's3Sync' | 'calling'> & {
76
+ calling?: import('@open-wa/schema').CallingOptions;
78
77
  s3Sync?: Omit<NonNullable<PartialConfig['s3Sync']>, 'region' | 'syncInterval'> & {
79
78
  region?: string;
80
79
  syncInterval?: number;
@@ -83,5 +82,8 @@ type CreateOptions = Omit<PartialConfig, 's3Sync'> & {
83
82
  };
84
83
  export declare function create(options?: CreateOptions): Promise<Client>;
85
84
  //#endregion
86
- export { type CliOutputEntry, type CliOutputLevel, type CliOutputSink, type CliQrPayload, type CliRuntimeResult, type CliStatusUpdate, Config, ConfigSchema, type CreateClientOptions, type CreateOptions, type OpenWAClient, type PortableSessionStatus, WAServer, createApiMiddleware, createApiServer, createClient, ensureBrowser, parseCliArgs, main as runCli, start as startCli };
85
+ //#region src/index.d.ts
86
+ export declare function ensureBrowser(...args: Parameters<typeof import('@open-wa/driver-puppeteer').ensureBrowser>): Promise<string>;
87
+ //#endregion
88
+ export { type CliOutputEntry, type CliOutputLevel, type CliOutputSink, type CliQrPayload, type CliRuntimeResult, type CliStatusUpdate, type Config, ConfigSchema, type CreateClientOptions, type CreateOptions, MessageAck, type OpenWAClient, type PortableSessionStatus, SimpleListener, WAServer, createApiMiddleware, createApiServer, createClient, ev, onGlobalEvent, parseCliArgs, main as runCli, start as startCli };
87
89
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":["Config","Config","CreateClientOptions"],"sources":["../src/server/lifecycle-manager.ts","../src/session/SessionArchiveManager.ts","../src/cli/output-sink.ts","../src/runtime-client.ts"],"mappings":";;;;;;;;;;qBAKa;UACD;UACA;UACA;UAEA;EAER,YAAY,QAAQA;EASP,cAAc;UAsBb;UAKA;UAMA;EAYD,QAAQ;;;;UC7DR;EACb;EACA;EACA,UAAU;EACV;EACA;;qBAGS;mBAOoB;mBANZ;UACT;UACA;UACA;UACA;EAER,YAA6B,QAAQ;EAI/B,SAAS;EAoBT,QAAQ;EAaR,iBAAiB;EAiBjB,eAAe,mBAAmB;EAYlC,oBAAoB,kBAAkB,qBAAmB;SAQxD,iBAAiB,QAAQC,WAAS;cAiB7B;UAIJ;;;;KCjHA;UAEK;EACf,OAAO;EACP;EACA,OAAO;;UAGQ;EACf;EAgBA;EACA;;UAGe;EACf;EACA;;UAGe;EACf,MAAM,OAAO;EACb,OAAO,QAAQ;EACf,GAAG,SAAS;;wBAiBE,2BAA2B;wBAkB3B,oBAAoB;wBAIpB,iBAAiB,MAAM;wBAIvB;;;KCiKJ,gBAAgB,KAAK;EAC7B,SAAS,KAAK,YAAY;IACtB;IACA;;EAGJ,SAASC;;wBAgBS,OAAO,UAAS,gBAAqB,QAAQ"}
1
+ {"version":3,"file":"index.d.cts","names":["Config","CreateClientOptions"],"sources":["../src/server/lifecycle-manager.ts","../src/session/SessionArchiveManager.ts","../src/cli/output-sink.ts","../src/runtime-client.ts","../src/index.ts"],"mappings":";;;;;;;;;qBAIa;UACD;UACA;UAEA;EAER,YAAY,QAAQA;EAIP,cAAc;UAiBb;UAKA;UAMA;EAYD,QAAQ;;;;UClDR;EACb;EACA;EACA,UAAU;EACV;EACA;;qBAGS;mBAOoB;mBANZ;UACT;UACA;UACA;UACA;EAER,YAA6B,QAAQ;EAI/B,SAAS;EAoBT,QAAQ;EAaR,iBAAiB;EAiBjB,eAAe,mBAAmB;EAYlC,oBAAoB,kBAAkB,qBAAmB;cAQnD;UAIJ;;;;KC/FA;UAEK;EACf,OAAO;EACP;EACA,OAAO;;UAGQ;EACf;EAgBA;EACA;;UAGe;EACf;EACA;;UAGe;EACf,MAAM,OAAO;EACb,OAAO,QAAQ;EACf,GAAG,SAAS;EACZ,cAAc,kBAAkB,6BAA6B;;wBAyC/C,2BAA2B;wBAmB3B,oBAAoB;wBAIpB,iBAAiB,MAAM;wBAIvB;;;KC6OJ,gBAAgB,KAAK;EAC7B,oCAAoC;EACpC,SAAS,KAAK,YAAY;IACtB;IACA;;EAGJ,SAASC;;wBAIS,OAAO,UAAS,gBAAqB,QAAQ;;;wBCnV7C,iBAAiB,MAAM,sDAAsD,iBAAiB"}
@@ -1,9 +1,9 @@
1
- const require_cli_runtime = require("./cli-runtime-BHx1nVhT.cjs");
1
+ const require_cli_runtime = require("./cli-runtime-BRj_LUIT.cjs");
2
2
  let node_path = require("node:path");
3
- let node_child_process = require("node:child_process");
4
3
  let node_fs_promises = require("node:fs/promises");
4
+ let node_child_process = require("node:child_process");
5
5
  //#region package.json
6
- var version = "5.3.0";
6
+ var version = "5.5.0";
7
7
  //#endregion
8
8
  //#region src/cli/init.ts
9
9
  const starter = `import { create } from '@open-wa/wa-automate';
@@ -111,4 +111,4 @@ async function initProject(args) {
111
111
  //#endregion
112
112
  exports.initProject = initProject;
113
113
 
114
- //# sourceMappingURL=init-CTh6gc8w.cjs.map
114
+ //# sourceMappingURL=init-CUhC5Wkq.cjs.map