Skip to content

fix some conflict-types with Graphql #89

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

Closed
wants to merge 2 commits 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
"coveralls": "2.11.9",
"eslint": "2.10.2",
"flow-bin": "0.25.0",
"flow-dynamic": "^0.0.9",
"flow-graphql": "^0.6.4",
"graphql": "0.6.0",
"isparta": "4.0.0",
"mocha": "2.5.3",
Expand Down
5 changes: 3 additions & 2 deletions src/mutation/__tests__/mutation.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ var simpleRootValueMutation = mutationWithClientMutationId({
type: GraphQLInt
}
},
mutateAndGetPayload: (params, context, {rootValue}) => (rootValue)
// :any to ignore type check in test.
mutateAndGetPayload: (params, context, {rootValue}) => ((rootValue:any))
});

var mutation = new GraphQLObjectType({
Expand All @@ -92,7 +93,7 @@ describe('mutationWithClientMutationId()', () => {
}
}
`;
var result = await graphql(schema, query);
var result:any = await graphql(schema, query);
expect(result.errors.length).to.equal(1);
expect(result.errors[0].message).to.equal('Field \"simpleMutation\" argument \"input\" of type \"SimpleMutationInput!\" is required but not provided.');
});
Expand Down
29 changes: 19 additions & 10 deletions src/mutation/mutation.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ import type {
GraphQLResolveInfo
} from 'graphql';

type mutationFn =
(object: Object, ctx: Object, info: GraphQLResolveInfo) => Object |
(object: Object, ctx: Object, info: GraphQLResolveInfo) => Promise<Object>;
import {
graph,
pro
} from 'flow-dynamic';
const {argsCheck} = graph;

type mutationFn = (object: Object, ctx: mixed, info: GraphQLResolveInfo) =>
( Object | Promise<Object> );

function resolveMaybeThunk<T>(thingOrThunk: T | () => T): T {
return typeof thingOrThunk === 'function' ? thingOrThunk() : thingOrThunk;
Expand Down Expand Up @@ -87,12 +92,16 @@ export function mutationWithClientMutationId(
args: {
input: {type: new GraphQLNonNull(inputType)}
},
resolve: (_, {input}, context, info) => {
return Promise.resolve(mutateAndGetPayload(input, context, info))
.then(payload => {
payload.clientMutationId = input.clientMutationId;
return payload;
});
}
resolve: argsCheck(
args => ({
input: pro.isObject(args.input)
}),
(_, {input}, context, info) => {
return Promise.resolve(mutateAndGetPayload(input, context, info))
.then(payload => {
payload.clientMutationId = input.clientMutationId;
return payload;
});
})
};
}
71 changes: 68 additions & 3 deletions src/node/__tests__/plural.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ import {
GraphQLObjectType,
GraphQLSchema,
GraphQLString,
GraphQLInputObjectType,
GraphQLScalarType,
GraphQLEnumType,
GraphQLList,
GraphQLNonNull,
graphql
} from 'graphql';

import {
pluralIdentifyingRootField
pluralIdentifyingRootField,
nonNull
} from '../plural';

var userType = new GraphQLObjectType({
Expand All @@ -42,9 +48,11 @@ var queryType = new GraphQLObjectType({
description: 'Map from a username to the user',
inputType: GraphQLString,
outputType: userType,
resolveSingleInput: (username, context, {rootValue: {lang}}) => ({
// rootValue Graphql(mixed) -> relay(object)
// :any to ignore type check in test.
resolveSingleInput: (username, context, {rootValue}) => ({
username: username,
url: 'www.facebook.com/' + username + '?lang=' + lang
url: 'www.facebook.com/' + username + '?lang=' + (rootValue:any).lang
})
})
})
Expand Down Expand Up @@ -157,3 +165,60 @@ describe('pluralIdentifyingRootField()', () => {
return expect(graphql(schema, query)).to.become({data: expected});
});
});

describe('nonNull()', () => {
function qlScalar() {
return new GraphQLScalarType({
name: 'scalar',
serialize: String,
description: 'test'
});
}

it('covert GraphQLInputObjectType to NonNull type', () => {
const inputType = new GraphQLInputObjectType({
name: 'input',
fields: {
test: {
type: qlScalar()
}
}
});
const result = nonNull(inputType);
expect(result).to.be.an.instanceof(GraphQLNonNull);
expect(result.ofType).to.deep.equal(inputType);
});

it('covert GraphQLScalarType to NonNull type', () => {
const scalarType = qlScalar();
const result = nonNull(scalarType);
expect(result).to.be.an.instanceof(GraphQLNonNull);
expect(result.ofType).to.deep.equal(scalarType);
});

it('covert GraphQLEnumType to NonNull type', () => {
const enumType = new GraphQLEnumType({
name: 'EM',
values: {
E: { value: 0},
M: { value: 1}
}
});
const result = nonNull(enumType);
expect(result).to.be.an.instanceof(GraphQLNonNull);
expect(result.ofType).to.deep.equal(enumType);
});

it('covert GraphQLList to NonNull type', () => {
const listType = new GraphQLList(GraphQLString);
const result = nonNull(listType);
expect(result).to.be.an.instanceof(GraphQLNonNull);
expect(result.ofType).to.deep.equal(listType);
});

it('does nothing to GraphQLNonNull Type', () => {
const nonNullType = new GraphQLNonNull(GraphQLString);
const result = nonNull(nonNullType);
expect(result).to.deep.equal(nonNullType);
});
});
28 changes: 21 additions & 7 deletions src/node/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,18 @@ import {
unbase64
} from '../utils/base64.js';

import {
graph,
pro
} from 'flow-dynamic';
const {argsCheck, sourceCheck} = graph;

type GraphQLNodeDefinitions = {
nodeInterface: GraphQLInterfaceType,
nodeField: GraphQLFieldConfig
}

type typeResolverFn = (object: any) => ?GraphQLObjectType |
(object: any) => ?Promise<GraphQLObjectType>;
type typeResolverFn = (object: any) => ?GraphQLObjectType;

/**
* Given a function to map from an ID to an underlying object, and a function
Expand All @@ -45,7 +50,7 @@ type typeResolverFn = (object: any) => ?GraphQLObjectType |
*/
export function nodeDefinitions(
idFetcher: ((id: string, context: any, info: GraphQLResolveInfo) => any),
typeResolver?: ?typeResolverFn
typeResolver?: typeResolverFn
): GraphQLNodeDefinitions {
var nodeInterface = new GraphQLInterfaceType({
name: 'Node',
Expand All @@ -59,6 +64,8 @@ export function nodeDefinitions(
resolveType: typeResolver
});



var nodeField = {
name: 'node',
description: 'Fetches an object given its ID',
Expand All @@ -69,7 +76,11 @@ export function nodeDefinitions(
description: 'The ID of an object'
}
},
resolve: (obj, {id}, context, info) => idFetcher(id, context, info),
// type NodeArgs = {id:string};
resolve: argsCheck(
args => ({id: pro.isString(args.id) }),
(obj, args, context, info) => idFetcher(args.id, context, info)
)
};

return {nodeInterface, nodeField};
Expand Down Expand Up @@ -115,9 +126,12 @@ export function globalIdField(
name: 'id',
description: 'The ID of an object',
type: new GraphQLNonNull(GraphQLID),
resolve: (obj, args, context, info) => toGlobalId(
typeName || info.parentType.name,
idFetcher ? idFetcher(obj, context, info) : obj.id
resolve: sourceCheck(
obj => pro.isObject(obj),
(obj, args, context, info) => toGlobalId(
typeName || info.parentType.name,
idFetcher ? idFetcher(obj, context, info) : obj.id
)
)
};
}
47 changes: 35 additions & 12 deletions src/node/plural.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,18 @@ import type {
GraphQLFieldConfig,
GraphQLInputType,
GraphQLOutputType,
GraphQLResolveInfo
GraphQLResolveInfo,
GraphQLScalarType,
GraphQLEnumType,
GraphQLInputObjectType
} from 'graphql';

import {
graph,
pro
} from 'flow-dynamic';
const {argsCheck} = graph;

type PluralIdentifyingRootFieldConfig = {
argName: string,
inputType: GraphQLInputType,
Expand All @@ -36,23 +45,37 @@ export function pluralIdentifyingRootField(
inputArgs[config.argName] = {
type: new GraphQLNonNull(
new GraphQLList(
new GraphQLNonNull(
config.inputType
)
nonNull(config.inputType)
)
)
};
return {
description: config.description,
type: new GraphQLList(config.outputType),
args: inputArgs,
resolve: (obj, args, context, info) => {
var inputs = args[config.argName];
return Promise.all(inputs.map(
input => Promise.resolve(
config.resolveSingleInput(input, context, info)
)
));
}
resolve: argsCheck( args => pro.isObject(args),
(obj, args, context, info) => {
var inputs = args[config.argName];
return Promise.all(inputs.map(
input => Promise.resolve(
config.resolveSingleInput(input, context, info)
)
));
}
)
};
}

type NonNullInputType = GraphQLNonNull<
GraphQLScalarType |
GraphQLEnumType |
GraphQLInputObjectType |
GraphQLList<GraphQLInputType> >;

export function nonNull(type:GraphQLInputType):NonNullInputType {
if ( type instanceof GraphQLNonNull) {
return type;
} else {
return new GraphQLNonNull(type);
}
}