Skip to content

Commit faeea7f

Browse files
mjmahoneleebyron
authored andcommitted
Json serialize types (#1378)
* Schema definitions now JSON serializeable * Remove commented-out code * Keep flow definitions with toJSON and inspect * Factor out into utility function, change applyToStringTag naming to match Also realized we weren't doing the same thing for directives, so fixed that as well.
1 parent 023c555 commit faeea7f

File tree

7 files changed

+69
-63
lines changed

7 files changed

+69
-63
lines changed

src/jsutils/defineToJSON.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict
8+
*/
9+
10+
/**
11+
* The `applyToJSON()` function defines toJSON() and inspect() prototype
12+
* methods which are aliases for toString().
13+
*/
14+
export default function applyToJSON(classObject: Class<any>): void {
15+
classObject.prototype.toJSON = classObject.prototype.inspect =
16+
classObject.prototype.toString;
17+
}
File renamed without changes.

src/language/source.js

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

1010
import invariant from '../jsutils/invariant';
11-
import applyToStringTag from '../jsutils/applyToStringTag';
11+
import defineToStringTag from '../jsutils/defineToStringTag';
1212

1313
type Location = {
1414
line: number,
@@ -44,4 +44,4 @@ export class Source {
4444
}
4545

4646
// Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported
47-
applyToStringTag(Source);
47+
defineToStringTag(Source);

src/type/__tests__/definition-test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,26 @@ describe('Type System: Example', () => {
348348
expect(String(GraphQLList(GraphQLList(GraphQLInt)))).to.equal('[[Int]]');
349349
});
350350

351+
it('JSON stringifies simple types', () => {
352+
expect(JSON.stringify(GraphQLInt)).to.equal('"Int"');
353+
expect(JSON.stringify(BlogArticle)).to.equal('"Article"');
354+
expect(JSON.stringify(InterfaceType)).to.equal('"Interface"');
355+
expect(JSON.stringify(UnionType)).to.equal('"Union"');
356+
expect(JSON.stringify(EnumType)).to.equal('"Enum"');
357+
expect(JSON.stringify(InputObjectType)).to.equal('"InputObject"');
358+
expect(JSON.stringify(GraphQLNonNull(GraphQLInt))).to.equal('"Int!"');
359+
expect(JSON.stringify(GraphQLList(GraphQLInt))).to.equal('"[Int]"');
360+
expect(JSON.stringify(GraphQLNonNull(GraphQLList(GraphQLInt)))).to.equal(
361+
'"[Int]!"',
362+
);
363+
expect(JSON.stringify(GraphQLList(GraphQLNonNull(GraphQLInt)))).to.equal(
364+
'"[Int!]"',
365+
);
366+
expect(JSON.stringify(GraphQLList(GraphQLList(GraphQLInt)))).to.equal(
367+
'"[[Int]]"',
368+
);
369+
});
370+
351371
it('identifies input types', () => {
352372
const expected = [
353373
[GraphQLInt, true],

src/type/definition.js

Lines changed: 20 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
* @flow strict
88
*/
99

10-
import applyToStringTag from '../jsutils/applyToStringTag';
10+
import defineToJSON from '../jsutils/defineToJSON';
11+
import defineToStringTag from '../jsutils/defineToStringTag';
1112
import instanceOf from '../jsutils/instanceOf';
1213
import inspect from '../jsutils/inspect';
1314
import invariant from '../jsutils/invariant';
@@ -349,11 +350,11 @@ export function GraphQLList(ofType) {
349350
}
350351
}
351352

352-
// Also provide toJSON and inspect aliases for toString.
353-
const listProto: any = GraphQLList.prototype;
354-
listProto.toString = listProto.toJSON = listProto.inspect = function toString() {
353+
// Need to cast through any to alter the prototype.
354+
(GraphQLList.prototype: any).toString = function toString() {
355355
return '[' + String(this.ofType) + ']';
356356
};
357+
defineToJSON(GraphQLList);
357358

358359
/**
359360
* Non-Null Type Wrapper
@@ -390,11 +391,11 @@ export function GraphQLNonNull(ofType) {
390391
}
391392
}
392393

393-
// Also provide toJSON and inspect aliases for toString.
394-
const nonNullProto: any = GraphQLNonNull.prototype;
395-
nonNullProto.toString = nonNullProto.toJSON = nonNullProto.inspect = function toString() {
394+
// Need to cast through any to alter the prototype.
395+
(GraphQLNonNull.prototype: any).toString = function toString() {
396396
return String(this.ofType) + '!';
397397
};
398+
defineToJSON(GraphQLNonNull);
398399

399400
/**
400401
* These types wrap and modify other types
@@ -579,17 +580,11 @@ export class GraphQLScalarType {
579580
toString(): string {
580581
return this.name;
581582
}
582-
583-
toJSON: () => string;
584-
inspect: () => string;
585583
}
586584

587585
// Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported
588-
applyToStringTag(GraphQLScalarType);
589-
590-
// Also provide toJSON and inspect aliases for toString.
591-
GraphQLScalarType.prototype.toJSON = GraphQLScalarType.prototype.inspect =
592-
GraphQLScalarType.prototype.toString;
586+
defineToStringTag(GraphQLScalarType);
587+
defineToJSON(GraphQLScalarType);
593588

594589
export type GraphQLScalarTypeConfig<TInternal, TExternal> = {
595590
name: string,
@@ -684,17 +679,11 @@ export class GraphQLObjectType {
684679
toString(): string {
685680
return this.name;
686681
}
687-
688-
toJSON: () => string;
689-
inspect: () => string;
690682
}
691683

692684
// Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported
693-
applyToStringTag(GraphQLObjectType);
694-
695-
// Also provide toJSON and inspect aliases for toString.
696-
GraphQLObjectType.prototype.toJSON = GraphQLObjectType.prototype.inspect =
697-
GraphQLObjectType.prototype.toString;
685+
defineToStringTag(GraphQLObjectType);
686+
defineToJSON(GraphQLObjectType);
698687

699688
function defineInterfaces(
700689
type: GraphQLObjectType,
@@ -936,17 +925,11 @@ export class GraphQLInterfaceType {
936925
toString(): string {
937926
return this.name;
938927
}
939-
940-
toJSON: () => string;
941-
inspect: () => string;
942928
}
943929

944930
// Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported
945-
applyToStringTag(GraphQLInterfaceType);
946-
947-
// Also provide toJSON and inspect aliases for toString.
948-
GraphQLInterfaceType.prototype.toJSON = GraphQLInterfaceType.prototype.inspect =
949-
GraphQLInterfaceType.prototype.toString;
931+
defineToStringTag(GraphQLInterfaceType);
932+
defineToJSON(GraphQLInterfaceType);
950933

951934
export type GraphQLInterfaceTypeConfig<TSource, TContext> = {
952935
name: string,
@@ -1019,17 +1002,11 @@ export class GraphQLUnionType {
10191002
toString(): string {
10201003
return this.name;
10211004
}
1022-
1023-
toJSON: () => string;
1024-
inspect: () => string;
10251005
}
10261006

10271007
// Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported
1028-
applyToStringTag(GraphQLUnionType);
1029-
1030-
// Also provide toJSON and inspect aliases for toString.
1031-
GraphQLUnionType.prototype.toJSON = GraphQLUnionType.prototype.inspect =
1032-
GraphQLUnionType.prototype.toString;
1008+
defineToStringTag(GraphQLUnionType);
1009+
defineToJSON(GraphQLUnionType);
10331010

10341011
function defineTypes(
10351012
unionType: GraphQLUnionType,
@@ -1138,17 +1115,11 @@ export class GraphQLEnumType /* <T> */ {
11381115
toString(): string {
11391116
return this.name;
11401117
}
1141-
1142-
toJSON: () => string;
1143-
inspect: () => string;
11441118
}
11451119

11461120
// Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported
1147-
applyToStringTag(GraphQLEnumType);
1148-
1149-
// Also provide toJSON and inspect aliases for toString.
1150-
GraphQLEnumType.prototype.toJSON = GraphQLEnumType.prototype.inspect =
1151-
GraphQLEnumType.prototype.toString;
1121+
defineToStringTag(GraphQLEnumType);
1122+
defineToJSON(GraphQLEnumType);
11521123

11531124
function defineEnumValues(
11541125
type: GraphQLEnumType,
@@ -1275,19 +1246,11 @@ export class GraphQLInputObjectType {
12751246
toString(): string {
12761247
return this.name;
12771248
}
1278-
1279-
toJSON: () => string;
1280-
inspect: () => string;
12811249
}
12821250

12831251
// Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported
1284-
applyToStringTag(GraphQLInputObjectType);
1285-
1286-
// Also provide toJSON and inspect aliases for toString.
1287-
GraphQLInputObjectType.prototype.toJSON =
1288-
GraphQLInputObjectType.prototype.toString;
1289-
GraphQLInputObjectType.prototype.inspect =
1290-
GraphQLInputObjectType.prototype.toString;
1252+
defineToStringTag(GraphQLInputObjectType);
1253+
defineToJSON(GraphQLInputObjectType);
12911254

12921255
export type GraphQLInputObjectTypeConfig = {
12931256
name: string,

src/type/directives.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import type {
1313
} from './definition';
1414
import { GraphQLNonNull } from './definition';
1515
import { GraphQLString, GraphQLBoolean } from './scalars';
16-
import applyToStringTag from '../jsutils/applyToStringTag';
16+
import defineToStringTag from '../jsutils/defineToStringTag';
17+
import defineToJSON from '../jsutils/defineToJSON';
1718
import instanceOf from '../jsutils/instanceOf';
1819
import invariant from '../jsutils/invariant';
1920
import type { DirectiveDefinitionNode } from '../language/ast';
@@ -75,10 +76,15 @@ export class GraphQLDirective {
7576
});
7677
}
7778
}
79+
80+
toString(): string {
81+
return '@' + this.name;
82+
}
7883
}
7984

8085
// Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported
81-
applyToStringTag(GraphQLDirective);
86+
defineToStringTag(GraphQLDirective);
87+
defineToJSON(GraphQLDirective);
8288

8389
export type GraphQLDirectiveConfig = {
8490
name: string,

src/type/schema.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import {
3333
import type { GraphQLError } from '../error/GraphQLError';
3434
import inspect from '../jsutils/inspect';
3535
import { __Schema } from './introspection';
36-
import applyToStringTag from '../jsutils/applyToStringTag';
36+
import defineToStringTag from '../jsutils/defineToStringTag';
3737
import find from '../jsutils/find';
3838
import instanceOf from '../jsutils/instanceOf';
3939
import invariant from '../jsutils/invariant';
@@ -233,7 +233,7 @@ export class GraphQLSchema {
233233
}
234234

235235
// Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported
236-
applyToStringTag(GraphQLSchema);
236+
defineToStringTag(GraphQLSchema);
237237

238238
type TypeMap = ObjMap<GraphQLNamedType>;
239239

0 commit comments

Comments
 (0)