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
JavaScript
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