Skip to content

Commit

Permalink
feat(InterfaceTypeComposer): add getFieldOTC(), getFieldArgTC() a…
Browse files Browse the repository at this point in the history
…nd `getFieldArgITC()` methods
  • Loading branch information
nodkz committed Apr 8, 2019
1 parent cc6a743 commit f0aef21
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 5 deletions.
18 changes: 17 additions & 1 deletion src/InterfaceTypeComposer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,17 @@ export class InterfaceTypeComposer<TSource = any, TContext = any> {
fieldName: string
):
| ObjectTypeComposer<TSource, TContext>
| InputTypeComposer<TContext>
| EnumTypeComposer<TContext>
| InterfaceTypeComposer<TSource, TContext>
| UnionTypeComposer<TSource, TContext>
| ScalarTypeComposer<TContext>;

/**
* Alias for `getFieldTC()` but returns statically checked ObjectTypeComposer.
* If field have other type then error will be thrown.
*/
public getFieldOTC(fieldName: string): ObjectTypeComposer<TSource, TContext>;

public makeFieldNonNull(fieldNameOrArray: string | string[]): this;

public makeFieldNullable(fieldNameOrArray: string | string[]): this;
Expand All @@ -162,6 +167,17 @@ export class InterfaceTypeComposer<TSource = any, TContext = any> {

public getFieldArgType(fieldName: string, argName: string): GraphQLInputType;

public getFieldArgTC(
fieldName: string,
argName: string
): InputTypeComposer<TContext> | EnumTypeComposer<TContext> | ScalarTypeComposer<TContext>;

/**
* Alias for `getFieldArgTC()` but returns statically checked InputTypeComposer.
* If field have other type then error will be thrown.
*/
public getFieldArgITC(fieldName: string, argName: string): InputTypeComposer<TContext>;

public setFieldArgs(fieldName: string, args: ComposeFieldConfigArgumentMap<any>): this;

public addFieldArgs(fieldName: string, newArgs: ComposeFieldConfigMap<TSource, TContext>): this;
Expand Down
65 changes: 61 additions & 4 deletions src/InterfaceTypeComposer.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import type {
GraphQLResolveInfo,
GraphQLTypeResolver,
} from './graphql';
import type { InputTypeComposer } from './InputTypeComposer';
import { InputTypeComposer } from './InputTypeComposer';
import type { EnumTypeComposer } from './EnumTypeComposer';
import type { UnionTypeComposer } from './UnionTypeComposer';
import { UnionTypeComposer } from './UnionTypeComposer';
import type { ScalarTypeComposer } from './ScalarTypeComposer';
import type { TypeAsString, TypeDefinitionString } from './TypeMapper';
import { SchemaComposer } from './SchemaComposer';
Expand Down Expand Up @@ -345,13 +345,34 @@ export class InterfaceTypeComposer<TSource, TContext> {
fieldName: string
):
| ObjectTypeComposer<TSource, TContext>
| InputTypeComposer<TContext>
| EnumTypeComposer<TContext>
| InterfaceTypeComposer<TSource, TContext>
| UnionTypeComposer<TSource, TContext>
| ScalarTypeComposer<TContext> {
const fieldType = getNamedType(this.getFieldType(fieldName));
return this.schemaComposer.createTempTC(fieldType);
const tc = this.schemaComposer.createTC(fieldType);
if (tc instanceof InputTypeComposer) {
throw new Error(
`${this.getTypeName()}.getFieldTC('${fieldName}') returns InputTypeComposer. It's very strange cause fields may have only Output types (Scalar, Object, Enum, Union, Interface).`
);
}
return tc;
}

/**
* Alias for `getFieldTC()` but returns statically checked ObjectTypeComposer.
* If field have other type then error will be thrown.
*/
getFieldOTC(fieldName: string): ObjectTypeComposer<TSource, TContext> {
const tc = this.getFieldTC(fieldName);
if (!(tc instanceof ObjectTypeComposer)) {
throw new Error(
`${this.getTypeName()}.getFieldOTC('${fieldName}') must be ObjectTypeComposer, but recieved ${
tc.constructor.name
}. Maybe you need to use 'getFieldTC()' method which returns any type composer?`
);
}
return tc;
}

makeFieldNonNull(fieldNameOrArray: string | string[]): InterfaceTypeComposer<TSource, TContext> {
Expand Down Expand Up @@ -466,6 +487,42 @@ export class InterfaceTypeComposer<TSource, TContext> {
return graphqlAC.type;
}

getFieldArgTC(
fieldName: string,
argName: string
): InputTypeComposer<TContext> | EnumTypeComposer<TContext> | ScalarTypeComposer<TContext> {
const fieldType = getNamedType(this.getFieldArgType(fieldName, argName));
const tc = this.schemaComposer.createTC(fieldType);
if (
tc instanceof ObjectTypeComposer ||
tc instanceof InterfaceTypeComposer ||
tc instanceof UnionTypeComposer
) {
throw new Error(
`${this.getTypeName()}.getFieldArgTC('${fieldName}', '${argName}') returns ${
tc.constructor.name
}. It's very strange cause args may have only Input types (Scalar, InputObject, Enum).`
);
}
return tc;
}

/**
* Alias for `getFieldArgTC()` but returns statically checked InputTypeComposer.
* If field have other type then error will be thrown.
*/
getFieldArgITC(fieldName: string, argName: string): InputTypeComposer<TContext> {
const tc = this.getFieldArgTC(fieldName, argName);
if (!(tc instanceof InputTypeComposer)) {
throw new Error(
`${this.getTypeName()}.getFieldArgITC('${fieldName}', '${argName}') must be InputTypeComposer, but recieved ${
tc.constructor.name
}. Maybe you need to use 'getFieldArgTC()' method which returns any type composer?`
);
}
return tc;
}

setFieldArgs(
fieldName: string,
args: ComposeFieldConfigArgumentMap<any>
Expand Down
21 changes: 21 additions & 0 deletions src/__tests__/InterfaceTypeComposer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,24 @@ describe('InterfaceTypeComposer', () => {
);
expect(iftc.hasFieldArg('unexistedField', 'arg1')).toBeFalsy();
});

it('getFieldArgTC()', () => {
iftc.setField('fieldWithArgs', {
type: 'Int',
args: {
scalarArg: '[Int]',
complexArg: `input SomeInput { a: Int, b: Int }`,
},
});
expect(iftc.getFieldArgTC('fieldWithArgs', 'scalarArg')).toBeInstanceOf(ScalarTypeComposer);
const argTC = iftc.getFieldArgTC('fieldWithArgs', 'complexArg');
expect(argTC).toBeInstanceOf(InputTypeComposer);
// should return the same TC instance
expect(iftc.getFieldArgITC('fieldWithArgs', 'complexArg')).toBe(argTC);
expect(() => iftc.getFieldArgITC('fieldWithArgs', 'scalarArg')).toThrow(
'must be InputTypeComposer'
);
});
});

describe('extendField()', () => {
Expand Down Expand Up @@ -567,12 +585,15 @@ describe('InterfaceTypeComposer', () => {
const tco = myIFTC.getFieldTC('objArr');
expect(tco).toBeInstanceOf(ObjectTypeComposer);
expect(tco.getTypeName()).toBe('MyCustomObjType2');
const tco2 = myIFTC.getFieldOTC('objArr');
expect(tco).toBe(tco2);
});

it('should return TypeComposer for scalar fields', () => {
const tco = myIFTC.getFieldTC('scalar');
expect(tco).toBeInstanceOf(ScalarTypeComposer);
expect(tco.getTypeName()).toBe('String');
expect(() => myIFTC.getFieldOTC('scalar')).toThrow('must be ObjectTypeComposer');
});

it('should return TypeComposer for scalar list fields', () => {
Expand Down

0 comments on commit f0aef21

Please sign in to comment.