@everestate/serverless-router
Advanced tools
Comparing version 0.4.0 to 0.5.0
@@ -34,5 +34,13 @@ const BasePlugin = require('../../BasePlugin'); | ||
static match(dayIndex) { | ||
return date => (date.getDay() === dayIndex ? {} : null); | ||
return date => (date.getDay() === dayIndex ? this.ctx(date) : null); | ||
} | ||
static ctx(date) { | ||
return { | ||
day: date.getDay(), | ||
month: date.getMonth() + 1, | ||
year: date.getFullYear(), | ||
}; | ||
} | ||
static get pluginName() { return 'weekday'; } | ||
@@ -39,0 +47,0 @@ } |
@@ -39,16 +39,21 @@ const ServerlessRouter = require('../ServerlessRouter'); | ||
describe('dispatch', () => { | ||
test('returns callback value', () => { | ||
test('resolves on match', () => { | ||
const router = subj(); | ||
router.weekday.saturday((...args) => ({ saturday: true, args })); | ||
router.mismatch(() => ({ mismatched: true })); | ||
expect(router.dispatch(new Date('2014-08-16'))).toEqual({ | ||
return expect(router.dispatch(new Date('2014-08-16'))).resolves.toEqual({ | ||
saturday: true, | ||
args: [ | ||
{}, | ||
{ day: 6, month: 8, year: 2014 }, | ||
new Date('2014-08-16'), | ||
], | ||
}); | ||
expect(router.dispatch(new Date('2017-09-05'))).toEqual({ mismatched: true }); | ||
}); | ||
test('rejects on mismatch', () => { | ||
const router = subj(); | ||
router.weekday.saturday((...args) => ({ saturday: true, args })); | ||
router.mismatch(() => Promise.reject(new Error('My Error on mismatch'))); | ||
return expect(router.dispatch(new Date('2017-09-05'))).rejects.toEqual(new Error('My Error on mismatch')); | ||
}); | ||
test('respects the order of the routes #1', () => { | ||
@@ -58,3 +63,3 @@ const router = subj(); | ||
router.type.number(() => ({ type: 'number' })); | ||
expect(router.dispatch(42)).toEqual({ even: true }); | ||
return expect(router.dispatch(42)).resolves.toEqual({ even: true }, 42); | ||
}); | ||
@@ -67,34 +72,69 @@ | ||
router.evenodd.even(() => ({ even: true })); | ||
expect(router.dispatch(42)).toEqual({ type: 'number' }); | ||
return expect(router.dispatch(42)).resolves.toEqual({ type: 'number' }, 42); | ||
}); | ||
test('throws error when there are no routes', () => | ||
expect(() => subj().dispatch('42')).toThrowErrorMatchingSnapshot()); | ||
test('rejects with "route not found" error when there are no routes', () => | ||
expect(subj().dispatch('42')).rejects.toEqual(new Error('ServerlessRouter can\'t find the route'))); | ||
test('throws error when route is not found', () => { | ||
test('rejects with "route not found" when route is not found', () => { | ||
const router = subj(); | ||
router.evenodd.even((event, context, callback) => callback(null, { even: true })); | ||
router.type.number((event, context, callback) => callback(null, { type: 'number' })); | ||
expect(() => subj().dispatch('42')).toThrowErrorMatchingSnapshot(); | ||
return expect(subj().dispatch('42')).rejects.toEqual(new Error('ServerlessRouter can\'t find the route')); | ||
}); | ||
}); | ||
describe('mismatch(handler)', () => { | ||
test('sets custom handler to call when dispatcher can\'t match the route', (done) => { | ||
test('resolves when there are no rejecting middleware', () => { | ||
const router = subj(); | ||
router.mismatch((event, context, callback) => | ||
callback(null, { | ||
statusCode: '418', | ||
body: JSON.stringify({ message: 'My custom mismatch handler' }), | ||
})); | ||
router.dispatch('42', {}, (error, payload) => { | ||
expect(error).toEqual(null); | ||
expect(payload).toEqual({ | ||
statusCode: '418', | ||
body: '{"message":"My custom mismatch handler"}', | ||
}); | ||
done(); | ||
router.use(date => Promise.resolve({ foo: 'bar', dateFoo: date })); | ||
router.weekday.use(date => Promise.resolve({ baz: 'qux', dateBaz: date })); | ||
router.weekday.friday((ctx, date) => ({ friday: true, date, ctx })); | ||
return expect(router.dispatch(new Date('1909-01-01'))).resolves.toEqual({ | ||
friday: true, | ||
date: new Date('1909-01-01'), | ||
ctx: { | ||
foo: 'bar', | ||
dateFoo: new Date('1909-01-01'), | ||
baz: 'qux', | ||
dateBaz: new Date('1909-01-01'), | ||
day: 5, | ||
month: 1, | ||
year: 1909, | ||
}, | ||
}); | ||
}); | ||
test('rejects when there are rejecting middleware', () => { | ||
const router = subj(); | ||
router.use(date => Promise.resolve({ foo: 'bar', dateFoo: date })); | ||
router.weekday.use(() => Promise.reject(new Error('Ooops'))); | ||
router.weekday.friday((ctx, date) => ({ friday: true, date, ctx })); | ||
return expect(router.dispatch(new Date('1909-01-01'))).rejects.toEqual(new Error('Ooops')); | ||
}); | ||
}); | ||
describe('mismatch(handler): callback', () => { | ||
test('sets custom handler to invoke callback when dispatcher can\'t match the route', done => | ||
subj() | ||
.mismatch((event, context, callback) => | ||
callback(null, { | ||
statusCode: '418', | ||
body: JSON.stringify({ message: 'My custom mismatch handler' }), | ||
})) | ||
.dispatch('42', {}, (error, payload) => { | ||
expect(error).toEqual(null); | ||
expect(payload).toEqual({ | ||
statusCode: '418', | ||
body: '{"message":"My custom mismatch handler"}', | ||
}); | ||
done(); | ||
})); | ||
}); | ||
describe('mismatch(handler): promise', () => { | ||
test('sets custom handler to return rejected promise when dispatcher can\'t match the route', () => { | ||
const router = subj() | ||
.mismatch(() => Promise.reject(new Error('Error from my custom mismatch handler'))); | ||
return expect(router.dispatch('42')).rejects.toEqual(new Error('Error from my custom mismatch handler')); | ||
}); | ||
}); | ||
}); |
@@ -6,2 +6,3 @@ const Route = require('./Route'); | ||
this.routes = routes; | ||
this.middlewares = []; | ||
} | ||
@@ -18,2 +19,7 @@ | ||
use(...middlewares) { | ||
this.middlewares.push(...middlewares); | ||
return this; | ||
} | ||
static get pluginName() { | ||
@@ -20,0 +26,0 @@ return this.name.toLowerCase(); |
@@ -14,4 +14,4 @@ class Route { | ||
respond(...args) { | ||
return this.callback.apply(null, [this.ctx || {}, ...args]); | ||
respond(ctx, ...args) { | ||
return this.callback.apply(null, [{ ...ctx, ...this.ctx }, ...args]); | ||
} | ||
@@ -18,0 +18,0 @@ } |
class ServerlessRouter { | ||
constructor(plugins) { | ||
this.routes = []; | ||
this.mismatchHandler = null; | ||
this.middlewares = []; | ||
this.mismatchHandler = undefined; | ||
@@ -28,4 +29,10 @@ this.initializePlugins(plugins); | ||
use(...middlewares) { | ||
this.middlewares.push(...middlewares); | ||
return this; | ||
} | ||
mismatch(handler) { | ||
this.mismatchHandler = handler; | ||
return this; | ||
} | ||
@@ -37,3 +44,9 @@ | ||
if (matchingRoute) { | ||
return matchingRoute.respond(...args); | ||
return this | ||
.middlewares.concat(this[matchingRoute.pluginName].middlewares) | ||
.reduce((p, fn) => p.then(res => fn(...args).then(([]).concat.bind(res))), Promise.resolve([])) | ||
.then((results) => { | ||
const ctx = results.reduce((acc, obj) => ({ ...acc, ...obj }), {}); | ||
return matchingRoute.respond(ctx, ...args); | ||
}); | ||
} | ||
@@ -44,3 +57,3 @@ | ||
} | ||
throw new Error('ServerlessRouter can\'t find the route'); | ||
return Promise.reject(new Error('ServerlessRouter can\'t find the route')); | ||
} | ||
@@ -47,0 +60,0 @@ } |
{ | ||
"name": "@everestate/serverless-router", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "Serverless, minimalist, pluggable, universal router.", | ||
@@ -34,8 +34,8 @@ "keywords": [ | ||
"devDependencies": { | ||
"eslint": "^5.12.1", | ||
"eslint": "^5.15.3", | ||
"eslint-config-airbnb-base": "^13.1.0", | ||
"eslint-plugin-import": "^2.15.0", | ||
"eslint-plugin-jest": "^22.1.3", | ||
"jest": "^23.6.0" | ||
"eslint-plugin-import": "^2.16.0", | ||
"eslint-plugin-jest": "^22.4.1", | ||
"jest": "^24.5.0" | ||
} | ||
} |
@@ -72,2 +72,16 @@ # @everestate/serverless-router [![npm version](https://badge.fury.io/js/%40everestate%2Fserverless-router.svg)](https://www.npmjs.com/package/@everestate/serverless-router) | ||
## Middleware | ||
When middleware are set, they will be called before each matched route in order they registered. | ||
Middleware callback is expected to return `Promise` and could be defined with `use`: | ||
``` | ||
router.use((event, context, callback) => { | ||
const { source } = event; | ||
if (source === 'bad source') { | ||
return Promise.reject(new Error('Bad event source')); | ||
} | ||
return Promise.resolve(); | ||
}) | ||
``` | ||
## Plugins | ||
@@ -74,0 +88,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
412
93
23504
20