function Growl(options) {
options = utils.clone(options || {});
if (!(this instanceof Growl)) {
return new Growl(options);
}
growly.appname = options.name || 'Node';
this.options = options;
EventEmitter.call(this);
}...
```javascript
const nn = require('node-notifier');
new nn.NotificationCenter(options).notify();
new nn.NotifySend(options).notify();
new nn.WindowsToaster(options).notify(options);
new nn.WindowsBalloon(options).notify(options);
new nn.Growl(options).notify(options);
```
## Contents
* [Notification Center documentation](#usage-notificationcenter)
* [Windows Toaster documentation](#usage-windowstoaster)
* [Windows Balloon documentation](#usage-windowsballoon)
...function NotifySend(options) {
options = utils.clone(options || {});
if (!(this instanceof NotifySend)) {
return new NotifySend(options);
}
this.options = options;
EventEmitter.call(this);
}n/a
function NotificationCenter(options) {
options = utils.clone(options || {});
if (!(this instanceof NotificationCenter)) {
return new NotificationCenter(options);
}
this.options = options;
EventEmitter.call(this);
}...
Or if you are using several (or you are lazy):
(note: technically, this takes longer to require)
```javascript
const nn = require('node-notifier');
new nn.NotificationCenter(options).notify();
new nn.NotifySend(options).notify();
new nn.WindowsToaster(options).notify(options);
new nn.WindowsBalloon(options).notify(options);
new nn.Growl(options).notify(options);
```
## Contents
...function NotifySend(options) {
options = utils.clone(options || {});
if (!(this instanceof NotifySend)) {
return new NotifySend(options);
}
this.options = options;
EventEmitter.call(this);
}...
Or if you are using several (or you are lazy):
(note: technically, this takes longer to require)
```javascript
const nn = require('node-notifier');
new nn.NotificationCenter(options).notify();
new nn.NotifySend(options).notify();
new nn.WindowsToaster(options).notify(options);
new nn.WindowsBalloon(options).notify(options);
new nn.Growl(options).notify(options);
```
## Contents
...function WindowsBalloon(options) {
options = utils.clone(options || {});
if (!(this instanceof WindowsBalloon)) {
return new WindowsBalloon(options);
}
this.options = options;
EventEmitter.call(this);
}...
```javascript
const nn = require('node-notifier');
new nn.NotificationCenter(options).notify();
new nn.NotifySend(options).notify();
new nn.WindowsToaster(options).notify(options);
new nn.WindowsBalloon(options).notify(options);
new nn.Growl(options).notify(options);
```
## Contents
* [Notification Center documentation](#usage-notificationcenter)
* [Windows Toaster documentation](#usage-windowstoaster)
...function WindowsToaster(options) {
options = utils.clone(options || {});
if (!(this instanceof WindowsToaster)) {
return new WindowsToaster(options);
}
this.options = options;
EventEmitter.call(this);
}...
(note: technically, this takes longer to require)
```javascript
const nn = require('node-notifier');
new nn.NotificationCenter(options).notify();
new nn.NotifySend(options).notify();
new nn.WindowsToaster(options).notify(options);
new nn.WindowsBalloon(options).notify(options);
new nn.Growl(options).notify(options);
```
## Contents
* [Notification Center documentation](#usage-notificationcenter)
...function Growl(options) {
options = utils.clone(options || {});
if (!(this instanceof Growl)) {
return new Growl(options);
}
growly.appname = options.name || 'Node';
this.options = options;
EventEmitter.call(this);
}...
```javascript
const nn = require('node-notifier');
new nn.NotificationCenter(options).notify();
new nn.NotifySend(options).notify();
new nn.WindowsToaster(options).notify(options);
new nn.WindowsBalloon(options).notify(options);
new nn.Growl(options).notify(options);
```
## Contents
* [Notification Center documentation](#usage-notificationcenter)
* [Windows Toaster documentation](#usage-windowstoaster)
* [Windows Balloon documentation](#usage-windowsballoon)
...function EventEmitter() {
EventEmitter.init.call(this);
}n/a
notify = function (options, callback) {
growly.setHost(this.options.host, this.options.port);
options = utils.clone(options || {});
if (typeof options === 'string') {
options = { title: 'node-notifier', message: options };
}
callback = utils.actionJackerDecorator(this, options, callback, function(
data
) {
if (data === 'click') {
return 'click';
}
if (data === 'timedout') {
return 'timeout';
}
return false;
});
options = utils.mapToGrowl(options);
if (!options.message) {
callback(new Error('Message is required.'));
return this;
}
options.title = options.title || 'Node Notification:';
if (hasGrowl || !!options.wait) {
var localCallback = options.wait ? callback : noop;
growly.notify(options.message, options, localCallback);
if (!options.wait) callback();
return this;
}
checkGrowl(growly, function(didHaveGrowl) {
hasGrowl = didHaveGrowl;
if (!didHaveGrowl) return callback(new Error(errorMessageNotFound));
growly.notify(options.message, options);
callback();
});
return this;
}...
## Quick Usage
Show a native notification on macOS, Windows, Linux:
```javascript
const notifier = require('node-notifier');
// String
notifier.notify('Message');
// Object
notifier.notify({
'title': 'My notification',
'message': 'Hello, there!'
});
```
...function NotifySend(options) {
options = utils.clone(options || {});
if (!(this instanceof NotifySend)) {
return new NotifySend(options);
}
this.options = options;
EventEmitter.call(this);
}n/a
function EventEmitter() {
EventEmitter.init.call(this);
}n/a
notify = function (options, callback) {
options = utils.clone(options || {});
callback = callback || noop;
if (typeof callback !== 'function') {
throw new TypeError(
'The second argument must be a function callback. You have passed ' +
typeof callback
);
}
if (typeof options === 'string') {
options = { title: 'node-notifier', message: options };
}
if (!options.message) {
callback(new Error('Message is required.'));
return this;
}
if (os.type() !== 'Linux' && !os.type().match(/BSD$/)) {
callback(new Error('Only supported on Linux and *BSD systems'));
return this;
}
if (hasNotifier === false) {
callback(new Error('notify-send must be installed on the system.'));
return this;
}
if (hasNotifier || !!this.options.suppressOsdCheck) {
doNotification(options, callback);
return this;
}
try {
hasNotifier = !!which.sync(notifier);
doNotification(options, callback);
} catch (err) {
hasNotifier = false;
return callback(err);
}
return this;
}...
## Quick Usage
Show a native notification on macOS, Windows, Linux:
```javascript
const notifier = require('node-notifier');
// String
notifier.notify('Message');
// Object
notifier.notify({
'title': 'My notification',
'message': 'Hello, there!'
});
```
...function NotificationCenter(options) {
options = utils.clone(options || {});
if (!(this instanceof NotificationCenter)) {
return new NotificationCenter(options);
}
this.options = options;
EventEmitter.call(this);
}...
Or if you are using several (or you are lazy):
(note: technically, this takes longer to require)
```javascript
const nn = require('node-notifier');
new nn.NotificationCenter(options).notify();
new nn.NotifySend(options).notify();
new nn.WindowsToaster(options).notify(options);
new nn.WindowsBalloon(options).notify(options);
new nn.Growl(options).notify(options);
```
## Contents
...function EventEmitter() {
EventEmitter.init.call(this);
}n/a
notify = function (options, callback) {
var fallbackNotifier;
var id = identificator();
options = utils.clone(options || {});
activeId = id;
if (typeof options === 'string') {
options = { title: 'node-notifier', message: options };
}
var timeout;
callback = callback || noop;
if (typeof callback !== 'function') {
throw new TypeError(
'The second argument must be a function callback. You have passed ' +
typeof fn
);
}
var actionJackedCallback = utils.actionJackerDecorator(
this,
options,
function() {
clearTimeout(timeout);
callback.apply(null, arguments);
},
function(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(new Error('Message, group, remove or list property is required.'));
return this;
}
var argsList = utils.constructArgumentList(options);
if (utils.isMountainLion()) {
var cp = utils.fileCommandJson(
this.options.customPath || notifier,
argsList,
actionJackedCallback
);
// Redundancy fallback to prevent memory leak
timeout = setTimeout(
function() {
cp.kill('SIGTERM');
},
FAILSAFE_TIMEOUT
);
return this;
}
if (fallbackNotifier || !!this.options.withFallback) {
fallbackNotifier = fallbackNotifier || new Growl(this.options);
return fallbackNotifier.notify(options, callback);
}
callback(new Error(errorMessageOsX));
return this;
}...
## Quick Usage
Show a native notification on macOS, Windows, Linux:
```javascript
const notifier = require('node-notifier');
// String
notifier.notify('Message');
// Object
notifier.notify({
'title': 'My notification',
'message': 'Hello, there!'
});
```
...function WindowsBalloon(options) {
options = utils.clone(options || {});
if (!(this instanceof WindowsBalloon)) {
return new WindowsBalloon(options);
}
this.options = options;
EventEmitter.call(this);
}...
```javascript
const nn = require('node-notifier');
new nn.NotificationCenter(options).notify();
new nn.NotifySend(options).notify();
new nn.WindowsToaster(options).notify(options);
new nn.WindowsBalloon(options).notify(options);
new nn.Growl(options).notify(options);
```
## Contents
* [Notification Center documentation](#usage-notificationcenter)
* [Windows Toaster documentation](#usage-windowstoaster)
...function EventEmitter() {
EventEmitter.init.call(this);
}n/a
notify = function (options, callback) {
var fallback;
var notifierOptions = this.options;
options = utils.clone(options || {});
callback = callback || noop;
if (typeof options === 'string') {
options = { title: 'node-notifier', message: options };
}
var actionJackedCallback = utils.actionJackerDecorator(
this,
options,
callback,
function(data) {
if (data === 'activate') {
return 'click';
}
if (data === 'timeout') {
return 'timeout';
}
return false;
}
);
if (!!this.options.withFallback && utils.isWin8()) {
fallback = fallback || new Toaster(notifierOptions);
return fallback.notify(options, callback);
}
if (
!!this.options.withFallback &&
(!utils.isLessThanWin8() || hasGrowl === true)
) {
fallback = fallback || new Growl(notifierOptions);
return fallback.notify(options, callback);
}
if (!this.options.withFallback || hasGrowl === false) {
doNotification(options, notifierOptions, actionJackedCallback);
return this;
}
checkGrowl(notifierOptions, function(hasGrowlResult) {
hasGrowl = hasGrowlResult;
if (hasGrowl) {
fallback = fallback || new Growl(notifierOptions);
return fallback.notify(options, callback);
}
doNotification(options, notifierOptions, actionJackedCallback);
});
return this;
}...
## Quick Usage
Show a native notification on macOS, Windows, Linux:
```javascript
const notifier = require('node-notifier');
// String
notifier.notify('Message');
// Object
notifier.notify({
'title': 'My notification',
'message': 'Hello, there!'
});
```
...function WindowsToaster(options) {
options = utils.clone(options || {});
if (!(this instanceof WindowsToaster)) {
return new WindowsToaster(options);
}
this.options = options;
EventEmitter.call(this);
}...
(note: technically, this takes longer to require)
```javascript
const nn = require('node-notifier');
new nn.NotificationCenter(options).notify();
new nn.NotifySend(options).notify();
new nn.WindowsToaster(options).notify(options);
new nn.WindowsBalloon(options).notify(options);
new nn.Growl(options).notify(options);
```
## Contents
* [Notification Center documentation](#usage-notificationcenter)
...function EventEmitter() {
EventEmitter.init.call(this);
}n/a
notify = function (options, callback) {
options = utils.clone(options || {});
callback = callback || noop;
if (typeof options === 'string') {
options = { title: 'node-notifier', message: options };
}
if (typeof callback !== 'function') {
throw new TypeError(
'The second argument must be a function callback. You have passed ' +
typeof fn
);
}
var actionJackedCallback = utils.actionJackerDecorator(
this,
options,
function cb(err, data) {
// Needs to filter out timeout. Not an actual error.
if (err && hasText(data, timeoutMessage)) {
return callback(null, data);
}
callback(err, data);
},
function mapper(data) {
if (hasText(data, successMessage)) {
return 'click';
}
if (hasText(data, timeoutMessage)) {
return 'timeout';
}
return false;
}
);
options.title = options.title || 'Node Notification:';
if (
typeof options.message === 'undefined' &&
typeof options.close === 'undefined'
) {
callback(new Error('Message or ID to close is required.'));
return this;
}
if (!utils.isWin8() && !!this.options.withFallback) {
fallback = fallback || new Balloon(this.options);
return fallback.notify(options, callback);
}
options = utils.mapToWin8(options);
var argsList = utils.constructArgumentList(options, {
explicitTrue: true,
wrapper: '',
keepNewlines: true,
noEscape: true
});
utils.fileCommand(
this.options.customPath || notifier,
argsList,
actionJackedCallback
);
return this;
}...
## Quick Usage
Show a native notification on macOS, Windows, Linux:
```javascript
const notifier = require('node-notifier');
// String
notifier.notify('Message');
// Object
notifier.notify({
'title': 'My notification',
'message': 'Hello, there!'
});
```
...actionJackerDecorator = function (emitter, options, fn, mapper) {
options = clone(options);
fn = fn || noop;
if (typeof fn !== 'function') {
throw new TypeError(
'The second argument must be a function callback. You have passed ' +
typeof fn
);
}
return function(err, data) {
var resultantData = data;
var metadata = {};
// Allow for extra data if resultantData is an object
if (resultantData && typeof resultantData === 'object') {
metadata = resultantData;
resultantData = resultantData.activationType;
}
// Sanitize the data
if (resultantData) {
resultantData = resultantData.toLowerCase().trim();
if (resultantData.match(/^activate|clicked$/)) {
resultantData = 'activate';
}
}
fn.apply(emitter, [err, resultantData, metadata]);
if (!mapper || !resultantData) return;
var key = mapper(resultantData);
if (!key) return;
emitter.emit(key, emitter, options, metadata);
};
}n/a
function clone(obj) {
return JSON.parse(JSON.stringify(obj));
}n/a
command = function (notifier, options, cb) {
notifier = shellwords.escape(notifier);
if (process.env.DEBUG) {
console.info('node-notifier debug info (command):');
console.info('[notifier path]', notifier);
console.info('[notifier options]', options.join(' '));
}
return cp.exec(
notifier + ' ' + options.join(' '),
function(error, stdout, stderr) {
if (error) return cb(error);
cb(stderr, stdout);
}
);
}n/a
constructArgumentList = function (options, extra) {
var args = [];
extra = extra || {};
// Massive ugly setup. Default args
var initial = extra.initial || [];
var keyExtra = extra.keyExtra || '';
var allowedArguments = extra.allowedArguments || [];
var noEscape = extra.noEscape !== void 0;
var checkForAllowed = extra.allowedArguments !== void 0;
var explicitTrue = !!extra.explicitTrue;
var keepNewlines = !!extra.keepNewlines;
var wrapper = extra.wrapper === void 0 ? '"' : extra.wrapper;
var escapeFn = function(arg) {
if (isArray(arg)) {
return removeNewLines(arg.join(','));
}
if (!noEscape) {
arg = escapeQuotes(arg);
}
if (typeof arg === 'string' && !keepNewlines) {
arg = removeNewLines(arg);
}
return wrapper + arg + wrapper;
};
initial.forEach(function(val) {
args.push(escapeFn(val));
});
for (var key in options) {
if (
options.hasOwnProperty(key) &&
(!checkForAllowed || inArray(allowedArguments, key))
) {
if (explicitTrue && options[key] === true) {
args.push('-' + keyExtra + key);
} else if (explicitTrue && options[key] === false) continue;
else args.push('-' + keyExtra + key, escapeFn(options[key]));
}
}
return args;
}n/a
fileCommand = function (notifier, options, cb) {
if (process.env.DEBUG) {
console.info('node-notifier debug info (fileCommand):');
console.info('[notifier path]', notifier);
console.info('[notifier options]', options.join(' '));
}
return cp.execFile(notifier, options, function(error, stdout, stderr) {
if (error) return cb(error, stdout);
cb(stderr, stdout);
});
}n/a
fileCommandJson = function (notifier, options, cb) {
if (process.env.DEBUG) {
console.info('node-notifier debug info (fileCommandJson):');
console.info('[notifier path]', notifier);
console.info('[notifier options]', options.join(' '));
}
return cp.execFile(notifier, options, function(error, stdout, stderr) {
if (error) return cb(error, stdout);
if (!stdout) return cb(error, {});
try {
var data = JSON.parse(stdout);
cb(stderr, data);
} catch (e) {
cb(e, stdout);
}
});
}n/a
immediateFileCommand = function (notifier, options, cb) {
if (process.env.DEBUG) {
console.info('node-notifier debug info (notifier):');
console.info('[notifier path]', notifier);
}
notifierExists(notifier, function(exists) {
if (!exists) {
return cb(new Error('Notifier (' + notifier + ') not found on system.'));
}
cp.execFile(notifier, options);
cb();
});
}n/a
isLessThanWin8 = function () {
return os.type() === 'Windows_NT' &&
semver.satisfies(garanteeSemverFormat(os.release()), '<6.2.9200');
}...
module.exports.Notification = NotifySend;
break;
case 'Darwin':
module.exports = new NotificationCenter(options);
module.exports.Notification = NotificationCenter;
break;
case 'Windows_NT':
if (utils.isLessThanWin8()) {
module.exports = new WindowsBalloon(options);
module.exports.Notification = WindowsBalloon;
} else {
module.exports = new WindowsToaster(options);
module.exports.Notification = WindowsToaster;
}
break;
...isMac = function () {
return os.type() === 'Darwin';
}n/a
isMountainLion = function () {
return os.type() === 'Darwin' &&
semver.satisfies(garanteeSemverFormat(os.release()), '>=12.0.0');
}n/a
isWin8 = function () {
return os.type() === 'Windows_NT' &&
semver.satisfies(garanteeSemverFormat(os.release()), '>=6.2.9200');
}n/a
mapToGrowl = function (options) {
options = mapAppIcon(options);
options = mapIconShorthand(options);
options = mapText(options);
if (options.icon && !Buffer.isBuffer(options.icon)) {
try {
options.icon = fs.readFileSync(options.icon);
} catch (ex) {}
}
return options;
}n/a
mapToMac = function (options) {
options = mapIconShorthand(options);
options = mapText(options);
if (options.icon) {
options.appIcon = options.icon;
delete options.icon;
}
if (options.sound === true) {
options.sound = 'Bottle';
}
if (options.sound === false) {
delete options.sound;
}
if (options.sound && options.sound.indexOf('Notification.') === 0) {
options.sound = 'Bottle';
}
if (options.wait === true) {
if (!options.timeout) {
options.timeout = 5;
}
delete options.wait;
}
options.json = true;
return options;
}n/a
mapToNotifu = function (options) {
options = mapAppIcon(options);
options = mapText(options);
if (options.icon) {
options.i = options.icon;
delete options.icon;
}
if (options.message) {
options.m = options.message;
delete options.message;
}
if (options.title) {
options.p = options.title;
delete options.title;
}
if (options.time) {
options.d = options.time;
delete options.time;
}
if (options.q !== false) {
options.q = true;
} else {
delete options.q;
}
if (options.quiet === false) {
delete options.q;
delete options.quiet;
}
if (options.sound) {
delete options.q;
delete options.sound;
}
if (options.t) {
options.d = options.t;
delete options.t;
}
if (options.type) {
options.t = sanitizeNotifuTypeArgument(options.type);
delete options.type;
}
return options;
}n/a
mapToNotifySend = function (options) {
options = mapAppIcon(options);
options = mapText(options);
for (var key in options) {
if (key === 'message' || key === 'title') continue;
if (options.hasOwnProperty(key) && notifySendFlags[key] !== key) {
options[notifySendFlags[key]] = options[key];
delete options[key];
}
}
return options;
}n/a
mapToWin8 = function (options) {
options = mapAppIcon(options);
options = mapText(options);
if (options.icon) {
if (/^file:\/+/.test(options.icon)) {
// should parse file protocol URL to path
options.p = url
.parse(options.icon)
.pathname.replace(/^\/(\w:\/)/, '$1')
.replace(/\//g, '\\');
} else {
options.p = options.icon;
}
delete options.icon;
}
if (options.message) {
// Remove escape char to debug "HRESULT : 0xC00CE508" exception
options.m = options.message.replace(/\x1b/g, '');
delete options.message;
}
if (options.title) {
options.t = options.title;
delete options.title;
}
if (options.appName) {
options.appID = options.appName;
delete options.appName;
} else {
options.appID = ' ';
}
if (typeof options.appID === 'undefined') {
options.appID = ' ';
}
if (typeof options.remove !== 'undefined') {
options.close = options.remove;
delete options.remove;
}
if (options.quiet || options.silent) {
options.silent = options.quiet || options.silent;
delete options.quiet;
}
if (typeof options.sound !== 'undefined') {
options.s = options.sound;
delete options.sound;
}
if (options.s === false) {
options.silent = true;
delete options.s;
}
// Silent takes precedence. Remove sound.
if (options.s && options.silent) {
delete options.s;
}
if (options.s === true) {
options.s = toasterDefaultSound;
}
if (options.s && options.s.indexOf(toasterSoundPrefix) !== 0) {
options.s = toasterDefaultSound;
}
if (options.wait) {
options.w = options.wait;
delete options.wait;
}
for (var key in options) {
// Check if is allowed. If not, delete!
if (
options.hasOwnProperty(key) && allowedToasterFlags.indexOf(key) === -1
) {
delete options[key];
}
}
return options;
}n/a