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)

109 lines (108 loc) • 4.23 kB
import callableClass from "../lib/callableClass.js"; import utils from "../lib/utils.js"; import { vendorPath } from "../lib/vendor.js"; import Notifier$1 from "./growl.js"; import { EventEmitter } from "node:events"; // src/notifiers/notificationcenter.ts const notifier = vendorPath("mac.noindex/terminal-notifier.app/Contents/MacOS/terminal-notifier"); const errorMessageOsX = "You need macOS 10.14 or above to use NotificationCenter, or use Growl fallback with constructor option {withFallback: true}."; var NotificationCenter = class extends EventEmitter { options; /** Clears each waiting notification. Used by `clearAll`. */ _activeNotifications; #notify; constructor(options) { super(); this.options = utils.clone(options || {}); this._activeNotifications = /* @__PURE__ */ new Set(); } get notify() { this.#notify ??= notifyRaw.bind(this); return this.#notify; } /** * Kill all running terminal-notifier processes started by this instance, so * the application can exit without waiting for their timeouts. Callbacks of * cleared notifications are called without an error or response. */ clearAll() { for (const clear of this._activeNotifications) clear(); this._activeNotifications.clear(); } }; const Notifier = callableClass(NotificationCenter); let activeId = null; function noop() {} function notifyRaw(notification, userCallback) { const id = {}; let options = typeof notification === "string" ? { title: "node-notifier", message: notification } : utils.clone(notification || {}); activeId = id; const callback = userCallback || noop; if (typeof callback !== "function") throw new TypeError(`The second argument must be a function callback. You have passed ${typeof callback}`); const actionJackedCallback = utils.actionJackerDecorator(this, options, callback, (data) => { if (activeId !== id) return false; if (data === "activate") return "click"; if (data === "timeout") return "timeout"; if (data === "replied") return "replied"; return false; }); options = utils.mapToMac(options); if (!options.message && !options.group && !options.list && !options.remove) { callback(/* @__PURE__ */ new Error("Message, group, remove or list property is required.")); return this; } if (options.actions?.some((action) => String(action).startsWith("-"))) { callback(/* @__PURE__ */ new Error("Action titles can not start with \"-\".")); return this; } const argsList = constructArgumentList(options); if (utils.isMojaveOrLater()) { let finished = false; let cleared = false; const clear = () => { cleared = true; child.kill(); }; const child = utils.fileCommand(this.options.customPath || notifier, argsList, (err, stdout) => { finished = true; this._activeNotifications.delete(clear); if (cleared) return actionJackedCallback(null); const output = (stdout || "").trim(); if (err?.code === 6 && output === "@TIMEOUT") err = null; if (err instanceof Error) return actionJackedCallback(err, stdout); const response = options.list || options.remove ? stdout : parseResponse(output, options); actionJackedCallback(err || null, response); }); if (child && !finished) this._activeNotifications.add(clear); return this; } if (this.options.withFallback) return new Notifier$1(this.options).notify(options, callback); callback(/* @__PURE__ */ new Error(errorMessageOsX)); return this; } function constructArgumentList(options) { const { actions, ...rest } = options; const args = utils.constructArgumentList(rest); for (const action of actions || []) args.push("-action", String(action)); return args; } function parseResponse(output, options) { if (!output) return {}; if (output === "@TIMEOUT") return { activationType: "timeout" }; if (output === "@CLOSED") return { activationType: "closed" }; if (output === "@ACTIONCLICKED") return { activationType: "contentsClicked" }; if (options.actions?.includes(output)) return { activationType: "actionClicked", activationValue: output }; if (options.reply !== void 0) return { activationType: "replied", activationValue: output }; return {}; } export { Notifier as default, Notifier as "module.exports" }; //# sourceMappingURL=notificationcenter.js.map