"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MemoryPublisher = exports.MqttPublisher = exports.asError = void 0; exports.send = send; /** What was thrown, as an Error. */ const asError = (err) => (err instanceof Error ? err : new Error(String(err))); exports.asError = asError; /** * Publishes to the broker through the client the bridge has at the time: a new one after disconnect() and connect(), * none before connect() and after disconnect(). Without a client the publish is refused. With a client that lost * its connection mqtt.js keeps the message and sends it after the reconnect, and the publish resolves then. */ class MqttPublisher { constructor(client) { this.client = client; } publish(topic, message) { const client = this.client(); return new Promise((resolve) => { const failed = (err) => resolve({ ok: false, topic, error: (0, exports.asError)(err) }); if (!client) { failed(new Error(`nothing was published to ${topic}: the bridge is not connected, call connect() first`)); return; } try { client.publish(topic, JSON.stringify(message), (err) => (err ? failed(err) : resolve({ ok: true, topic }))); } catch (err) { failed(err); } }); } } exports.MqttPublisher = MqttPublisher; /** * Keeps what it is asked to publish, for tests and dry runs without a broker: * * const sent = new MemoryPublisher(); * device.publisher = sent; // or new Alex2MQTT(..., { publisher: sent }) and bridge.receive() * await device.getStatusMessage(token, true).addPowerControllerProp(PowerController.ON).send(); * sent.published[0] // { topic: "//alexaResponce", message: { event, context } } */ class MemoryPublisher { constructor() { /** Oldest first. The message is what a subscriber gets after JSON.parse. */ this.published = []; /** Set it and every publish fails with this error, as a publish to a broker that is gone does. */ this.failWith = null; } publish(topic, message) { if (this.failWith) return Promise.resolve({ ok: false, topic, error: this.failWith }); try { this.published.push({ topic, message: JSON.parse(JSON.stringify(message)) }); } catch (err) { return Promise.resolve({ ok: false, topic, error: (0, exports.asError)(err) }); } return Promise.resolve({ ok: true, topic }); } } exports.MemoryPublisher = MemoryPublisher; /** * send() as 1.x promises it: resolves with the topic, or with "" when nothing was published, and never rejects * (1.5.1 rejected, and a send() nobody caught killed the host on any broker hiccup). What went wrong goes to report: * the message cannot be built, the device is on no bridge, or the publish failed. */ async function send(publisher, topic, build, report) { let result; try { const message = build(); if (!publisher) { throw new Error(`nothing was published to ${topic}: the device is on no bridge, register it with addDevice() or registerDevice()`); } result = await publisher.publish(topic, message); } catch (err) { result = { ok: false, topic, error: (0, exports.asError)(err) }; } if (result.ok) return topic; if (report) report(result.error); return ""; }