Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(typeMerging): fix scalar type merging #1980

Merged
merged 2 commits into from
Sep 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/stitch/src/mergeCandidates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,10 @@ function mergeScalarTypeCandidates(typeName: string, candidates: Array<MergeType
const serialize = serializeFns[serializeFns.length - 1];

const parseValueFns = pluck<GraphQLScalarValueParser<any>>('parseValue', candidates);
const parseValue = parseValueFns[descriptions.length - 1];
const parseValue = parseValueFns[parseValueFns.length - 1];

const parseLiteralFns = pluck<GraphQLScalarLiteralParser<any>>('parseLiteral', candidates);
const parseLiteral = parseLiteralFns[descriptions.length - 1];
const parseLiteral = parseLiteralFns[parseLiteralFns.length - 1];

const astNodes = pluck<ScalarTypeDefinitionNode>('astNode', candidates);
const astNode = astNodes
Expand Down
14 changes: 5 additions & 9 deletions packages/stitch/src/stitchSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {

import { buildTypeCandidates, buildTypeMap } from './typeCandidates';
import { createStitchingInfo, completeStitchingInfo, addStitchingInfo } from './stitchingInfo';
import { MergeTypeCandidate, IStitchSchemasOptions, StitchingInfo } from './types';
import { IStitchSchemasOptions } from './types';
import { SubschemaConfig, isSubschemaConfig } from '@graphql-tools/delegate';

export function stitchSchemas({
Expand Down Expand Up @@ -89,7 +89,6 @@ export function stitchSchemas({
});

const transformedSchemas: Map<GraphQLSchema | SubschemaConfig, GraphQLSchema> = new Map();
const typeCandidates: Record<string, Array<MergeTypeCandidate>> = Object.create(null);
const extensions: Array<DocumentNode> = [];
const directives: Array<GraphQLDirective> = [];
const directiveMap: Record<string, GraphQLDirective> = specifiedDirectives.reduce((acc, directive) => {
Expand All @@ -103,10 +102,9 @@ export function stitchSchemas({
subscription: 'Subscription',
};

buildTypeCandidates({
const typeCandidates = buildTypeCandidates({
schemaLikeObjects,
transformedSchemas,
typeCandidates,
extensions,
directiveMap,
schemaDefs,
Expand All @@ -118,16 +116,14 @@ export function stitchSchemas({
directives.push(directiveMap[directiveName]);
});

let stitchingInfo: StitchingInfo;

stitchingInfo = createStitchingInfo(transformedSchemas, typeCandidates, mergeTypes);
let stitchingInfo = createStitchingInfo(transformedSchemas, typeCandidates, mergeTypes);

const typeMap = buildTypeMap({
typeCandidates,
mergeTypes,
stitchingInfo,
onTypeConflict,
operationTypeNames,
onTypeConflict,
mergeTypes,
});

const { typeMap: newTypeMap, directives: newDirectives } = rewireTypes(typeMap, directives, { skipPruning: true });
Expand Down
5 changes: 2 additions & 3 deletions packages/stitch/src/stitchingInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,7 @@ function createMergedTypes(
return;
}

const transformedSubschema = typeCandidate.transformedSubschema;
typeMaps.set(subschema, transformedSubschema.getTypeMap());
typeMaps.set(subschema, typeCandidate.transformedSchema.getTypeMap());

if (!isSubschemaConfig(subschema)) {
return;
Expand Down Expand Up @@ -197,7 +196,7 @@ function createMergedTypes(
return;
}

const type = transformedSubschema.getType(typeName) as GraphQLObjectType | GraphQLInterfaceType;
const type = typeCandidate.transformedSchema.getType(typeName) as GraphQLObjectType | GraphQLInterfaceType;
const fieldMap = type.getFields();
const selectionSet = selectionSets.get(subschema);
Object.keys(fieldMap).forEach(fieldName => {
Expand Down
26 changes: 13 additions & 13 deletions packages/stitch/src/typeCandidates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ function isDocumentNode(schemaLikeObject: any): schemaLikeObject is DocumentNode
export function buildTypeCandidates({
schemaLikeObjects,
transformedSchemas,
typeCandidates,
extensions,
directiveMap,
schemaDefs,
Expand All @@ -46,7 +45,6 @@ export function buildTypeCandidates({
}: {
schemaLikeObjects: Array<GraphQLSchema | SubschemaConfig | DocumentNode | GraphQLNamedType>;
transformedSchemas: Map<GraphQLSchema | SubschemaConfig, GraphQLSchema>;
typeCandidates: Record<string, Array<MergeTypeCandidate>>;
extensions: Array<DocumentNode>;
directiveMap: Record<string, GraphQLDirective>;
schemaDefs: {
Expand All @@ -55,7 +53,9 @@ export function buildTypeCandidates({
};
operationTypeNames: Record<string, any>;
mergeDirectives: boolean;
}): void {
}): Record<string, Array<MergeTypeCandidate>> {
const typeCandidates: Record<string, Array<MergeTypeCandidate>> = Object.create(null);

let schemaDef: SchemaDefinitionNode;
let schemaExtensions: Array<SchemaExtensionNode> = [];

Expand Down Expand Up @@ -86,10 +86,9 @@ export function buildTypeCandidates({
Object.keys(operationTypes).forEach(operationType => {
if (operationTypes[operationType] != null) {
addTypeCandidate(typeCandidates, operationTypeNames[operationType], {
schema,
type: operationTypes[operationType],
subschema: schemaLikeObject,
transformedSubschema: schema,
transformedSchema: schema,
});
}
});
Expand All @@ -111,10 +110,9 @@ export function buildTypeCandidates({
type !== operationTypes.subscription
) {
addTypeCandidate(typeCandidates, type.name, {
schema,
type,
subschema: schemaLikeObject,
transformedSubschema: schema,
transformedSchema: schema,
});
}
});
Expand Down Expand Up @@ -147,6 +145,8 @@ export function buildTypeCandidates({
throw new Error(`Invalid object ${schemaLikeObject as string}`);
}
});

return typeCandidates;
}

function setOperationTypeNames(
Expand Down Expand Up @@ -186,16 +186,16 @@ function addTypeCandidate(

export function buildTypeMap({
typeCandidates,
mergeTypes,
stitchingInfo,
onTypeConflict,
operationTypeNames,
onTypeConflict,
mergeTypes,
}: {
typeCandidates: Record<string, Array<MergeTypeCandidate>>;
mergeTypes: boolean | Array<string> | MergeTypeFilter;
stitchingInfo: StitchingInfo;
onTypeConflict: OnTypeConflict;
operationTypeNames: Record<string, any>;
onTypeConflict: OnTypeConflict;
mergeTypes: boolean | Array<string> | MergeTypeFilter;
}): TypeMap {
const typeMap: TypeMap = Object.create(null);

Expand Down Expand Up @@ -227,10 +227,10 @@ function onTypeConflictToCandidateSelector(onTypeConflict: OnTypeConflict): Cand
cands.reduce((prev, next) => {
const type = onTypeConflict(prev.type, next.type, {
left: {
schema: prev.schema,
schema: prev.transformedSchema,
},
right: {
schema: next.schema,
schema: next.transformedSchema,
},
});
if (prev.type === type) {
Expand Down
5 changes: 2 additions & 3 deletions packages/stitch/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import { IExecutableSchemaDefinition } from '@graphql-tools/schema';

export type MergeTypeCandidate = {
type: GraphQLNamedType;
schema?: GraphQLSchema;
subschema?: GraphQLSchema | SubschemaConfig;
transformedSubschema?: GraphQLSchema;
transformedSchema?: GraphQLSchema;
};

export type MergeTypeFilter = (mergeTypeCandidates: Array<MergeTypeCandidate>, typeName: string) => boolean;
Expand Down Expand Up @@ -45,8 +44,8 @@ export interface IStitchSchemasOptions<TContext = any> extends Omit<IExecutableS
types?: Array<GraphQLNamedType>;
schemas?: Array<SchemaLikeObject>;
onTypeConflict?: OnTypeConflict;
mergeTypes?: boolean | Array<string> | MergeTypeFilter;
mergeDirectives?: boolean;
mergeTypes?: boolean | Array<string> | MergeTypeFilter;
}

export type OnTypeConflict = (
Expand Down
9 changes: 7 additions & 2 deletions website/docs/stitch-type-merging.md
Original file line number Diff line number Diff line change
Expand Up @@ -621,9 +621,14 @@ Finally, you may wish to fine-tune which types are merged. Besides taking a bool

```ts
export type MergeTypeCandidate = {
// type: a type to potentially merge
type: GraphQLNamedType;
subschema?: GraphQLSchema | SubschemaConfig; // undefined if the type is added to the gateway directly, not from a subschema
transformedSubschema?: GraphQLSchema; // the target schema of the above after any subschema config schema transformations are applied
// subschema: undefined if the type is added to the gateway directly, not from a subschema
subschema?: GraphQLSchema | SubschemaConfig;
// transformedSchema: when `subschema` is a `GraphQLSchema`, identical to above.
// When `subschema` is a `SubschemaConfig` object, `transformedSchema` will be the result of applying the schema
// transforms from the `SubschemaConfig` object to the original schema.
transformedSchema?: GraphQLSchema;
};

export type MergeTypeFilter = (mergeTypeCandidates: Array<MergeTypeCandidate>, typeName: string) => boolean;
Expand Down