Skip to content

Commit

Permalink
fix(schema): Ensure that resolveResult and resolveExternal are run as…
Browse files Browse the repository at this point in the history
… around hooks (#3032)
  • Loading branch information
daffl authored Jan 31, 2023
1 parent 1ac18a7 commit 71942f4
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 24 deletions.
2 changes: 1 addition & 1 deletion docs/api/schema/resolvers.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ app.service('users').hooks({

<BlockQuote type="warning" label="important">

In order to get the safe data from resolved associations **all services** involved need the `schemaHooks.resolveExternal` (or `resolveAll`) hook registered even if it does not need a resolver (`schemaHooks.resolveExternal()`).
In order to get the safe data from resolved associations **all services** involved need the `schemaHooks.resolveExternal` hook registered even if it does not need a resolver (`schemaHooks.resolveExternal()`).

`schemaHooks.resolveExternal` should be registered first when used as an `around` hook or last when used as an `after` hook so that it gets the final result data.

Expand Down
50 changes: 27 additions & 23 deletions packages/schema/src/hooks/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,28 +81,30 @@ export const resolveData =
export const resolveResult = <H extends HookContext>(...resolvers: Resolver<any, H>[]) => {
const virtualProperties = new Set(resolvers.reduce((acc, current) => acc.concat(current.virtualNames), []))

return async (context: H, next?: NextFunction) => {
if (typeof next === 'function') {
const { $resolve, $select: select, ...query } = context.params?.query || {}
const $select = Array.isArray(select) ? select.filter((name) => !virtualProperties.has(name)) : select
const resolve = {
originalContext: context,
...context.params.resolve,
properties: $resolve || select
}
return async (context: H, next: NextFunction) => {
if (typeof next !== 'function') {
throw new Error('The resolveResult hook must be used as an around hook')
}

context.params = {
...context.params,
resolve,
query: {
...query,
...($select ? { $select } : {})
}
}
const { $resolve, $select: select, ...query } = context.params?.query || {}
const $select = Array.isArray(select) ? select.filter((name) => !virtualProperties.has(name)) : select
const resolve = {
originalContext: context,
...context.params.resolve,
properties: $resolve || select
}

await next()
context.params = {
...context.params,
resolve,
query: {
...query,
...($select ? { $select } : {})
}
}

await next()

const ctx = getContext(context)
const status = context.params.resolve
const { isPaginated, data } = getResult(context)
Expand Down Expand Up @@ -148,13 +150,15 @@ export const setDispatch = (current: any, dispatch: any) => {
return dispatch
}

export const resolveDispatch =
export const resolveExternal =
<H extends HookContext>(...resolvers: Resolver<any, H>[]) =>
async (context: H, next?: NextFunction) => {
if (typeof next === 'function') {
await next()
async (context: H, next: NextFunction) => {
if (typeof next !== 'function') {
throw new Error('The resolveExternal hook must be used as an around hook')
}

await next()

const ctx = getContext(context)
const existingDispatch = getDispatch(context.result)

Expand Down Expand Up @@ -188,7 +192,7 @@ export const resolveDispatch =
}
}

export const resolveExternal = resolveDispatch
export const resolveDispatch = resolveExternal

type ResolveAllSettings<H extends HookContext> = {
data?: {
Expand Down

0 comments on commit 71942f4

Please # to comment.