Skip to content

Commit c8d1c28

Browse files
committed
Add 'toConfig' method
1 parent 9e40465 commit c8d1c28

File tree

5 files changed

+313
-263
lines changed

5 files changed

+313
-263
lines changed

src/type/definition.js

Lines changed: 147 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import instanceOf from '../jsutils/instanceOf';
1414
import inspect from '../jsutils/inspect';
1515
import invariant from '../jsutils/invariant';
1616
import keyMap from '../jsutils/keyMap';
17+
import keyValMap from '../jsutils/keyValMap';
1718
import mapValue from '../jsutils/mapValue';
1819
import type { ObjMap } from '../jsutils/ObjMap';
1920
import { Kind } from '../language/kinds';
@@ -510,6 +511,10 @@ function resolveThunk<+T>(thunk: Thunk<T>): T {
510511
return typeof thunk === 'function' ? thunk() : thunk;
511512
}
512513

514+
function undefineIfEmpty<T>(arr: ?$ReadOnlyArray<T>): ?$ReadOnlyArray<T> {
515+
return arr && arr.length > 0 ? arr : undefined;
516+
}
517+
513518
/**
514519
* Scalar Type Definition
515520
*
@@ -550,7 +555,7 @@ export class GraphQLScalarType {
550555
this.parseValue = config.parseValue || (value => value);
551556
this.parseLiteral = config.parseLiteral || valueFromASTUntyped;
552557
this.astNode = config.astNode;
553-
this.extensionASTNodes = config.extensionASTNodes;
558+
this.extensionASTNodes = undefineIfEmpty(config.extensionASTNodes);
554559
invariant(typeof config.name === 'string', 'Must provide name.');
555560
invariant(
556561
typeof config.serialize === 'function',
@@ -568,6 +573,23 @@ export class GraphQLScalarType {
568573
}
569574
}
570575

576+
toConfig(): {|
577+
...GraphQLScalarTypeConfig<*, *>,
578+
parseValue: GraphQLScalarValueParser<*>,
579+
parseLiteral: GraphQLScalarLiteralParser<*>,
580+
extensionASTNodes: $ReadOnlyArray<ScalarTypeExtensionNode>,
581+
|} {
582+
return {
583+
name: this.name,
584+
description: this.description,
585+
serialize: this.serialize,
586+
parseValue: this.parseValue,
587+
parseLiteral: this.parseLiteral,
588+
astNode: this.astNode,
589+
extensionASTNodes: this.extensionASTNodes || [],
590+
};
591+
}
592+
571593
toString(): string {
572594
return this.name;
573595
}
@@ -648,7 +670,7 @@ export class GraphQLObjectType {
648670
this.name = config.name;
649671
this.description = config.description;
650672
this.astNode = config.astNode;
651-
this.extensionASTNodes = config.extensionASTNodes;
673+
this.extensionASTNodes = undefineIfEmpty(config.extensionASTNodes);
652674
this.isTypeOf = config.isTypeOf;
653675
this._fields = defineFieldMap.bind(undefined, config);
654676
this._interfaces = defineInterfaces.bind(undefined, config);
@@ -674,6 +696,23 @@ export class GraphQLObjectType {
674696
return this._interfaces;
675697
}
676698

699+
toConfig(): {|
700+
...GraphQLObjectTypeConfig<*, *>,
701+
interfaces: Array<GraphQLInterfaceType>,
702+
fields: GraphQLFieldConfigMap<*, *>,
703+
extensionASTNodes: $ReadOnlyArray<ObjectTypeExtensionNode>,
704+
|} {
705+
return {
706+
name: this.name,
707+
description: this.description,
708+
isTypeOf: this.isTypeOf,
709+
interfaces: this.getInterfaces(),
710+
fields: fieldsToFieldsConfig(this.getFields()),
711+
astNode: this.astNode,
712+
extensionASTNodes: this.extensionASTNodes || [],
713+
};
714+
}
715+
677716
toString(): string {
678717
return this.name;
679718
}
@@ -751,6 +790,33 @@ function isPlainObj(obj) {
751790
return obj && typeof obj === 'object' && !Array.isArray(obj);
752791
}
753792

793+
function fieldsToFieldsConfig(fields) {
794+
return mapValue(fields, field => ({
795+
type: field.type,
796+
args: argsToArgsConfig(field.args),
797+
resolve: field.resolve,
798+
subscribe: field.subscribe,
799+
deprecationReason: field.deprecationReason,
800+
description: field.description,
801+
astNode: field.astNode,
802+
}));
803+
}
804+
805+
export function argsToArgsConfig(
806+
args: Array<GraphQLArgument>,
807+
): GraphQLFieldConfigArgumentMap {
808+
return keyValMap(
809+
args,
810+
arg => arg.name,
811+
arg => ({
812+
type: arg.type,
813+
defaultValue: arg.defaultValue,
814+
description: arg.description,
815+
astNode: arg.astNode,
816+
}),
817+
);
818+
}
819+
754820
export type GraphQLObjectTypeConfig<TSource, TContext> = {|
755821
name: string,
756822
interfaces?: Thunk<?Array<GraphQLInterfaceType>>,
@@ -892,7 +958,7 @@ export class GraphQLInterfaceType {
892958
this.name = config.name;
893959
this.description = config.description;
894960
this.astNode = config.astNode;
895-
this.extensionASTNodes = config.extensionASTNodes;
961+
this.extensionASTNodes = undefineIfEmpty(config.extensionASTNodes);
896962
this.resolveType = config.resolveType;
897963
this._fields = defineFieldMap.bind(undefined, config);
898964
invariant(typeof config.name === 'string', 'Must provide name.');
@@ -910,6 +976,21 @@ export class GraphQLInterfaceType {
910976
return this._fields;
911977
}
912978

979+
toConfig(): {|
980+
...GraphQLInterfaceTypeConfig<*, *>,
981+
fields: GraphQLFieldConfigMap<*, *>,
982+
extensionASTNodes: $ReadOnlyArray<InterfaceTypeExtensionNode>,
983+
|} {
984+
return {
985+
name: this.name,
986+
description: this.description,
987+
resolveType: this.resolveType,
988+
fields: fieldsToFieldsConfig(this.getFields()),
989+
astNode: this.astNode,
990+
extensionASTNodes: this.extensionASTNodes || [],
991+
};
992+
}
993+
913994
toString(): string {
914995
return this.name;
915996
}
@@ -969,7 +1050,7 @@ export class GraphQLUnionType {
9691050
this.name = config.name;
9701051
this.description = config.description;
9711052
this.astNode = config.astNode;
972-
this.extensionASTNodes = config.extensionASTNodes;
1053+
this.extensionASTNodes = undefineIfEmpty(config.extensionASTNodes);
9731054
this.resolveType = config.resolveType;
9741055
this._types = defineTypes.bind(undefined, config);
9751056
invariant(typeof config.name === 'string', 'Must provide name.');
@@ -987,6 +1068,21 @@ export class GraphQLUnionType {
9871068
return this._types;
9881069
}
9891070

1071+
toConfig(): {|
1072+
...GraphQLUnionTypeConfig<*, *>,
1073+
types: Array<GraphQLObjectType>,
1074+
extensionASTNodes: $ReadOnlyArray<UnionTypeExtensionNode>,
1075+
|} {
1076+
return {
1077+
name: this.name,
1078+
description: this.description,
1079+
resolveType: this.resolveType,
1080+
types: this.getTypes(),
1081+
astNode: this.astNode,
1082+
extensionASTNodes: this.extensionASTNodes || [],
1083+
};
1084+
}
1085+
9901086
toString(): string {
9911087
return this.name;
9921088
}
@@ -1057,7 +1153,7 @@ export class GraphQLEnumType /* <T> */ {
10571153
this.name = config.name;
10581154
this.description = config.description;
10591155
this.astNode = config.astNode;
1060-
this.extensionASTNodes = config.extensionASTNodes;
1156+
this.extensionASTNodes = undefineIfEmpty(config.extensionASTNodes);
10611157
this._values = defineEnumValues(this, config.values);
10621158
this._valueLookup = new Map(
10631159
this._values.map(enumValue => [enumValue.value, enumValue]),
@@ -1101,6 +1197,30 @@ export class GraphQLEnumType /* <T> */ {
11011197
}
11021198
}
11031199

1200+
toConfig(): {|
1201+
...GraphQLEnumTypeConfig,
1202+
extensionASTNodes: $ReadOnlyArray<EnumTypeExtensionNode>,
1203+
|} {
1204+
const values = keyValMap(
1205+
this.getValues(),
1206+
value => value.name,
1207+
value => ({
1208+
description: value.description,
1209+
value: value.value,
1210+
deprecationReason: value.deprecationReason,
1211+
astNode: value.astNode,
1212+
}),
1213+
);
1214+
1215+
return {
1216+
name: this.name,
1217+
description: this.description,
1218+
values,
1219+
astNode: this.astNode,
1220+
extensionASTNodes: this.extensionASTNodes || [],
1221+
};
1222+
}
1223+
11041224
toString(): string {
11051225
return this.name;
11061226
}
@@ -1198,7 +1318,7 @@ export class GraphQLInputObjectType {
11981318
this.name = config.name;
11991319
this.description = config.description;
12001320
this.astNode = config.astNode;
1201-
this.extensionASTNodes = config.extensionASTNodes;
1321+
this.extensionASTNodes = undefineIfEmpty(config.extensionASTNodes);
12021322
this._fields = defineInputFieldMap.bind(undefined, config);
12031323
invariant(typeof config.name === 'string', 'Must provide name.');
12041324
}
@@ -1210,6 +1330,27 @@ export class GraphQLInputObjectType {
12101330
return this._fields;
12111331
}
12121332

1333+
toConfig(): {|
1334+
...GraphQLInputObjectTypeConfig,
1335+
fields: GraphQLInputFieldConfigMap,
1336+
extensionASTNodes: $ReadOnlyArray<InputObjectTypeExtensionNode>,
1337+
|} {
1338+
const fields = mapValue(this.getFields(), field => ({
1339+
description: field.description,
1340+
type: field.type,
1341+
defaultValue: field.defaultValue,
1342+
astNode: field.astNode,
1343+
}));
1344+
1345+
return {
1346+
name: this.name,
1347+
description: this.description,
1348+
fields,
1349+
astNode: this.astNode,
1350+
extensionASTNodes: this.extensionASTNodes || [],
1351+
};
1352+
}
1353+
12131354
toString(): string {
12141355
return this.name;
12151356
}

src/type/directives.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
import objectEntries from '../polyfills/objectEntries';
11+
import { argsToArgsConfig } from './definition';
1112
import type {
1213
GraphQLFieldConfigArgumentMap,
1314
GraphQLArgument,
@@ -84,6 +85,19 @@ export class GraphQLDirective {
8485
toString(): string {
8586
return '@' + this.name;
8687
}
88+
89+
toConfig(): {|
90+
...GraphQLDirectiveConfig,
91+
args: GraphQLFieldConfigArgumentMap,
92+
|} {
93+
return {
94+
name: this.name,
95+
description: this.description,
96+
locations: this.locations,
97+
args: argsToArgsConfig(this.args),
98+
astNode: this.astNode,
99+
};
100+
}
87101
}
88102

89103
// Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported

src/type/schema.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,27 @@ export class GraphQLSchema {
238238
getDirective(name: string): ?GraphQLDirective {
239239
return find(this.getDirectives(), directive => directive.name === name);
240240
}
241+
242+
toConfig(): {|
243+
...GraphQLSchemaConfig,
244+
types: Array<GraphQLNamedType>,
245+
directives: Array<GraphQLDirective>,
246+
extensionASTNodes: $ReadOnlyArray<SchemaExtensionNode>,
247+
assumeValid: boolean,
248+
allowedLegacyNames: $ReadOnlyArray<string>,
249+
|} {
250+
return {
251+
types: objectValues(this.getTypeMap()),
252+
directives: this.getDirectives().slice(),
253+
query: this.getQueryType(),
254+
mutation: this.getMutationType(),
255+
subscription: this.getSubscriptionType(),
256+
astNode: this.astNode,
257+
extensionASTNodes: this.extensionASTNodes || [],
258+
assumeValid: this.__validationErrors !== undefined,
259+
allowedLegacyNames: this.__allowedLegacyNames,
260+
};
261+
}
241262
}
242263

243264
// Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported

0 commit comments

Comments
 (0)