Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pubst

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pubst - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

6

CHANGELOG.md

@@ -0,1 +1,7 @@

## v0.4.0 - Sep 21 2018
+ Adds `validator` option to topic configuration.
## v0.3.0 - Sep 11 2018
+ Adds topic configuration
## v0.2.1 - Apr 27 2018

@@ -2,0 +8,0 @@ + Adds documentation

47

lib/pubst.js

@@ -100,3 +100,6 @@ 'use strict';

doPrime: true,
allowRepeats: false
allowRepeats: false,
validator: function validator() {
return { valid: true, messages: [] };
}
};

@@ -122,2 +125,14 @@

function buildValidationErrorMessage(topicName, validationMessages, payload) {
var messages = '';
if (Array.isArray(validationMessages) && validationMessages.length > 0) {
var s = validationMessages.length === 1 ? '' : 's';
messages = 'Message' + s + ':\n ' + validationMessages.join('\n ');
}
var payloadString = 'Received Payload:\n ' + JSON.stringify(payload, null, 2);
return 'Validation failed for topic \'' + topicName + '\'.\n ' + messages + '\n ' + payloadString;
}
/**

@@ -152,2 +167,14 @@ * @summary Configure a new topic.

* </li>
* <li>
* `validator` - Validation function to assert that published values are valid before sent to subscribers.
* Function will be called with each published payload.
* If a payload fails validation, an error will be thrown during the `publish` call.
* The function should return something like:<br/>
* <code>
* {
* valid: false,
* messages: ['Message 1', 'Message 2']
* }
* </code>
* </li>
* </ul>

@@ -167,2 +194,9 @@ * </p>

if (isDefined(topic.default)) {
var defaultValidationResult = topic.validator(topic.default);
if (!defaultValidationResult.valid) {
warn('\'' + topic.name + '\' has been configured with a default value that does not pass validation.\nComplete message:\n' + buildValidationErrorMessage(topic.name, defaultValidationResult.messages, topic.default));
}
}
topics[topic.name] = topic;

@@ -288,2 +322,13 @@ }

var topicConfig = getTopicConfig(topic);
if (!topicConfig.eventOnly) {
var validationResult = topicConfig.validator(payload);
if (!validationResult || !validationResult.valid) {
var messages = validationResult ? validationResult.messages : [];
throw new Error(buildValidationErrorMessage(topic, messages, payload));
}
}
store[topic] = payload;

@@ -290,0 +335,0 @@ var subs = allSubsFor(topic);

6

package.json
{
"name": "pubst",
"version": "0.3.0",
"version": "0.4.0",
"description": "A slightly opinionated pub/sub event emitter for JavaScript.",

@@ -41,3 +41,3 @@ "main": "lib/pubst.js",

"clear-require": "2.0.0",
"eslint": "5.5.0",
"eslint": "5.6.0",
"jsdoc": "3.5.5",

@@ -47,5 +47,5 @@ "mocha": "5.2.0",

"shx": "0.3.2",
"sinon": "6.2.0",
"sinon": "6.3.4",
"sinon-chai": "3.2.0"
}
}

@@ -114,2 +114,3 @@ # Pubst

+ This can be overridden by subscribers.
+ `validator` - A validation function to assert that published values are valid before they are sent to subscribers.

@@ -123,3 +124,18 @@ #### Examples

default: false,
doPrime: true
doPrime: true,
validator: payload => {
const valid = typeof payload === 'boolean';
if (!valid) {
return {
valid,
messages: [
'Value must be a boolean'
]
};
}
return {
valid
};
}
},

@@ -130,3 +146,6 @@ {

allowRepeats: true,
doPrime: false
doPrime: false,
validator: payload => ({
valid: typeof payload === 'number'
})
},

@@ -133,0 +152,0 @@ {

@@ -88,3 +88,4 @@ /**

doPrime: true,
allowRepeats: false
allowRepeats: false,
validator: () => ({valid: true, messages: []})
};

@@ -116,2 +117,14 @@

function buildValidationErrorMessage(topicName, validationMessages, payload) {
let messages = '';
if (Array.isArray(validationMessages) && validationMessages.length > 0) {
const s = validationMessages.length === 1 ? '' : 's';
messages = `Message${s}:\n ${validationMessages.join('\n ')}`;
}
const payloadString = 'Received Payload:\n ' + JSON.stringify(payload, null, 2);
return `Validation failed for topic '${topicName}'.\n ${messages}\n ${payloadString}`;
}
/**

@@ -146,2 +159,14 @@ * @summary Configure a new topic.

* </li>
* <li>
* `validator` - Validation function to assert that published values are valid before sent to subscribers.
* Function will be called with each published payload.
* If a payload fails validation, an error will be thrown during the `publish` call.
* The function should return something like:<br/>
* <code>
* {
* valid: false,
* messages: ['Message 1', 'Message 2']
* }
* </code>
* </li>
* </ul>

@@ -161,2 +186,11 @@ * </p>

if (isDefined(topic.default)) {
const defaultValidationResult = topic.validator(topic.default);
if (!defaultValidationResult.valid) {
warn(`'${topic.name}' has been configured with a default value that does not pass validation.
Complete message:
${buildValidationErrorMessage(topic.name, defaultValidationResult.messages, topic.default)}`);
}
}
topics[topic.name] = topic;

@@ -275,2 +309,13 @@

const topicConfig = getTopicConfig(topic);
if (!topicConfig.eventOnly) {
const validationResult = topicConfig.validator(payload);
if (!validationResult || !validationResult.valid) {
const messages = validationResult ? validationResult.messages : [];
throw new Error(buildValidationErrorMessage(topic, messages, payload));
}
}
store[topic] = payload;

@@ -277,0 +322,0 @@ const subs = allSubsFor(topic);

@@ -532,5 +532,97 @@ const clearRequire = require('clear-require');

});
describe('validator', () => {
it('allows all values by default', () => {
pubst.addTopics([
{
name: TEST_TOPIC_1,
doPrime: false
}
]);
const handler1 = sinon.spy();
pubst.subscribe(TEST_TOPIC_1, handler1);
pubst.publish(TEST_TOPIC_1, 'Hello');
pubst.publish(TEST_TOPIC_1, 12);
clock.tick(1);
expect(handler1).to.have.been.calledWith('Hello', TEST_TOPIC_1);
expect(handler1).to.have.been.calledWith(12, TEST_TOPIC_1);
});
it('fails when valid is false', () => {
pubst.addTopic({
name: TEST_TOPIC_1,
doPrime: false,
validator: () => ({valid: false, messages: ['message 1', 'message 2']})
});
const handler1 = sinon.spy();
pubst.subscribe(TEST_TOPIC_1, handler1);
try {
pubst.publish(TEST_TOPIC_1, 'Hello');
throw new Error('This publish should have thrown');
} catch (e) {
const {message} = e;
expect(message).to.contain('message 1');
expect(message).to.contain('message 2');
expect(message).to.contain(TEST_TOPIC_1);
expect(message).to.contain('Hello');
}
clock.tick(1);
expect(handler1).not.to.have.been.called;
});
it('fails when result is falsey', () => {
pubst.addTopic({
name: TEST_TOPIC_1,
doPrime: false,
validator: () => false
});
const handler1 = sinon.spy();
pubst.subscribe(TEST_TOPIC_1, handler1);
try {
pubst.publish(TEST_TOPIC_1, 'Hello');
throw new Error('This publish should have thrown');
} catch (e) {
const {message} = e;
expect(message).to.contain(TEST_TOPIC_1);
expect(message).to.contain('Hello');
}
clock.tick(1);
expect(handler1).not.to.have.been.called;
});
it('allows payloads when valid is true', () => {
pubst.addTopic({
name: TEST_TOPIC_1,
doPrime: false,
validator: () => ({valid: true})
});
const handler1 = sinon.spy();
pubst.subscribe(TEST_TOPIC_1, handler1);
pubst.publish(TEST_TOPIC_1, 'Hello');
clock.tick(1);
expect(handler1).to.have.been.calledOnceWith('Hello', TEST_TOPIC_1);
});
});
});
describe('publish & subscribe', () => {

@@ -537,0 +629,0 @@ it('calls the subscriber if the topic already has a set value', () => {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc