Skip to content

Commit

Permalink
fix(stitching): custom scalars/enums
Browse files Browse the repository at this point in the history
Provide support for overriding scalars or enums used within input objects.
  • Loading branch information
yaacovCR committed Jan 9, 2020
1 parent b17f0a8 commit bd60b3f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 11 deletions.
6 changes: 5 additions & 1 deletion src/stitching/delegateToSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,11 @@ async function delegateToSchemaImplementation({

if (args) {
transforms.push(
new AddArgumentsAsVariables(targetSchema, args)
new AddArgumentsAsVariables(targetSchema, args, info.schema)
);
} else {
console.warn(
'"args" undefined. "args" argument may be required in a future version. Custom scalars or enums may not be properly serialized prior to delegation.'
);
}

Expand Down
5 changes: 5 additions & 0 deletions src/test/testMergeSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,11 @@ testCombinations.forEach(async combination => {
},
},
},
TestScalar: new GraphQLScalarType({
name: 'TestScalar',
description: undefined,
serialize: value => value,
}),
Query: {
delegateInterfaceTest(parent, args, context, info) {
return delegateToSchema({
Expand Down
38 changes: 28 additions & 10 deletions src/transforms/AddArgumentsAsVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,30 @@ import {
SelectionNode,
TypeNode,
VariableDefinitionNode,
GraphQLEnumType,
GraphQLScalarType,
} from 'graphql';
import { Request } from '../Interfaces';
import { Transform } from './transforms';
import { serializeInputValue } from '../utils/transformInputValue';
import { transformInputValue } from '../utils';

export default class AddArgumentsAsVariablesTransform implements Transform {
private schema: GraphQLSchema;
private targetSchema: GraphQLSchema;
private args: { [key: string]: any };
private newSchema: GraphQLSchema;

constructor(schema: GraphQLSchema, args: { [key: string]: any }) {
this.schema = schema;
constructor(targetSchema: GraphQLSchema, args: { [key: string]: any }, newSchema: GraphQLSchema) {
this.targetSchema = targetSchema;
this.args = args;
this.newSchema = newSchema;
}

public transformRequest(originalRequest: Request): Request {
const { document, newVariables } = addVariablesToRootField(
this.schema,
this.targetSchema,
originalRequest.document,
this.args,
this.newSchema,
);
const variables = {
...originalRequest.variables,
Expand All @@ -49,10 +54,11 @@ function addVariablesToRootField(
targetSchema: GraphQLSchema,
document: DocumentNode,
args: { [key: string]: any },
newSchema: GraphQLSchema,
): {
document: DocumentNode;
newVariables: { [key: string]: any };
} {
} {
const operations: Array<
OperationDefinitionNode
> = document.definitions.filter(
Expand Down Expand Up @@ -132,10 +138,22 @@ function addVariablesToRootField(
},
type: typeToAst(argument.type),
};
newVariables[variableName] = serializeInputValue(
argument.type,
args[argument.name],
);
if (newSchema) {
newVariables[variableName] = transformInputValue(
argument.type,
args[argument.name],
(t, v) => {
const newType = newSchema.getType(t.name) as GraphQLEnumType | GraphQLScalarType;
return newType ? newType.serialize(v) : v;
}
);
} else {
// tslint:disable-next-line:max-line-length
console.warn(
'AddArgumentsAsVariables should be passed the wrapping schema so that arguments can be properly serialized prior to delegation.'
);
newVariables[variableName] = args[argument.name];
}
}
});

Expand Down

0 comments on commit bd60b3f

Please sign in to comment.