Skip to content

Commit f8625da

Browse files
feat: support fragment parsing in parseFieldNodes
1 parent c7ed50a commit f8625da

File tree

1 file changed

+22
-11
lines changed

1 file changed

+22
-11
lines changed

packages/query-graphql/src/decorators/graphql-resolve-info.utils.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import type { CursorConnectionType, OffsetConnectionType } from '../types'
1313
import type { RelationDescriptor } from './relation.decorator'
1414
import type { QueryResolveFields, QueryResolveTree, SelectRelation } from '@ptc-org/nestjs-query-core'
1515
import type { GraphQLCompositeType, GraphQLResolveInfo as ResolveInfo, SelectionNode } from 'graphql'
16-
1716
/**
1817
* Parts based of https://github.com/graphile/graphile-engine/blob/master/packages/graphql-parse-resolve-info/src/index.ts
1918
*/
@@ -60,6 +59,27 @@ function getDirectiveResults(fieldNode: SelectionNode, info: ResolveInfo) {
6059
}, directiveResult)
6160
}
6261

62+
function inlineFragments(nodes: ReadonlyArray<SelectionNode>, resolveInfo: ResolveInfo): SelectionNode[] {
63+
return nodes.flatMap((ast) => {
64+
if (ast.kind !== Kind.FRAGMENT_SPREAD) return ast
65+
66+
if (ast.directives?.length) {
67+
const { shouldInclude, shouldSkip } = getDirectiveResults(ast, resolveInfo)
68+
// field/fragment is not included if either the @skip condition is true or the @include condition is false
69+
// https://facebook.github.io/graphql/draft/#sec--include
70+
if (shouldSkip || !shouldInclude) {
71+
return []
72+
}
73+
}
74+
75+
const fragment = resolveInfo.fragments[ast.name.value]
76+
if (fragment) {
77+
return inlineFragments(fragment.selectionSet.selections, resolveInfo)
78+
}
79+
return []
80+
})
81+
}
82+
6383
function parseFieldNodes<DTO>(
6484
inASTs: ReadonlyArray<SelectionNode> | SelectionNode,
6585
resolveInfo: ResolveInfo,
@@ -68,16 +88,7 @@ function parseFieldNodes<DTO>(
6888
): QueryResolveTree<DTO> | QueryResolveFields<DTO> {
6989
const asts: ReadonlyArray<SelectionNode> = Array.isArray(inASTs) ? inASTs : [inASTs]
7090

71-
const astsWithInlinedFragments = asts.flatMap(ast => {
72-
if (ast.kind === Kind.FRAGMENT_SPREAD) {
73-
const fragment = resolveInfo.fragments[ast.name.value];
74-
if (fragment) {
75-
return fragment.selectionSet.selections;
76-
}
77-
return [];
78-
}
79-
return ast;
80-
})
91+
const astsWithInlinedFragments = inlineFragments(asts, resolveInfo)
8192

8293
return astsWithInlinedFragments.reduce((tree, fieldNode) => {
8394
let name: string

0 commit comments

Comments
 (0)