diff --git a/lib/core.js b/lib/core.js index b64b063..941be4a 100644 --- a/lib/core.js +++ b/lib/core.js @@ -3,7 +3,13 @@ const feathers = require('@feathersjs/feathers'); const { _ } = require('@feathersjs/commons'); const SYNC = Symbol('feathers-sync/enabled'); -const defaultEvents = ['created', 'updated', 'removed', 'patched']; +const eventMap = { + created: 'create', + updated: 'update', + patched: 'patch', + removed: 'remove' +}; +const defaultEvents = Object.keys(eventMap); const getServiceOptions = service => { if (typeof feathers.getServiceOptions === 'function') { return feathers.getServiceOptions(service); @@ -12,6 +18,20 @@ const getServiceOptions = service => { return {}; }; +const constructContext = (app, path, event, data, context = {}) => { + const id = (typeof data === 'object' && !Array.isArray(data)) + ? (data._id || data.id) + : undefined; + return Object.assign({ + path, + id, + method: eventMap[event], + params: {}, + result: data, + event + }, context); +}; + module.exports = app => { if (app[SYNC]) { return; @@ -25,6 +45,7 @@ module.exports = app => { app.on('sync-in', (rawData) => { const { event, path, data, context } = app.sync.deserialize(rawData); + if (!path) return; const service = app.service(path); const hook = context ? Object.assign({ app, service }, context) @@ -53,9 +74,10 @@ module.exports = app => { } const serializedContext = ctx && typeof ctx.toJSON === 'function' ? ctx.toJSON() : ctx; + const constructedContext = constructContext(app, path, event, data, serializedContext); const context = ctx && (ctx.app === app || ctx.service === service) - ? _.omit(serializedContext, 'app', 'service', 'self') - : serializedContext; + ? _.omit(constructedContext, 'app', 'service', 'self') + : constructedContext; debug(`Sending sync-out event '${path} ${event}'`); diff --git a/test/core.test.js b/test/core.test.js index d4ef56a..1951e15 100644 --- a/test/core.test.js +++ b/test/core.test.js @@ -31,6 +31,7 @@ describe('feathers-sync core tests', () => { path: 'todo', data: message, context: { + id: undefined, arguments: [message, {}], data: message, params: {}, @@ -80,13 +81,47 @@ describe('feathers-sync core tests', () => { app.service('todo').create({ message }); }); + it('sends sync-out for manual emits', done => { + const message = { message: 'This is a test', id: 1 }; + + app.once('sync-out', data => { + try { + assert.deepStrictEqual(data, { + event: 'created', + path: 'todo', + data: message, + context: { + id: 1, + params: {}, + method: 'create', + event: 'created', + path: 'todo', + result: message + } + }); + done(); + } catch (error) { + done(error); + } + }); + + app.service('todo').emit('created', message); + }); + it('sends sync-out for custom events', done => { app.once('sync-out', data => { assert.deepStrictEqual(data, { event: 'custom', path: 'todo', data: 'testing', - context: undefined + context: { + path: 'todo', + id: undefined, + method: undefined, + params: {}, + result: 'testing', + event: 'custom' + } }); done(); });