1
0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-02-21 07:29:37 +01:00

Merge branch 'master' into master

This commit is contained in:
Juan Picado @jotadeveloper 2018-06-14 22:56:42 +02:00 committed by GitHub
commit dffe497a09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 614 additions and 42 deletions

@ -5,12 +5,14 @@ title: "Notifications"
Notify was built primarily to use with Slack's Incoming
webhooks, but will also deliver a simple payload to
any endpoint. Currently only active for `publish` / `create`
commands.
any endpoint. Currently only active for `npm publish`
command.
## Usage
An example with a **HipChat** and **Google Hangouts Chat** hook:
An example with a **HipChat**, **Stride** and **Google Hangouts Chat** hook:
> Verdaccio supports any API, feel free to ad more examples.
#### Single notification
@ -43,7 +45,84 @@ notify:
content: '{"body": {"version": 1,"type": "doc","content": [{"type": "paragraph","content": [{"type": "text","text": "New package published: * {{ name }}* Publisher name: * {{ publisher.name }}"}]}]}}'
```
### Publisher information
## Template
We use [Handlebars](https://handlebarsjs.com/) as main template engine.
### Format Examples
```
# iterate all versions
{{ name }}{{#each versions}} v{{version}}{{/each}}`"}
# publisher and `dist-tag` package published
{{ publisher.name }} has published {{publishedPackage}}"}
```
### Properties
List of properties accesible via template
* Metadata
* Publisher (who is publishing)
* Package Published (package@1.0.0)
### Metadata
Package metadata that the template has access
```
{
"_id": "@test/pkg1",
"name": "@test/pkg1",
"description": "",
"dist-tags": {
"beta": "1.0.54"
},
"versions": {
"1.0.54": {
"name": "@test/pkg1",
"version": "1.0.54",
"description": "some description",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": {
"name": "Author Name",
"email": "author@domain.com"
},
"license": "MIT",
"dependencies": {
"webpack": "4.12.0"
},
"readmeFilename": "README.md",
"_id": "@ test/pkg1@1.0.54",
"_npmVersion": "6.1.0",
"_nodeVersion": "9.9.0",
"_npmUser": {},
"dist": {
"integrity": "sha512-JlXWpLtMUBAqvVZBvH7UVLhXkGE1ctmXbDjbH/l0zMuG7wVzQ7GshTYvD/b5C+G2vOL2oiIS1RtayA/kKkTwKw==",
"shasum": "29c55c52c1e76e966e706165e5b9f22e32aa9f22",
"tarball": "http://localhost:4873/@test/pkg1/-/@test/pkg1-1.0.54.tgz"
}
}
},
"readme": "# test",
"_attachments": {
"@test/pkg1-1.0.54.tgz": {
"content_type": "application/octet-stream",
"data": "H4sIAAAAAAAAE+y9Z5PjyJIgOJ ...",
"length": 33112
}
},
"time": {}
}
```
### Publisher
You can access to the package publisher information in the `content` of a webhook using the `publisher` object.
@ -69,6 +148,14 @@ notify:
**Note:** it's not possible to get the publisher information if the `package.json` file already has the `publisher` property.
### Package Published
You can acces to the package is being published with the keyword `{{publishedPackage}}` as follows.
```
{{ publisher.name }} has published {{publishedPackage}}"}
```
## Configuration
Property | Type | Required | Support | Default | Description
@ -78,4 +165,4 @@ packagePattern| string | No | all | | Only run this notification if the package
packagePatternFlags| string | No | all | | Any flags to be used with the regular expression
headers| array/object | Yes | all | | If this endpoint requires specific headers, set them here as an array of key: value objects.
endpoint| string | Yes | all | | set the URL endpoint for this call
content| string | Yes | all | | any [handlebar](https://handlebarsjs.com/) expressions
content| string | Yes | all | | any [Handlebar](https://handlebarsjs.com/) expressions

@ -12,6 +12,7 @@ import {notify} from '../../../lib/notify';
import type {Router} from 'express';
import type {Config, Callback} from '@verdaccio/types';
import type {IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler} from '../../../../types';
import logger from '../../../lib/logger';
export default function(router: Router, auth: IAuth, storage: IStorageHandler, config: Config) {
const can = allow(auth);
@ -80,18 +81,24 @@ export default function(router: Router, auth: IAuth, storage: IStorageHandler, c
return next(err);
}
const t2 = Object.keys(metadata.versions)[0];
metadata.versions[t2].readme = _.isNil(metadata.readme) === false ? String(metadata.readme) : '';
create_version(t2, metadata.versions[t2], function(err) {
const versionToPublish = Object.keys(metadata.versions)[0];
metadata.versions[versionToPublish].readme = _.isNil(metadata.readme) === false ? String(metadata.readme) : '';
create_version(versionToPublish, metadata.versions[versionToPublish], function(err) {
if (err) {
return next(err);
}
add_tags(metadata[DIST_TAGS], function(err) {
add_tags(metadata[DIST_TAGS], async function(err) {
if (err) {
return next(err);
}
notify(metadata, config, req.remote_user);
try {
await notify(metadata, config, req.remote_user, `${metadata.name}@${versionToPublish}`);
} catch (err) {
logger.logger.error({err}, 'notify batch service has failed: @{err}');
}
res.status(201);
return next({ok: ok_message, success: true});
});

@ -1,9 +1,9 @@
const Handlebars = require('handlebars');
const request = require('request');
const _ = require('lodash');
const logger = require('./logger');
import Handlebars from 'handlebars';
import request from 'request';
import _ from 'lodash';
import logger from './logger';
const handleNotify = function(metadata, notifyEntry, publisherInfo) {
const handleNotify = function(metadata, notifyEntry, publisherInfo, publishedPackage) {
let regex;
if (metadata.name && notifyEntry.packagePattern) {
// FUTURE: comment out due https://github.com/verdaccio/verdaccio/pull/108#issuecomment-312421052
@ -18,7 +18,7 @@ const handleNotify = function(metadata, notifyEntry, publisherInfo) {
// don't override 'publisher' if package.json already has that
if (!metadata.publisher) {
metadata = {...metadata, publisher: publisherInfo};
metadata = {...metadata, publishedPackage, publisher: publisherInfo};
}
const content = template(metadata);
@ -52,29 +52,40 @@ const handleNotify = function(metadata, notifyEntry, publisherInfo) {
return new Promise((resolve, reject) => {
request(options, function(err, response, body) {
if (err || response.statusCode >= 400) {
const errorMessage = _.isNil(err) ? response.statusMessage : err;
logger.logger.error({err: errorMessage}, ' notify error: @{err.message}');
const errorMessage = _.isNil(err) ? response.body : err.message;
logger.logger.error({errorMessage}, 'notify service has thrown an error: @{errorMessage}');
reject(errorMessage);
} else {
logger.logger.info({content: content}, 'A notification has been shipped: @{content}');
if (body) {
logger.logger.debug({body: body}, ' body: @{body}');
logger.logger.info({content}, 'A notification has been shipped: @{content}');
if (_.isNil(body) === false) {
const bodyResolved = _.isNil(body) === false ? body : null;
logger.logger.debug({body}, ' body: @{body}');
return resolve(bodyResolved);
}
resolve(_.isNil(body) === false ? body : null);
reject(Error('body is missing'));
}
});
});
};
const notify = function(metadata, config, publisherInfo) {
function sendNotification(metadata, key, ...moreMedatata) {
return handleNotify(metadata, key, ...moreMedatata);
}
const notify = function(metadata, config, ...moreMedatata) {
if (config.notify) {
if (config.notify.content) {
return handleNotify(metadata, config.notify, publisherInfo);
return sendNotification(metadata, config.notify, ...moreMedatata);
} else {
// multiple notifications endpoints PR #108
return Promise.all(_.map(config.notify, (key) => handleNotify(metadata, key, publisherInfo)));
return Promise.all(_.map(config.notify, (key) => sendNotification(metadata, key, ...moreMedatata)));
}
}
return Promise.resolve();
};
module.exports.notify = notify;
export {notify};

@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
import LastSync from './modules/LastSync';
import Maintainers from './modules/Maintainers';
import Dependencies from './modules/Dependencies';
import Infos from './modules/Infos';
import API from '../../../utils/api';
@ -53,6 +54,7 @@ export default class PackageSidebar extends React.Component {
return packageMeta ?
(<aside className="sidebar-info">
<LastSync packageMeta={packageMeta} />
<Infos packageMeta={packageMeta} />
<Maintainers packageMeta={packageMeta} />
<Dependencies packageMeta={packageMeta} />
{/* Package management module? Help us implement it! */}

@ -0,0 +1,69 @@
import React from 'react';
import PropTypes from 'prop-types';
import get from 'lodash/get';
import Module from '../../Module';
import isString from 'lodash/isString';
import isNil from 'lodash/isNil';
import classes from './style.scss';
export default class Infos extends React.Component {
static propTypes = {
packageMeta: PropTypes.object.isRequired
};
get infos() {
const homepage = this.normalizeInfo(get(this, 'props.packageMeta.latest.homepage', null));
const repo = this.normalizeInfo(get(this, 'props.packageMeta.latest.repository', null));
const license = get(this, 'props.packageMeta.latest.license', 'N/A');
return {homepage, repo, license};
}
normalizeInfo(infoObj) {
if (isString(infoObj)) {
return {url: infoObj};
} else if (isNil(infoObj)) {
return {url: ''};
}
infoObj.url = this.normalizeGitUrl(infoObj);
return infoObj;
}
normalizeGitUrl(infoObj) {
return infoObj.url.replace(/^git\+/, '');
}
render() {
const infos = this.infos;
if (infos.homepage.url === '' && infos.repo.url === '' && infos.license === 'N/A') {
return '';
}
return (
<Module
title="Infos"
className={classes.infosModule}
>
<ul>
{infos.homepage.url && this.renderSection('Homepage', infos.homepage.url)}
{infos.repo.url && this.renderSection('Repository', infos.repo.url)}
{infos.license &&
<li><span>License</span><span>{infos.license}</span></li>
}
</ul>
</Module>
);
}
renderSection(title, url) {
return (
<li><span>{title}</span><a href={url} target="_blank">{url}</a></li>
);
}
}

@ -0,0 +1,22 @@
@import '../../../../styles/variable';
.infosModule {
li {
display: flex;
font-size: 14px;
line-height: 2;
a {
color: inherit;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 150px;
}
a:last-child,
span:last-child {
margin-left: auto;
}
}
}

@ -12,7 +12,7 @@ export default class ExpressServer {
}
start(port: number): Promise<any> {
return new Promise((resolve, reject) => {
return new Promise((resolve) => {
this.app.use(bodyParser.json());
this.app.use(bodyParser.urlencoded({
extended: true

@ -22,6 +22,12 @@ export default function(express) {
describe('notifications', () => {
function parseBody(notification) {
const jsonBody = JSON.parse(notification);
return jsonBody;
}
beforeAll(function () {
express.post('/api/notify', function (req, res) {
res.send(req.body);
@ -38,7 +44,7 @@ export default function(express) {
};
notify(metadata, config, publisherInfo).then(function (body) {
const jsonBody = JSON.parse(body);
const jsonBody = parseBody(body);
assert.ok(
`New package published: * ${metadata.name}*. Publisher name: * ${
publisherInfo.name
@ -63,7 +69,7 @@ export default function(express) {
};
notify(metadata, configMultipleHeader, publisherInfo).then(function (body) {
const jsonBody = JSON.parse(body);
const jsonBody = parseBody(body);
assert.ok(
`New package published: * ${metadata.name}*. Publisher name: * ${
publisherInfo.name
@ -99,7 +105,7 @@ export default function(express) {
notify(metadata, multipleNotificationsEndpoint, publisherInfo).then(function (body) {
body.forEach(function(notification) {
const jsonBody = JSON.parse(notification);
const jsonBody = parseBody(notification);
assert.ok(
`New package published: * ${metadata.name}*. Publisher name: * ${
publisherInfo.name
@ -125,7 +131,7 @@ export default function(express) {
assert.equal(false, 'This service should fails with status code 400');
done();
}, function (err) {
assert.ok('Bad Request' === err, 'The error message should be "Bad Request');
expect(err).toEqual('bad response');
done();
});
});
@ -140,7 +146,7 @@ export default function(express) {
notify(metadata, config, publisherInfo).then(
function(body) {
const jsonBody = JSON.parse(body);
const jsonBody = parseBody(body);
assert.ok(
`New package published: * ${metadata.name}*. Publisher name: * ${
metadata.publisher.name

@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<PackageSidebar /> : <Infos /> should load the Info component and match snapshot 1`] = `"<div class=\\"module infosModule\\"><h2 class=\\"moduleTitle\\">Infos</h2><div><ul><li><span>Homepage</span><a href=\\"https://github.com/verdaccio/verdaccio#readme\\" target=\\"_blank\\">https://github.com/verdaccio/verdaccio#readme</a></li><li><span>Repository</span><a href=\\"git://github.com/verdaccio/verdaccio.git\\" target=\\"_blank\\">git://github.com/verdaccio/verdaccio.git</a></li><li><span>License</span><span>WTFPL</span></li></ul></div></div>"`;

@ -0,0 +1,29 @@
/**
* Infos component
*/
import React from 'react';
import { mount, shallow } from 'enzyme';
import Infos from '../../../../src/webui/src/components/PackageSidebar/modules/Infos';
import { packageMeta } from '../store/packageMeta';
console.error = jest.fn();
describe('<PackageSidebar /> : <Infos />', () => {
it('should load the component and check getter: info with package data', () => {
const wrapper = mount(<Infos packageMeta={packageMeta} />);
const instance = wrapper.instance();
const result = {
repo: { type: 'git', url: 'git://github.com/verdaccio/verdaccio.git' },
homepage: { url: 'https://github.com/verdaccio/verdaccio#readme' },
license: 'WTFPL'
};
expect(instance.infos).toEqual(result);
});
it('should load the Info component and match snapshot', () => {
const wrapper = shallow(<Infos packageMeta={packageMeta} />);
expect(wrapper.html()).toMatchSnapshot();
});
});

@ -2,11 +2,13 @@
id: notifications
title: "Notificaciones"
---
Las notificaciones fueron introducidas con la idea de usar webhooks para Slack, pero también se puede enviar un *payload* a cualquier endpoint. Actualmente solo activo para los comandos `publish` / `create`.
Notify was built primarily to use with Slack's Incoming webhooks, but will also deliver a simple payload to any endpoint. Currently only active for `npm publish` command.
## Uso
An example with a **HipChat** and **Google Hangouts Chat** hook:
An example with a **HipChat**, **Stride** and **Google Hangouts Chat** hook:
> Verdaccio supports any API, feel free to ad more examples.
#### Notificación sencilla
@ -32,9 +34,119 @@ notify:
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}'
'example-stride':
method: POST
headers: [{'Content-Type': 'application/json'}, {'authorization': 'Bearer secretToken'}]
endpoint: https://api.atlassian.com/site/{cloudId}/conversation/{conversationId}/message
content: '{"body": {"version": 1,"type": "doc","content": [{"type": "paragraph","content": [{"type": "text","text": "New package published: * {{ name }}* Publisher name: * {{ publisher.name }}"}]}]}}'
```
## Configuración
## Template
We use [Handlebars](https://handlebarsjs.com/) as main template engine.
### Format Examples
# iterate all versions
{{ name }}{{#each versions}} v{{version}}{{/each}}`"}
# publisher and `dist-tag` package published
{{ publisher.name }} has published {{publishedPackage}}"}
### Properties
List of properties accesible via template
* Metadata
* Publisher (who is publishing)
* Package Published (package@1.0.0)
### Metadata
Package metadata that the template has access
{
"_id": "@test/pkg1",
"name": "@test/pkg1",
"description": "",
"dist-tags": {
"beta": "1.0.54"
},
"versions": {
"1.0.54": {
"name": "@test/pkg1",
"version": "1.0.54",
"description": "some description",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": {
"name": "Author Name",
"email": "author@domain.com"
},
"license": "MIT",
"dependencies": {
"webpack": "4.12.0"
},
"readmeFilename": "README.md",
"_id": "@ test/pkg1@1.0.54",
"_npmVersion": "6.1.0",
"_nodeVersion": "9.9.0",
"_npmUser": {},
"dist": {
"integrity": "sha512-JlXWpLtMUBAqvVZBvH7UVLhXkGE1ctmXbDjbH/l0zMuG7wVzQ7GshTYvD/b5C+G2vOL2oiIS1RtayA/kKkTwKw==",
"shasum": "29c55c52c1e76e966e706165e5b9f22e32aa9f22",
"tarball": "http://localhost:4873/@test/pkg1/-/@test/pkg1-1.0.54.tgz"
}
}
},
"readme": "# test",
"_attachments": {
"@test/pkg1-1.0.54.tgz": {
"content_type": "application/octet-stream",
"data": "H4sIAAAAAAAAE+y9Z5PjyJIgOJ ...",
"length": 33112
}
},
"time": {}
}
### Publisher
You can access to the package publisher information in the `content` of a webhook using the `publisher` object.
See below the `publisher` object type:
{
name: string,
groups: string[],
real_groups: string[]
}
An example:
notify:
method: POST
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"New package published: * {{ name }}*. Publisher name: * {{ publisher.name }} *.","notify":true,"message_format":"text"}'
**Note:** it's not possible to get the publisher information if the `package.json` file already has the `publisher` property.
### Package Published
You can acces to the package is being published with the keyword `{{publishedPackage}}` as follows.
{{ publisher.name }} has published {{publishedPackage}}"}
## Configuration
| Propiedad | Tipo | Requerido | Soporte | Por Defecto | Descripción |
| ------------------- | ------------ | --------- | ------- | ----------- | -------------------------------------------------------------------------------------------- |
@ -43,4 +155,4 @@ notify:
| packagePatternFlags | string | No | all | | Any flags to be used with the regular expression |
| headers | array/object | Yes | all | | Si el endpoint requiere encabezados específicos, defínelos aquí como un arreglo (key:value). |
| endpoint | string | Yes | all | | define el URL para el endpoint |
| content | string | Yes | all | | any [handlebar](https://handlebarsjs.com/) expressions |
| content | string | Yes | all | | any [Handlebar](https://handlebarsjs.com/) expressions |

@ -2,11 +2,13 @@
id: notifications
title: "Notifications"
---
Notify was built primarily to use with Slack's Incoming webhooks, but will also deliver a simple payload to any endpoint. Currently only active for `publish` / `create` commands.
Notify was built primarily to use with Slack's Incoming webhooks, but will also deliver a simple payload to any endpoint. Currently only active for `npm publish` command.
## Usage
An example with a **HipChat** and **Google Hangouts Chat** hook:
An example with a **HipChat**, **Stride** and **Google Hangouts Chat** hook:
> Verdaccio supports any API, feel free to ad more examples.
#### Single notification
@ -32,8 +34,118 @@ notify:
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}'
'example-stride':
method: POST
headers: [{'Content-Type': 'application/json'}, {'authorization': 'Bearer secretToken'}]
endpoint: https://api.atlassian.com/site/{cloudId}/conversation/{conversationId}/message
content: '{"body": {"version": 1,"type": "doc","content": [{"type": "paragraph","content": [{"type": "text","text": "New package published: * {{ name }}* Publisher name: * {{ publisher.name }}"}]}]}}'
```
## Template
We use [Handlebars](https://handlebarsjs.com/) as main template engine.
### Format Examples
# iterate all versions
{{ name }}{{#each versions}} v{{version}}{{/each}}`"}
# publisher and `dist-tag` package published
{{ publisher.name }} has published {{publishedPackage}}"}
### Properties
List of properties accesible via template
* Metadata
* Publisher (who is publishing)
* Package Published (package@1.0.0)
### Metadata
Package metadata that the template has access
{
"_id": "@test/pkg1",
"name": "@test/pkg1",
"description": "",
"dist-tags": {
"beta": "1.0.54"
},
"versions": {
"1.0.54": {
"name": "@test/pkg1",
"version": "1.0.54",
"description": "some description",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": {
"name": "Author Name",
"email": "author@domain.com"
},
"license": "MIT",
"dependencies": {
"webpack": "4.12.0"
},
"readmeFilename": "README.md",
"_id": "@ test/pkg1@1.0.54",
"_npmVersion": "6.1.0",
"_nodeVersion": "9.9.0",
"_npmUser": {},
"dist": {
"integrity": "sha512-JlXWpLtMUBAqvVZBvH7UVLhXkGE1ctmXbDjbH/l0zMuG7wVzQ7GshTYvD/b5C+G2vOL2oiIS1RtayA/kKkTwKw==",
"shasum": "29c55c52c1e76e966e706165e5b9f22e32aa9f22",
"tarball": "http://localhost:4873/@test/pkg1/-/@test/pkg1-1.0.54.tgz"
}
}
},
"readme": "# test",
"_attachments": {
"@test/pkg1-1.0.54.tgz": {
"content_type": "application/octet-stream",
"data": "H4sIAAAAAAAAE+y9Z5PjyJIgOJ ...",
"length": 33112
}
},
"time": {}
}
### Publisher
You can access to the package publisher information in the `content` of a webhook using the `publisher` object.
See below the `publisher` object type:
{
name: string,
groups: string[],
real_groups: string[]
}
An example:
notify:
method: POST
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"New package published: * {{ name }}*. Publisher name: * {{ publisher.name }} *.","notify":true,"message_format":"text"}'
**Note:** it's not possible to get the publisher information if the `package.json` file already has the `publisher` property.
### Package Published
You can acces to the package is being published with the keyword `{{publishedPackage}}` as follows.
{{ publisher.name }} has published {{publishedPackage}}"}
## Configuration
| Property | Type | Required | Support | Default | Description |
@ -43,4 +155,4 @@ notify:
| packagePatternFlags | string | No | all | | Any flags to be used with the regular expression |
| headers | array/object | Yes | all | | If this endpoint requires specific headers, set them here as an array of key: value objects. |
| endpoint | string | Yes | all | | set the URL endpoint for this call |
| content | string | Yes | all | | any [handlebar](https://handlebarsjs.com/) expressions |
| content | string | Yes | all | | any [Handlebar](https://handlebarsjs.com/) expressions |

@ -2,11 +2,13 @@
id: notifications
title: "Notifications"
---
Notify was built primarily to use with Slack's Incoming webhooks, but will also deliver a simple payload to any endpoint. Currently only active for `publish` / `create` commands.
Notify was built primarily to use with Slack's Incoming webhooks, but will also deliver a simple payload to any endpoint. Currently only active for `npm publish` command.
## Usage
An example with a **HipChat** and **Google Hangouts Chat** hook:
An example with a **HipChat**, **Stride** and **Google Hangouts Chat** hook:
> Verdaccio supports any API, feel free to ad more examples.
#### Single notification
@ -32,8 +34,118 @@ notify:
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"New package published: * {{ name }}*","notify":true,"message_format":"text"}'
'example-stride':
method: POST
headers: [{'Content-Type': 'application/json'}, {'authorization': 'Bearer secretToken'}]
endpoint: https://api.atlassian.com/site/{cloudId}/conversation/{conversationId}/message
content: '{"body": {"version": 1,"type": "doc","content": [{"type": "paragraph","content": [{"type": "text","text": "New package published: * {{ name }}* Publisher name: * {{ publisher.name }}"}]}]}}'
```
## Template
We use [Handlebars](https://handlebarsjs.com/) as main template engine.
### Format Examples
# iterate all versions
{{ name }}{{#each versions}} v{{version}}{{/each}}`"}
# publisher and `dist-tag` package published
{{ publisher.name }} has published {{publishedPackage}}"}
### Properties
List of properties accesible via template
* Metadata
* Publisher (who is publishing)
* Package Published (package@1.0.0)
### Metadata
Package metadata that the template has access
{
"_id": "@test/pkg1",
"name": "@test/pkg1",
"description": "",
"dist-tags": {
"beta": "1.0.54"
},
"versions": {
"1.0.54": {
"name": "@test/pkg1",
"version": "1.0.54",
"description": "some description",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": {
"name": "Author Name",
"email": "author@domain.com"
},
"license": "MIT",
"dependencies": {
"webpack": "4.12.0"
},
"readmeFilename": "README.md",
"_id": "@ test/pkg1@1.0.54",
"_npmVersion": "6.1.0",
"_nodeVersion": "9.9.0",
"_npmUser": {},
"dist": {
"integrity": "sha512-JlXWpLtMUBAqvVZBvH7UVLhXkGE1ctmXbDjbH/l0zMuG7wVzQ7GshTYvD/b5C+G2vOL2oiIS1RtayA/kKkTwKw==",
"shasum": "29c55c52c1e76e966e706165e5b9f22e32aa9f22",
"tarball": "http://localhost:4873/@test/pkg1/-/@test/pkg1-1.0.54.tgz"
}
}
},
"readme": "# test",
"_attachments": {
"@test/pkg1-1.0.54.tgz": {
"content_type": "application/octet-stream",
"data": "H4sIAAAAAAAAE+y9Z5PjyJIgOJ ...",
"length": 33112
}
},
"time": {}
}
### Publisher
You can access to the package publisher information in the `content` of a webhook using the `publisher` object.
See below the `publisher` object type:
{
name: string,
groups: string[],
real_groups: string[]
}
An example:
notify:
method: POST
headers: [{'Content-Type': 'application/json'}]
endpoint: https://usagge.hipchat.com/v2/room/3729485/notification?auth_token=mySecretToken
content: '{"color":"green","message":"New package published: * {{ name }}*. Publisher name: * {{ publisher.name }} *.","notify":true,"message_format":"text"}'
**Note:** it's not possible to get the publisher information if the `package.json` file already has the `publisher` property.
### Package Published
You can acces to the package is being published with the keyword `{{publishedPackage}}` as follows.
{{ publisher.name }} has published {{publishedPackage}}"}
## Configuration
| Property | Type | Required | Support | Default | Description |
@ -43,4 +155,4 @@ notify:
| packagePatternFlags | string | No | all | | Any flags to be used with the regular expression |
| headers | array/object | Yes | all | | If this endpoint requires specific headers, set them here as an array of key: value objects. |
| endpoint | string | Yes | all | | set the URL endpoint for this call |
| content | string | Yes | all | | any [handlebar](https://handlebarsjs.com/) expressions |
| content | string | Yes | all | | any [Handlebar](https://handlebarsjs.com/) expressions |