Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 1x 21x 50x 23x 100x 20x 1x 100x 16x 16x 14x 12x 16x 1x 25x | import { push } from 'object-path'
import deepEqual from 'deep-equal'
import { nextTick, skip } from './utils'
import { allResolvers } from './allResolvers'
import { pipeResolvers } from './pipeResolvers'
import { combineResolvers } from './combineResolvers'
import { contextMustBeObject } from './miscResolvers'
/**
* Piping resolver to save current value and reference to dependees cache.
*/
const saveDependee = combineResolvers(
contextMustBeObject,
(value, args, context, info) => (
push(context, '_dependees', { path: info.path, value }), value
)
)
/**
* Identify a resolver as being a dependee, so other sibling
* field resolvers might depend on the value resolved by this one.
*
* Basically, it will polute "info" during resolving
* to insert the resolved value and path to this resolver.
*
* @param {Function} resolver Resolver implementation.
* @return {Promise}.
*/
export const isDependee = resolver => (root, ...args) =>
saveDependee(resolver(root, ...args), ...args)
/**
* Make sure the field name exists on the parent type.
*
* @param {String} dependeeName The name of the dependee to check the parent against
* @return {Function} Resolver to error when no dependee is found.
*/
const dependeeExists = dependeeName => (
root,
args,
context,
{ fieldName, parentType: { _fields, name: parent } }
) =>
!_fields[dependeeName]
? new Error(
`Cannot get dependee "${dependeeName}" from field "${fieldName}" on type "${parent}"`
)
: skip
/**
* Resolver implementation to retrieve the resolved value of a dependee sibling field.
*
* @param {String} dependeeName The name of the dependee this resolver depends on.
* @param {Function} resolver Resolver implemenatation.
* @return {Function} dependee resolver.
*/
export const resolveDependee = dependeeName =>
combineResolvers(
contextMustBeObject,
dependeeExists(dependeeName),
pipeResolvers(
// Make sure dependent resolvers occur after
// dependees have been initialized.
nextTick,
(root, args, context, info) => {
const { _dependees = [] } = context
// Find any currently resolved dependee.
const resolved = _dependees
.filter(({ path: { prev } }) => deepEqual(prev, info.path.prev))
.find(({ path: { key } }) => key === dependeeName)
// Run field resolution, if resolved value was not found.
return resolved === skip
? info.parentType._fields[dependeeName].resolve(
root,
args,
context,
info
)
: resolved.value
}
)
)
/**
* Resolver implementation to retrieve the resolved value of multiple dependee sibling fields.
*
* @param {[String]} dependeeNames Array of names of the dependees this resolver depends on.
* @param {Function} resolver Resolver implemenatation.
* @return {Function} dependee resolver.
*/
export const resolveDependees = dependeeNames =>
combineResolvers(
contextMustBeObject,
allResolvers(dependeeNames.map(resolveDependee))
)
|