This repository was archived by the owner on Oct 9, 2025. It is now read-only.
forked from jcoreio/apollo-magic-refetch
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdoesQueryContain.js.flow
More file actions
81 lines (72 loc) · 2.26 KB
/
doesQueryContain.js.flow
File metadata and controls
81 lines (72 loc) · 2.26 KB
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
// @flow
import type { DocumentNode, SelectionSetNode, ASTKindToNode } from 'graphql'
import type { Type, Types } from './getSchemaTypes'
import getPotentialAncestors from './getPotentialAncestors'
type NodeKind = $Keys<ASTKindToNode>
type Name = {
+value: string,
}
type Node = {
+name?: Name,
+kind: NodeKind,
+selectionSet: ?SelectionSetNode,
}
export default function doesQueryContain(
document: DocumentNode,
types: Types,
typename: string,
data?: any,
predicate?: ?(data: any) => boolean
): boolean {
const targetType = types[typename]
if (!targetType) throw new Error(`type not found: ${typename}`)
const potentialAncestors = getPotentialAncestors(targetType)
function doesNodeContain(node: Node, data: any, type: Type): boolean {
if (type === targetType) {
if (!predicate || predicate(data)) return true
}
if (!type.name) return false
const ancestorEntry = potentialAncestors.get(type)
if (!ancestorEntry) return false
const { selectionSet } = node
if (selectionSet) {
for (let selection of selectionSet.selections) {
const alias: ?Name = (selection: any).alias
const name: ?Name = (selection: any).name
if (!name) continue
if (!ancestorEntry.fields.has(name.value)) continue
const { fields } = type
if (!fields) continue
let field = fields[name.value]
if (!field) continue
let innerType = field.type
let list = false
while (innerType.ofType) {
if (innerType.kind === 'LIST') list = true
innerType = innerType.ofType
}
let innerData = data ? data[alias ? alias.value : name.value] : null
if (predicate && innerData == null) continue
if (predicate && list) {
if (!Array.isArray(innerData)) continue
for (let element of innerData) {
if (doesNodeContain((selection: any), element, innerType)) {
return true
}
}
} else {
if (doesNodeContain((selection: any), innerData, innerType)) {
return true
}
}
}
}
return false
}
for (let node of document.definitions) {
if (doesNodeContain((node: any), data, types.Query)) {
return true
}
}
return false
}