1
0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-11-08 23:25:51 +01:00

Merge pull request #108 from ryan-codingintrigue/master

Add support for multiple notification endpoints to existing webhook s…
This commit is contained in:
jotadeveloper 2017-04-26 18:23:35 +02:00 committed by GitHub
commit 472e8e94b0
2 changed files with 83 additions and 37 deletions

@ -137,6 +137,11 @@ notify:
# Choose a method. Technically this will accept any HTTP # Choose a method. Technically this will accept any HTTP
# request method, but probably stick to GET or POST # request method, but probably stick to GET or POST
method: POST method: POST
# Only run this notification if the package name matches the regular
# expression
packagePattern: ^example-package$
# Any flags to be used with the regular expression
packagePatternFlags: i
# If this endpoint requires specific headers, set them here # If this endpoint requires specific headers, set them here
# as an array of key: value objects. # as an array of key: value objects.
headers: [{'Content-type': 'application/x-www-form-urlencoded'}] headers: [{'Content-type': 'application/x-www-form-urlencoded'}]
@ -149,3 +154,24 @@ notify:
content: ' {{ handlebar-expression }}' content: ' {{ handlebar-expression }}'
# For Slack, follow the following format: # For Slack, follow the following format:
# content: '{ "text": "Package *{{ name }}* published to version *{{ dist-tags.latest }}*", "username": "Verdaccio", "icon_emoji": ":package:" }' # content: '{ "text": "Package *{{ name }}* published to version *{{ dist-tags.latest }}*", "username": "Verdaccio", "icon_emoji": ":package:" }'
# Multiple notification endpoints can be created by specifying a collection
'example-package-1'
method: POST
# Only run this notification if the package name matches the regular
# expression
packagePattern: ^example-package-regex$
# Any flags to be used with the regular expression
packagePatternFlags: i
# If this endpoint requires specific headers, set them here
# as an array of key: value objects.
headers: [{'Content-type': 'application/x-www-form-urlencoded'}]
# set the URL endpoint for this call
endpoint: https://hooks.slack.com/...
# Finally, the content you will be sending in the body.
# This data will first be run through Handlebars to parse
# any Handlebar expressions. All data housed in the metadata object
# is available for use within the expressions.
content: ' {{ handlebar-expression }}'
# For Slack, follow the following format:
# content: '{ "text": "Package *{{ name }}* published to version *{{ dist-tags.latest }}*", "username": "Verdaccio", "icon_emoji": ":package:" }'

@ -1,48 +1,68 @@
'use strict'; 'use strict';
let Handlebars = require('handlebars'); const Handlebars = require('handlebars');
let request = require('request'); const request = require('request');
let Logger = require('./logger'); const Logger = require('./logger');
module.exports.notify = function(metadata, config) { const handleNotify = function(metadata, notifyEntry) {
if (config.notify && config.notify.content) { let regex;
let template = Handlebars.compile(config.notify.content); if (metadata.name && notifyEntry.packagePattern) {
let content = template( metadata ); regex = new RegExp(notifyEntry.packagePattern, notifyEntry.packagePatternFlags || '');
if (!regex.test(metadata.name)) {
return;
}
}
let options = { const template = Handlebars.compile(notifyEntry.content);
body: content, const content = template( metadata );
};
// provides fallback support, it's accept an Object {} and Array of {} const options = {body: content};
if ( config.notify.headers && Array.isArray(config.notify.headers) ) {
let header = {}; // provides fallback support, it's accept an Object {} and Array of {}
config.notify.headers.map(function(item) { if (notifyEntry.headers && Array.isArray(notifyEntry.headers)) {
if (Object.is(item, item)) { const header = {};
for (let key in item) { notifyEntry.headers.map(function(item) {
header[key] = item[key]; if (Object.is(item, item)) {
for (const key in item) {
if (item.hasOwnProperty(key)) {
header[key] = item[key];
} }
} }
});
options.headers = header;
} else if (Object.is(config.notify.headers, config.notify.headers)) {
options.headers = config.notify.headers;
}
options.method = config.notify.method;
if (config.notify.endpoint) {
options.url = config.notify.endpoint;
}
request(options, function(err, response, body) {
if (err) {
Logger.logger.error( {err: err}, ' notify error: @{err.message}' );
} else {
Logger.logger.info({content: content}, 'A notification has been shipped: @{content}');
if (body) {
Logger.logger.debug( {body: body}, ' body: @{body}' );
}
} }
}); });
options.headers = header;
} else if (Object.is(notifyEntry.headers, notifyEntry.headers)) {
options.headers = notifyEntry.headers;
}
options.method = notifyEntry.method;
if ( notifyEntry.endpoint ) {
options.url = notifyEntry.endpoint;
}
request(options, function(err, response, body) {
if (err) {
Logger.logger.error({err: err}, ' notify error: @{err.message}' );
} else {
Logger.logger.info({content: content}, 'A notification has been shipped: @{content}');
if (body) {
Logger.logger.debug({body: body}, ' body: @{body}' );
}
}
});
};
module.exports.notify = function(metadata, config) {
if (config.notify) {
if (config.notify.content) {
handleNotify(metadata, config.notify);
} else {
for (const key in config.notify) {
if (config.notify.hasOwnProperty(key)) {
handleNotify(metadata, config.notify[key]);
}
}
}
} }
}; };