Skip to content

Commit

Permalink
feat(TypeMapper): add default(value: mixed) directive for SDL in In…
Browse files Browse the repository at this point in the history
…putFieldConfigs

```js
const IntRangeITC = InputTypeComposer.create(`
  input IntRangeInput {
    min: Int @default(value: 0)
    max: Int
  }
`);
```
  • Loading branch information
nodkz committed Apr 27, 2018
1 parent e93379e commit 5478dd4
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/TypeComposer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ export class TypeComposer<TContext> {

public getInputTypeComposer(): InputTypeComposer;

public getITC(): InputTypeComposer;

public getResolvers(): Map<string, Resolver<any, TContext>>;

public hasResolver(name: string): boolean;
Expand Down
5 changes: 5 additions & 0 deletions src/TypeComposer.js
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,11 @@ export class TypeComposer<TContext> {
return this.gqType._gqcInputTypeComposer;
}

// Alias for getInputTypeComposer()
getITC(): InputTypeComposer {
return this.getInputTypeComposer();
}

getResolvers(): Map<string, Resolver<any, TContext>> {
if (!this.gqType._gqcResolvers) {
this.gqType._gqcResolvers = new Map();
Expand Down
14 changes: 12 additions & 2 deletions src/TypeMapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getDescription } from 'graphql/utilities/buildASTSchema';
import keyValMap from 'graphql/jsutils/keyValMap';
import invariant from 'graphql/jsutils/invariant';
import find from 'graphql/jsutils/find';
import { getArgumentValues } from 'graphql/execution/values';
import { getArgumentValues, getDirectiveValues } from 'graphql/execution/values';
import type {
DocumentNode,
ObjectTypeDefinitionNode,
Expand Down Expand Up @@ -76,6 +76,7 @@ import { Resolver } from './Resolver';
import { TypeStorage } from './TypeStorage';
import type { Thunk } from './utils/definitions';
import { isFunction, isObject } from './utils/is';
import DefaultDerective from './directive/default';

export type TypeDefinitionString = string; // eg type Name { field: Int }
export type TypeWrappedString = string; // eg. Int, Int!, [Int]
Expand Down Expand Up @@ -651,6 +652,15 @@ function makeSchemaDef(def, schema: SchemaComposer<any>) {
}
}

function getInputDefaultValue(value: InputValueDefinitionNode, type: GraphQLInputType): mixed {
// check getDirectiveValues become avaliable from 0.10.2
if (Array.isArray(value.directives) && getDirectiveValues) {
const vars = getDirectiveValues(DefaultDerective, value);
if (vars && vars.hasOwnProperty('value')) return vars.value;
}
return valueFromAST(value.defaultValue, type);
}

function makeInputValues(
values: ?$ReadOnlyArray<InputValueDefinitionNode>,
schema: SchemaComposer<any>
Expand All @@ -664,7 +674,7 @@ function makeInputValues(
return {
type,
description: getDescription(value),
defaultValue: valueFromAST(value.defaultValue, type),
defaultValue: getInputDefaultValue(value, type),
};
}
);
Expand Down
3 changes: 2 additions & 1 deletion src/__tests__/InputTypeComposer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ describe('InputTypeComposer', () => {
const itc1 = InputTypeComposer.create(
`
input TestTypeTplInput {
f1: String
f1: String @default(value: "new")
# Description for some required Int field
f2: Int!
}
Expand All @@ -276,6 +276,7 @@ describe('InputTypeComposer', () => {
expect(itc1).toBeInstanceOf(InputTypeComposer);
expect(itc1.getTypeName()).toBe('TestTypeTplInput');
expect(itc1.getFieldType('f1')).toBe(GraphQLString);
expect((itc1.getField('f1'): any).defaultValue).toBe('new');
expect(itc1.getFieldType('f2')).toBeInstanceOf(GraphQLNonNull);
expect((itc1.getFieldType('f2'): any).ofType).toBe(GraphQLInt);
});
Expand Down
9 changes: 5 additions & 4 deletions src/__tests__/TypeMapper-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ describe('TypeMapper', () => {
const type: GraphQLInputObjectType = (TypeMapper.createType(
`
input InputIntRange {
max: Int,
min: Int!
min: Int @default(value: 0)
max: Int!
}
`
): any);
Expand All @@ -124,8 +124,9 @@ describe('TypeMapper', () => {

const IntRangeTC = new InputTypeComposer(type);
expect(IntRangeTC.getTypeName()).toBe('InputIntRange');
expect(IntRangeTC.getField('max').type).toBe(GraphQLInt);
expect(IntRangeTC.getField('min').type).toBeInstanceOf(GraphQLNonNull);
expect(IntRangeTC.getField('min').defaultValue).toBe(0);
expect(IntRangeTC.getField('min').type).toBe(GraphQLInt);
expect(IntRangeTC.getField('max').type).toBeInstanceOf(GraphQLNonNull);
});

it('should return wrapped type', () => {
Expand Down
15 changes: 15 additions & 0 deletions src/directive/default.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* @flow */

import { GraphQLDirective, DirectiveLocation, GraphQLNonNull } from '../graphql';
import GraphQLJSON from '../type/json';

export default new GraphQLDirective({
name: 'default',
description: 'Provides default value for input field.',
locations: [DirectiveLocation.INPUT_FIELD_DEFINITION],
args: {
value: {
type: new GraphQLNonNull(GraphQLJSON),
},
},
});

0 comments on commit 5478dd4

Please sign in to comment.