Skip to content

Commit

Permalink
Introduce result visiting (#1718)
Browse files Browse the repository at this point in the history
* introduce result visiting

This changes introduces a few generic functions for revisiting data, demonstrating use of some of them within the RenameTypes transform.

= visitData can be used to recursively visit an ExecutionResult (or any object)

it takes two functions, one executed when entering the object, one when leaving

= visitResult can be used to visit a result by with a resultVisitorMap and/or an errorVisitorMap

visitResult visits the result using the request, so it knows the object type for every object within the map, as long as the result includes __typename info when requesting abstract types, and also knows the field name for each aliased key within the object.

* it executes the correct visitor from each objectVisitorMap included within the resultVisitorMap depending on the object type and field name
* it executes object visitors on the object itself when entering and leaving the object using the values from the __enter and __leave dummy field names within the objectVisitorMap
* it executes any visitors for leaf types included within the resultVisitorMap to provide a simple mechanism of visiting all fields of a certain leaf type

errors can also be visited -- these are meant to provide opportunities for transforming a GraphQLError, including the path, and so, if an errorVisitorMap is included, error visitors from the map will be collected for each field found in the path of the original error.

* Add result transforming to bundled transformers

These transformers now can utilize the visitData method to recursively visit the result and modify it as necessary by checking the __typename value. State about fields can be saved within the transformation context.

Adds result wrapping capability to the following generic transformers

= TransformCompositeFields
= TransformInterfaceFields
= TransformObjectFields
= TransformRootFields
= ExtendSchema
= MapFields

Adds result visiting usage to the following transfromers
= WrapFields
= WrapType
= HoistField
  • Loading branch information
yaacovCR committed Jul 5, 2020
1 parent 895f9a4 commit 6dc5e02
Show file tree
Hide file tree
Showing 15 changed files with 1,415 additions and 171 deletions.
3 changes: 2 additions & 1 deletion packages/utils/src/Interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ export interface Transform {

export type FieldNodeMapper = (
fieldNode: FieldNode,
fragments: Record<string, FragmentDefinitionNode>
fragments: Record<string, FragmentDefinitionNode>,
transformationContext: Record<string, any>
) => SelectionNode | Array<SelectionNode>;

export type FieldNodeMappers = Record<string, Record<string, FieldNodeMapper>>;
Expand Down
1 change: 1 addition & 0 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ export * from './implementsAbstractType';
export * from './errors';
export * from './toConfig';
export * from './observableToAsyncIterable';
export * from './visitResult';

0 comments on commit 6dc5e02

Please sign in to comment.