Skip to content

Commit

Permalink
feat: created types via TypeComposer.create() now added to TypeStorag…
Browse files Browse the repository at this point in the history
…e and may be used in SDL by name
  • Loading branch information
nodkz committed Apr 25, 2018
1 parent ea443fb commit b3e28b8
Show file tree
Hide file tree
Showing 15 changed files with 220 additions and 31 deletions.
2 changes: 2 additions & 0 deletions src/EnumTypeComposer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export class EnumTypeComposer {

public static create(opts: TypeAsString | GraphQLEnumTypeConfig | GraphQLEnumType): EnumTypeComposer;

public static createTemp(opts: TypeAsString | GraphQLEnumTypeConfig | GraphQLEnumType): EnumTypeComposer;

public hasField(name: string): boolean;

public getFields(): GraphQLEnumValueConfigMap;
Expand Down
9 changes: 9 additions & 0 deletions src/EnumTypeComposer.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ export class EnumTypeComposer {
static schemaComposer: SchemaComposer<any>;

static create(opts: TypeAsString | GraphQLEnumTypeConfig | GraphQLEnumType): EnumTypeComposer {
const etc = this.createTemp(opts);
this.schemaComposer.add(etc);
return etc;
}

static createTemp(
opts: TypeAsString | GraphQLEnumTypeConfig | GraphQLEnumType
): EnumTypeComposer {
if (!this.schemaComposer) {
throw new Error('Class<EnumTypeComposer> must be created by a SchemaComposer.');
}
Expand Down Expand Up @@ -217,6 +225,7 @@ export class EnumTypeComposer {
setTypeName(name: string): EnumTypeComposer {
this.gqType.name = name;
this.gqType._enumConfig.name = name;
this.constructor.schemaComposer.add(this);
return this;
}

Expand Down
4 changes: 4 additions & 0 deletions src/InputTypeComposer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export class InputTypeComposer {
ComposeInputObjectTypeConfig |
GraphQLInputObjectType): InputTypeComposer;

public static createTemp(opts: TypeAsString |
ComposeInputObjectTypeConfig |
GraphQLInputObjectType): InputTypeComposer;

/**
* Get fields from a GraphQL type
* WARNING: this method read an internal GraphQL instance variable.
Expand Down
11 changes: 10 additions & 1 deletion src/InputTypeComposer.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ export class InputTypeComposer {

static create(
opts: TypeAsString | ComposeInputObjectTypeConfig | GraphQLInputObjectType
): InputTypeComposer {
const itc = this.createTemp(opts);
this.schemaComposer.add(itc);
return itc;
}

static createTemp(
opts: TypeAsString | ComposeInputObjectTypeConfig | GraphQLInputObjectType
): InputTypeComposer {
if (!this.schemaComposer) {
throw new Error('Class<InputTypeComposer> must be created by a SchemaComposer.');
Expand Down Expand Up @@ -268,7 +276,7 @@ export class InputTypeComposer {
`This field should be InputObjectType, but it has type '${fieldType.constructor.name}'`
);
}
return this.constructor.schemaComposer.InputTypeComposer.create(fieldType);
return this.constructor.schemaComposer.InputTypeComposer.createTemp(fieldType);
}

makeRequired(fieldNameOrArray: string | Array<string>): InputTypeComposer {
Expand Down Expand Up @@ -330,6 +338,7 @@ export class InputTypeComposer {

setTypeName(name: string): InputTypeComposer {
this.gqType.name = name;
this.constructor.schemaComposer.add(this);
return this;
}

Expand Down
8 changes: 4 additions & 4 deletions src/Resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ export class Resolver<TSource, TContext> {
throw new Error('You should provide new type name. It is equal to current name.');
}

let clonedType = this.constructor.schemaComposer.InputTypeComposer.create(originalType)
let clonedType = this.constructor.schemaComposer.InputTypeComposer.createTemp(originalType)
.clone(newTypeName)
.getType();
if (isUnwrapped) {
Expand Down Expand Up @@ -579,7 +579,7 @@ export class Resolver<TSource, TContext> {
'Eg. FilterXXXXXInput'
);
}
filterITC = this.constructor.schemaComposer.InputTypeComposer.create(
filterITC = this.constructor.schemaComposer.InputTypeComposer.createTemp(
opts.filterTypeNameFallback
);
}
Expand Down Expand Up @@ -642,7 +642,7 @@ export class Resolver<TSource, TContext> {
if (resolver.hasArg('sort')) {
const sortConfig = resolver.getArgConfig('sort');
if (sortConfig.type instanceof GraphQLEnumType) {
sortETC = this.constructor.schemaComposer.EnumTypeComposer.create(sortConfig.type);
sortETC = this.constructor.schemaComposer.EnumTypeComposer.createTemp(sortConfig.type);
} else {
throw new Error(
'Resolver must have `sort` arg with type GraphQLEnumType. ' +
Expand All @@ -657,7 +657,7 @@ export class Resolver<TSource, TContext> {
'Eg. SortXXXXXEnum'
);
}
sortETC = this.constructor.schemaComposer.EnumTypeComposer.create({
sortETC = this.constructor.schemaComposer.EnumTypeComposer.createTemp({
name: opts.sortTypeNameFallback,
values: {
[opts.name]: {},
Expand Down
6 changes: 6 additions & 0 deletions src/TypeComposer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ export class TypeComposer<TContext> {
| ComposeObjectTypeConfig<any, TCtx>
| GraphQLObjectType): TypeComposer<TCtx>;

public static createTemp<TCtx>(
opts:
| TypeAsString
| ComposeObjectTypeConfig<any, TCtx>
| GraphQLObjectType): TypeComposer<TCtx>;

/**
* Get fields from a GraphQL type
* WARNING: this method read an internal GraphQL instance variable.
Expand Down
16 changes: 14 additions & 2 deletions src/TypeComposer.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,17 @@ export class TypeComposer<TContext> {

static create(
opts: TypeAsString | ComposeObjectTypeConfig<any, TContext> | GraphQLObjectType
): TypeComposer<TContext> {
const tc = this.createTemp(opts);
const typeName = tc.getTypeName();
if (typeName !== 'Query' && typeName !== 'Mutation' && typeName !== 'Subscription') {
this.schemaComposer.add(tc);
}
return tc;
}

static createTemp(
opts: TypeAsString | ComposeObjectTypeConfig<any, TContext> | GraphQLObjectType
): TypeComposer<TContext> {
if (!this.schemaComposer) {
throw new Error('Class<TypeComposer> must be created by a SchemaComposer.');
Expand Down Expand Up @@ -310,7 +321,7 @@ export class TypeComposer<TContext> {
// nested field
let childTC;
if (!this.hasField(name)) {
childTC = this.constructor.schemaComposer.TypeComposer.create({
childTC = this.constructor.schemaComposer.TypeComposer.createTemp({
name: `${this.getTypeName()}${upperFirst(name)}`,
});
this.setField(name, {
Expand Down Expand Up @@ -610,7 +621,7 @@ export class TypeComposer<TContext> {
`This field should be ObjectType, but it has type '${fieldType.constructor.name}'`
);
}
return this.constructor.schemaComposer.TypeComposer.create(fieldType);
return this.constructor.schemaComposer.TypeComposer.createTemp(fieldType);
}

makeFieldNonNull(fieldNameOrArray: string | Array<string>): TypeComposer<TContext> {
Expand Down Expand Up @@ -761,6 +772,7 @@ export class TypeComposer<TContext> {

setTypeName(name: string): TypeComposer<TContext> {
this.gqType.name = name;
this.constructor.schemaComposer.add(this);
return this;
}

Expand Down
2 changes: 1 addition & 1 deletion src/TypeStorage.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class TypeStorage<TContext> {

public values(): Iterator<V<TContext>>;

public add(value: V<TContext>): void;
public add(value: V<TContext>): string | null;

public hasInstance(key: K, ClassObj: any): boolean;

Expand Down
14 changes: 10 additions & 4 deletions src/TypeStorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,22 @@ export class TypeStorage<TContext> {
return this.types.values();
}

add(value: V<TContext>): void {
add(value: V<TContext>): ?string {
if (value) {
let typeName: ?string;
if (value.getTypeName && value.getTypeName.call) {
// $FlowFixMe
this.set(value.getTypeName(), value);
typeName = (value.getTypeName(): any);
} else if (value.name) {
// $FlowFixMe
this.set(value.name, value);
typeName = (value.name: any);
}

if (typeName) {
this.set(typeName, value);
return typeName;
}
}
return null;
}

hasInstance(typeName: K, ClassObj: any): boolean {
Expand Down
16 changes: 15 additions & 1 deletion src/__tests__/EnumTypeComposer-test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
/* @flow strict */

import { EnumTypeComposer } from '../';
import { EnumTypeComposer, schemaComposer } from '../';
import { GraphQLList, GraphQLNonNull, GraphQLEnumType } from '../graphql';
import { graphqlVersion } from '../utils/graphqlVersion';

beforeEach(() => {
schemaComposer.clear();
});

describe('EnumTypeComposer', () => {
let enumType: GraphQLEnumType;
let etc: EnumTypeComposer;
Expand Down Expand Up @@ -191,6 +195,16 @@ describe('EnumTypeComposer', () => {
const myTC = EnumTypeComposer.create('MyEnum');
expect(myTC.getFieldNames()).toEqual([]);
});

it('should create type and store it in schemaComposer', () => {
const SomeUserETC = EnumTypeComposer.create('SomeUserEnum');
expect(schemaComposer.getETC('SomeUserEnum')).toBe(SomeUserETC);
});

it('createTemp() should not store type in schemaComposer', () => {
EnumTypeComposer.createTemp('SomeUserEnum');
expect(schemaComposer.has('SomeUserEnum')).toBeFalsy();
});
});

describe('type methods', () => {
Expand Down
16 changes: 15 additions & 1 deletion src/__tests__/InputTypeComposer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import {
GraphQLInt,
GraphQLBoolean,
} from '../graphql';
import { InputTypeComposer } from '../';
import { InputTypeComposer, schemaComposer } from '../';

beforeEach(() => {
schemaComposer.clear();
});

describe('InputTypeComposer', () => {
let objectType: GraphQLInputObjectType;
Expand Down Expand Up @@ -306,6 +310,16 @@ describe('InputTypeComposer', () => {
expect(itc1.getType()).toBe(objType);
expect(itc1.getFieldType('f1')).toBe(GraphQLString);
});

it('should create type and store it in schemaComposer', () => {
const SomeUserITC = InputTypeComposer.create('SomeUserInput');
expect(schemaComposer.getITC('SomeUserInput')).toBe(SomeUserITC);
});

it('createTemp() should not store type in schemaComposer', () => {
InputTypeComposer.createTemp('SomeUserInput');
expect(schemaComposer.has('SomeUserInput')).toBeFalsy();
});
});

it('get() should return type by path', () => {
Expand Down
27 changes: 26 additions & 1 deletion src/__tests__/TypeComposer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import {
GraphQLBoolean,
GraphQLInterfaceType,
} from '../graphql';
import { TypeComposer, Resolver } from '../';
import { TypeComposer, Resolver, schemaComposer } from '../';

beforeEach(() => {
schemaComposer.clear();
});

describe('TypeComposer', () => {
let objectType: GraphQLObjectType;
Expand Down Expand Up @@ -385,6 +389,27 @@ describe('TypeComposer', () => {
expect(myTC.getType()).toBe(objType);
expect(myTC.getFieldType('f1')).toBe(GraphQLString);
});

it('should create type and store it in schemaComposer', () => {
const SomeUserTC = TypeComposer.create('SomeUser');
expect(schemaComposer.getTC('SomeUser')).toBe(SomeUserTC);
});

it('should create type and NOTE store root types in schemaComposer', () => {
TypeComposer.create('Query');
expect(schemaComposer.has('Query')).toBeFalsy();

TypeComposer.create('Mutation');
expect(schemaComposer.has('Query')).toBeFalsy();

TypeComposer.create('Subscription');
expect(schemaComposer.has('Query')).toBeFalsy();
});

it('createTemp() should not store type in schemaComposer', () => {
TypeComposer.createTemp('SomeUser');
expect(schemaComposer.has('SomeUser')).toBeFalsy();
});
});

describe('clone()', () => {
Expand Down
26 changes: 15 additions & 11 deletions src/__tests__/TypeMapper-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,21 @@ import {
GraphQLNonNull,
GraphQLEnumType,
} from '../graphql';
import { GQC, TypeComposer, InputTypeComposer, EnumTypeComposer, Resolver, TypeMapper } from '../';
import {
schemaComposer,
TypeComposer,
InputTypeComposer,
EnumTypeComposer,
Resolver,
TypeMapper,
} from '../';
import { graphqlVersion } from '../utils/graphqlVersion';
import GraphQLJSON from '../type/json';
import GraphQLDate from '../type/date';
import GraphQLBuffer from '../type/buffer';

beforeEach(() => {
GQC.clear();
schemaComposer.clear();
});

describe('TypeMapper', () => {
Expand Down Expand Up @@ -165,12 +172,13 @@ describe('TypeMapper', () => {
expect(fc.type).toBe(GraphQLString);
});

it('should lookup type name as string in GQC', () => {
it('should lookup type name as string in schemaComposer', () => {
const tc = TypeComposer.create(`type MyType { a: Int }`);
GQC.add(tc);

const fc = TypeMapper.convertOutputFieldConfig('MyType');
expect(fc.type).toBe(tc.getType());

const fc2: any = TypeMapper.convertOutputFieldConfig({ type: '[MyType]' });
expect(fc2.type.ofType).toBe(tc.getType());
});

it('should create field config from GraphQL Schema Language', () => {
Expand Down Expand Up @@ -395,10 +403,8 @@ describe('TypeMapper', () => {
expect(ic.type).toBe(GraphQLString);
});

it('should lookup type name as string in GQC', () => {
it('should lookup type name as string in schemaComposer', () => {
const itc = InputTypeComposer.create(`input MyInput { a: Int }`);
GQC.add(itc);

const ic = TypeMapper.convertInputFieldConfig('MyInput');
expect(ic.type).toBe(itc.getType());
});
Expand Down Expand Up @@ -584,10 +590,8 @@ describe('TypeMapper', () => {
expect(ac.type).toBe(GraphQLString);
});

it('should lookup type name as string in GQC', () => {
it('should lookup type name as string in schemaComposer', () => {
const itc = InputTypeComposer.create(`input MyArg { a: Int }`);
GQC.add(itc);

const ac = TypeMapper.convertArgConfig('MyArg');
expect(ac.type).toBe(itc.getType());
});
Expand Down

0 comments on commit b3e28b8

Please sign in to comment.