diff --git a/docs/api/schema/resolvers.md b/docs/api/schema/resolvers.md index 13c8066bce..6a74a7ed0b 100644 --- a/docs/api/schema/resolvers.md +++ b/docs/api/schema/resolvers.md @@ -315,7 +315,7 @@ app.service('users').hooks({
-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. diff --git a/packages/schema/src/hooks/resolve.ts b/packages/schema/src/hooks/resolve.ts index f7356fd415..6bb53f1e8b 100644 --- a/packages/schema/src/hooks/resolve.ts +++ b/packages/schema/src/hooks/resolve.ts @@ -81,28 +81,30 @@ export const resolveData = export const resolveResult =(...resolvers: Resolver []) => { 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) @@ -148,13 +150,15 @@ export const setDispatch = (current: any, dispatch: any) => { return dispatch } -export const resolveDispatch = +export const resolveExternal = (...resolvers: Resolver []) => - 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) @@ -188,7 +192,7 @@ export const resolveDispatch = } } -export const resolveExternal = resolveDispatch +export const resolveDispatch = resolveExternal type ResolveAllSettings = { data?: {