Skip to content

Commit 038159f

Browse files
committed
Add types to simplifyParsedResolveInfoFragmentWithType and fix bug in field merging
1 parent 603bf8f commit 038159f

File tree

1 file changed

+46
-6
lines changed
  • packages/graphql-parse-resolve-info/src

1 file changed

+46
-6
lines changed

packages/graphql-parse-resolve-info/src/index.ts

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import * as debugFactory from "debug";
2323
type mixed = Record<string, any> | string | number | boolean | undefined | null;
2424

2525
export interface FieldsByTypeName {
26-
[str: string]: {
27-
[str: string]: ResolveTree;
26+
[typeName: string]: {
27+
[fieldName: string]: ResolveTree;
2828
};
2929
}
3030

@@ -350,17 +350,28 @@ function getType(
350350
export function simplifyParsedResolveInfoFragmentWithType(
351351
parsedResolveInfoFragment: ResolveTree,
352352
type: GraphQLType
353-
) {
353+
): ResolveTree & { fields: { [fieldName: string]: ResolveTree } } {
354354
const { fieldsByTypeName } = parsedResolveInfoFragment;
355-
const fields = {};
355+
const fields: { [fieldName: string]: ResolveTree } = Object.create(null);
356356
const strippedType = getNamedType(type);
357357
if (isCompositeType(strippedType)) {
358358
Object.assign(fields, fieldsByTypeName[strippedType.name]);
359359
if (strippedType instanceof GraphQLObjectType) {
360360
const objectType: GraphQLObjectType = strippedType;
361-
// GraphQL ensures that the subfields cannot clash, so it's safe to simply overwrite them
361+
// GraphQL ensures that the subfields cannot clash, so it's safe to simply merge them
362362
for (const anInterface of objectType.getInterfaces()) {
363-
Object.assign(fields, fieldsByTypeName[anInterface.name]);
363+
const interfaceFields = fieldsByTypeName[anInterface.name];
364+
for (const fieldName of Object.keys(interfaceFields)) {
365+
const interfaceField = interfaceFields[fieldName];
366+
if (fields[fieldName]) {
367+
fields[fieldName] = recursiveMerge(
368+
fields[fieldName],
369+
interfaceField
370+
);
371+
} else {
372+
fields[fieldName] = interfaceField;
373+
}
374+
}
364375
}
365376
}
366377
}
@@ -370,6 +381,35 @@ export function simplifyParsedResolveInfoFragmentWithType(
370381
};
371382
}
372383

384+
function recursiveMerge(treeA: ResolveTree, treeB: ResolveTree): ResolveTree {
385+
const result: ResolveTree = {
386+
...treeA,
387+
fieldsByTypeName: Object.create(null),
388+
};
389+
390+
for (const tree of [treeA, treeB]) {
391+
for (const typeName of Object.keys(tree.fieldsByTypeName)) {
392+
if (!result.fieldsByTypeName[typeName]) {
393+
result.fieldsByTypeName[typeName] = Object.create(null);
394+
}
395+
const targetFields = result.fieldsByTypeName[typeName];
396+
const sourceFields = tree.fieldsByTypeName[typeName];
397+
for (const fieldName of Object.keys(sourceFields)) {
398+
if (!targetFields[fieldName]) {
399+
targetFields[fieldName] = sourceFields[fieldName];
400+
} else {
401+
targetFields[fieldName] = recursiveMerge(
402+
targetFields[fieldName],
403+
sourceFields[typeName]
404+
);
405+
}
406+
}
407+
}
408+
}
409+
410+
return result;
411+
}
412+
373413
export const parse = parseResolveInfo;
374414
export const simplify = simplifyParsedResolveInfoFragmentWithType;
375415
export const getAlias = getAliasFromResolveInfo;

0 commit comments

Comments
 (0)