diff --git a/lib/query-builder.js b/lib/query-builder.js index faa7f0a..09f8692 100644 --- a/lib/query-builder.js +++ b/lib/query-builder.js @@ -113,7 +113,7 @@ function buildQuery (query, parentResult) { } // get keys to reuse on merge results -function buildQuerySelection (selection, parent, wrap = true) { +function buildQuerySelection (selection, parent, wrap = true, fragment = undefined) { if (!(selection && selection.length > 0)) { return { selection: '', keys: [] } } @@ -132,7 +132,7 @@ function buildQuerySelection (selection, parent, wrap = true) { fields.add(toQuerySelection(keyField)) keys.set('key' + keyId(k), k) } else if (selection[i].selection) { - fields.add(buildQuerySelection(selection[i].selection, null, selection[i].wrap).selection) + fields.add(buildQuerySelection(selection[i].selection, null, selection[i].wrap, selection[i].fragment).selection) } else if (selection[i].nested) { fields.add(selection[i].parentField) for (const nested of selection[i].nested.values()) { @@ -182,7 +182,7 @@ function buildQuerySelection (selection, parent, wrap = true) { } } - const qselection = wrap ? `{ ${Array.from(fields).join(' ')} }` : Array.from(fields).join(' ') + const qselection = wrap ? `${fragment ? `... on ${fragment} ` : ''}{ ${Array.from(fields).join(' ')} }` : Array.from(fields).join(' ') return { selection: qselection, keys: Array.from(keys.values()) } } diff --git a/lib/query-lookup.js b/lib/query-lookup.js index 0a8216c..35e85f7 100644 --- a/lib/query-lookup.js +++ b/lib/query-lookup.js @@ -28,6 +28,7 @@ const { mergeMaps, collectNodeArgs, collectPlainArgs, pathJoin } = require('./ut */ function collectQueries ({ subgraphName, queryFieldNode, path = '', fieldId, parent, args, + fragmentFieldTypeName, // references types, fields, aliases, // root: collect root queries @@ -85,6 +86,7 @@ function collectQueries ({ field, fieldId, queryFieldNode, + // TODO maybe parent and root are redundant parent, root, @@ -104,8 +106,9 @@ function collectQueries ({ return { queries, deferreds, order } } - const fieldTypeName = field?.typeName + const fieldTypeName = fragmentFieldTypeName ?? field?.typeName // const fieldType = field && types[fieldTypeName] + const isUnionTypeType = field.type.src.kind === 'UNION' for (let i = 0; i < queryFieldSelections.length; ++i) { const querySelection = queryFieldSelections[i] @@ -115,6 +118,7 @@ function collectQueries ({ ? context.info.fragments[querySelection.name.value] : querySelection + const fragmentFieldTypeName = isUnionTypeType ? fragment.typeCondition.name.value : undefined // TODO if !field - shouldn't happen const nested = collectNestedQueries({ context, @@ -124,12 +128,17 @@ function collectQueries ({ queryNode, querySelection: fragment, types, + fragmentFieldTypeName, fields }) // unwrap fragment as selection for (const n of nested.queries.values()) { - queryNode.query.selection.push({ selection: n.query.selection, wrap: false }) + queryNode.query.selection.push({ + selection: n.query.selection, + wrap: fragmentFieldTypeName !== undefined, + fragment: fragmentFieldTypeName + }) } collectDeferredQueries(queryNode, nested, deferreds) @@ -161,7 +170,7 @@ function collectQueries ({ context.logger.debug(`deferred query for ${cpath} > ${selectionFieldName} on ${subgraphName}`) - const alias = aliases[fieldId] + const alias = aliases && aliases[fieldId] if (alias && nested) { nesting({ selectionFieldName, @@ -258,7 +267,8 @@ function collectNestedQueries ({ types, fields, aliases, - alias + alias, + fragmentFieldTypeName }) { context.logger.debug({ fieldId, path }, 'query lookup, nested') const a = alias ? Object.values(alias)[0] : null @@ -274,7 +284,8 @@ function collectNestedQueries ({ types, fields, aliases, - typeName: a?.type + typeName: a?.type, + fragmentFieldTypeName }) }