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

Serialize enum argument values in AddArgumentsAsVariables #1075

Closed
wants to merge 1 commit into from
Closed
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
75 changes: 70 additions & 5 deletions src/test/testMergeSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@

import { expect } from 'chai';
import {
graphql,
GraphQLSchema,
ExecutionResult,
GraphQLEnumType,
GraphQLInputObjectType,
GraphQLList,
GraphQLNonNull,
GraphQLObjectType,
GraphQLScalarType,
subscribe,
parse,
ExecutionResult,
GraphQLSchema,
GraphQLString,
findDeprecatedUsages,
graphql,
parse,
subscribe,
} from 'graphql';
import mergeSchemas from '../stitching/mergeSchemas';
import {
Expand Down Expand Up @@ -583,6 +588,66 @@ testCombinations.forEach(async combination => {
expect(mergedResult).to.deep.equal(enumResult);
});

it(`works with enum arguments`, async () => {
const SortOrder = new GraphQLEnumType({
name: 'SortOrder',
values: {
ASC: { value: 'asc' },
DESC: { value: 'desc' },
},
});
const Query = new GraphQLObjectType({
name: 'Query',
fields: {
sort: {
type: GraphQLString,
args: {
sort: { type: SortOrder },
},
resolve(source, args) {
return args.sort;
}
},
nested: {
type: new GraphQLList(GraphQLString),
args: {
sort: {
type: new GraphQLInputObjectType({
name: 'SortOrders',
fields: {
orders: {
type: new GraphQLNonNull(new GraphQLList(
new GraphQLNonNull(SortOrder)
))
}
}
})
},
},
resolve(source, args) {
return args.sort.orders;
}
}
}
});
const schema = new GraphQLSchema({
query: Query,
});
const merged = mergeSchemas({ schemas: [schema]});
const result = await graphql(
merged,
`
query {
sort(sort: DESC)
nested(sort: { orders: [DESC, ASC] })
}
`,
);
expect(result.errors).to.be.undefined;
expect(result.data.sort).to.equal('desc');
expect(result.data.nested).to.eql(['desc', 'asc']);
});

it('queries', async () => {
const propertyFragment = `
propertyById(id: "p1") {
Expand Down
38 changes: 33 additions & 5 deletions src/transforms/AddArgumentsAsVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@ import {
DocumentNode,
FragmentDefinitionNode,
GraphQLArgument,
GraphQLEnumType,
GraphQLInputObjectType,
GraphQLInputType,
GraphQLList,
GraphQLField,
GraphQLNonNull,
GraphQLObjectType,
GraphQLScalarType,
GraphQLSchema,
Kind,
OperationDefinitionNode,
SelectionNode,
TypeNode,
VariableDefinitionNode,
getNullableType,
} from 'graphql';
import { Request } from '../Interfaces';
import { Transform } from './transforms';
Expand Down Expand Up @@ -62,6 +66,7 @@ function addVariablesToRootField(
) as Array<FragmentDefinitionNode>;

const variableNames = {};
const newVariables = {};

const newOperations = operations.map((operation: OperationDefinitionNode) => {
let existingVariables = operation.variableDefinitions.map(
Expand Down Expand Up @@ -130,6 +135,10 @@ function addVariablesToRootField(
},
type: typeToAst(argument.type),
};
newVariables[variableName] = serializeArgumentValue(
argument.type,
args[argument.name],
);
}
});

Expand All @@ -154,11 +163,6 @@ function addVariablesToRootField(
};
});

const newVariables = {};
Object.keys(variableNames).forEach(name => {
newVariables[variableNames[name]] = args[name];
});

return {
document: {
...document,
Expand Down Expand Up @@ -197,3 +201,27 @@ function typeToAst(type: GraphQLInputType): TypeNode {
};
}
}

function serializeArgumentValue(type: GraphQLInputType, value: any): any {
if (value == null) {
return null;
}

const nullableType = getNullableType(type);
if (nullableType instanceof GraphQLEnumType) {
return nullableType.serialize(value);
} else if (nullableType instanceof GraphQLScalarType) {
return value;
} else if (nullableType instanceof GraphQLList) {
return value.map(
(v: any) => serializeArgumentValue(nullableType.ofType, v)
);
} else if (nullableType instanceof GraphQLInputObjectType) {
const fields = nullableType.getFields();
return Object.keys(value).reduce((acc, k) => {
const v = value[k];
acc[k] = serializeArgumentValue(fields[k].type, v);
return acc;
}, {});
}
}