UNPKG

node-notifier

Version:

A Node.js module for sending notifications on native Mac, Windows (post and pre 8) and Linux (or Growl as fallback)

91 lines (90 loc) • 3.5 kB
import callableClass from "../lib/callableClass.js"; import utils from "../lib/utils.js"; import { vendorPath } from "../lib/vendor.js"; import Notifier$1 from "./balloon.js"; import os from "node:os"; import { EventEmitter } from "node:events"; import crypto from "node:crypto"; // src/notifiers/toaster.ts const notifier = vendorPath("snoreToast", "snoretoast"); let fallback; const PIPE_NAME = "notifierPipe"; const PIPE_PATH_PREFIX = "\\\\.\\pipe\\"; const PIPE_PATH_PREFIX_WSL = "/tmp/"; var WindowsToaster = class extends EventEmitter { options; #notify; constructor(options) { super(); this.options = utils.clone(options || {}); } get notify() { this.#notify ??= notifyRaw.bind(this); return this.#notify; } }; const Notifier = callableClass(WindowsToaster); function noop() {} function parseResult(data) { if (!data) return {}; const result = {}; for (const cur of data.split(";")) { const [key, value, ...rest] = cur.split("="); if (key !== void 0 && value !== void 0 && !rest.length) result[key] = value; } return result; } function getPipeName() { return `${utils.isWSL() ? PIPE_PATH_PREFIX_WSL : PIPE_PATH_PREFIX}${PIPE_NAME}-${crypto.randomUUID()}`; } function notifyRaw(notification, userCallback) { let options = typeof notification === "string" ? { title: "node-notifier", message: notification } : utils.clone(notification || {}); const callback = userCallback || noop; const is64Bit = os.arch() === "x64"; let resultChunks = []; const server = { namedPipe: getPipeName() }; if (typeof callback !== "function") throw new TypeError(`The second argument must be a function callback. You have passed ${typeof callback}`); const snoreToastResultParser = (err, callback) => { const result = parseResult(Buffer.concat(resultChunks).toString("utf16le")); if (result.action === "buttonClicked" && result.button) result.activationType = result.button; else if (result.action) result.activationType = result.action; if (err?.code === -1) callback(err, result); else callback(null, result); server.instance?.close(); }; const actionJackedCallback = (err) => snoreToastResultParser(err, utils.actionJackerDecorator(this, options, callback, (data) => data === "activate" ? "click" : data || false)); options.title = options.title || "Node Notification:"; if (options.message === void 0 && options.close === void 0 && options.remove === void 0) { callback(/* @__PURE__ */ new Error("Message or ID to close is required.")); return this; } if (String(options.application ?? "").startsWith("-")) { callback(/* @__PURE__ */ new Error("Application can not start with \"-\".")); return this; } if (!utils.isWin8() && !utils.isWSL() && this.options.withFallback) { fallback = fallback || new Notifier$1(this.options); return fallback.notify(options, callback); } utils.createNamedPipe(server).then((out) => { resultChunks = out; options.pipeName = server.namedPipe; const customPath = options.customPath || this.options.customPath; const localNotifier = customPath || `${notifier}-x${is64Bit ? "64" : "86"}.exe`; options = utils.mapToWin8(options); if (!customPath && !is64Bit) delete options.d; const argsList = utils.constructArgumentList(options, { explicitTrue: true, wrapper: "", keepNewlines: true, noEscape: true }); utils.fileCommand(localNotifier, argsList, actionJackedCallback); }); return this; } export { Notifier as default, Notifier as "module.exports" }; //# sourceMappingURL=toaster.js.map