Created
June 26, 2020 18:28
-
-
Save KidkArolis/98c5305dfe3c0f259d34cc1061eeb522 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Install this hook in app.hooks.js | |
module.exports = app => { | |
app.hooks({ | |
before: { | |
all: [ | |
addParamsForward() | |
] | |
} | |
}) | |
} | |
Then use whenever you want to forward params, e.g. in a hook: | |
const { app, params } = context | |
app.service('another-service').find({ query: { id: 'x' }, ...params.forward() }) | |
app.service('another-service').get(id, params.forward()) | |
app.service('another-service').patch(id, {smth: 'x' }, params.forward()) | |
*/ | |
const { has } = require('lodash') | |
const paramsSeen = new WeakSet() | |
module.exports = function addParamsForward() { | |
return context => { | |
if (paramsSeen.has(context.params)) { | |
throw new Error( | |
`Params should never be shared across services, always use params.forward(). Fix calls to ${context.path}#${context.method}`, | |
) | |
} | |
paramsSeen.add(context.params) | |
context.params.forward = ({ only, omit = [] } = {}) => { | |
const { params } = context | |
const forwardedParams = { | |
caller: { | |
path: context.path, | |
method: context.method, | |
type: context.type, | |
}, | |
requestId: context.params.requestId, | |
forwarded: true, | |
} | |
;( | |
only || [ | |
'authenticated', | |
'user', | |
'transaction', | |
'skipEvents', | |
'permissions', | |
] | |
).forEach(param => { | |
if (has(params, param) && !omit.includes(param)) { | |
forwardedParams[param] = params[param] | |
} | |
}) | |
if (forwardedParams.authenticated) { | |
forwardedParams.authentication = params.authentication | |
} | |
return forwardedParams | |
} | |
} | |
} |
Because you can only spread properties in an object:
let a = { x: 'y' }
let b = { ...a }
Or you can spread arrays as arguments:
let a = ['x', 'y', 'z']
example(...a)
You can't spread an object as arguments:
// not valid!!
// throws non-callable @@iterator / is not iterable
let a = { x: 'y' }
example(...a)
In Feathers, params
is an object, params.forward() is also an object, so:
// invalid
service.get(1, ...params)
service.get(1, ...params.forward())
// valid
service.get(1, params)
service.get(1, params.forward())
service.get(1, { ...params })
service.get(1, { ...params.forward() })
// invalid
service.find(...params)
service.find(...params.forward())
// valid
service.find({ query: { email: 'x', }, ...params })
service.find({ query: { email: 'x', }, ...params.forward() })
That's it.
Thank you so much.
Hello @KidkArolis,
I noticed that in the forwardedParams.caller.type
is always before
, is that intended? I would imagine that it should be whoever called the forward()
?
// I have a hook x at the after-remove hook of service y
// now I call to remove
app.service('y').remove(id)
// within hook x, it calls service z (note hook x is in after-remove hook of service y)
app.service('z').remove(anotherId, params.forward());
So when I logs out the forwardedParams
before the return
in addParamsForward()
, the caller.type
is before
.
@bwgjoseph you're right, it could be fixed by readding addParamsForward() hook in after all, so that it uses updated the closed over context when computing forwardedParams.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@KidkArolis,
ah! it works, but still can't figure out why using
spread ...params.forward()
will trigger thenon-callable @@iterator
error. Other than that, it looks good now.If you know what's causing the error, do let me know.
Thanks!