Skip to content

Commit 236ef96

Browse files
committed
Refactor to incorporate review feedback. Always require types.
1 parent 98314fc commit 236ef96

19 files changed

+697
-482
lines changed

src/index.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ export {
417417
TypeInfo,
418418
visitWithTypeInfo,
419419
// Converts a value to a const value by replacing variables.
420-
replaceASTVariables,
420+
replaceVariables,
421421
// Create a GraphQL Literal AST from a JavaScript input value.
422422
valueToLiteral,
423423
// Create a JavaScript input value from a GraphQL Literal AST.

src/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ export {
406406
TypeInfo,
407407
visitWithTypeInfo,
408408
// Converts a value to a const value by replacing variables.
409-
replaceASTVariables,
409+
replaceVariables,
410410
// Create a GraphQL Literal AST from a JavaScript input value.
411411
valueToLiteral,
412412
// Create a JavaScript input value from a GraphQL Literal AST.

src/jsutils/isSignedInt32.d.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* As per the GraphQL Spec, Integers are only treated as valid when a valid
3+
* 32-bit signed integer, providing the broadest support across platforms.
4+
*
5+
* n.b. JavaScript's integers are safe between -(2^53 - 1) and 2^53 - 1 because
6+
* they are internally represented as IEEE 754 doubles.
7+
*/
8+
export function isSignedInt32(value: unknown): value is number;

src/jsutils/isSignedInt32.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const MAX_INT32 = 2147483647;
2+
const MIN_INT32 = -2147483648;
3+
4+
/**
5+
* As per the GraphQL Spec, Integers are only treated as valid when a valid
6+
* 32-bit signed integer, providing the broadest support across platforms.
7+
*
8+
* n.b. JavaScript's integers are safe between -(2^53 - 1) and 2^53 - 1 because
9+
* they are internally represented as IEEE 754 doubles.
10+
*/
11+
export function isSignedInt32(value: mixed): boolean %checks {
12+
return (
13+
typeof value === 'number' &&
14+
Number.isInteger(value) &&
15+
value <= MAX_INT32 &&
16+
value >= MIN_INT32
17+
);
18+
}

src/type/definition.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -1383,12 +1383,14 @@ export class GraphQLEnumType /* <T> */ {
13831383
}
13841384

13851385
valueToLiteral(value: mixed): ?ConstValueNode {
1386-
if (typeof value === 'string') {
1387-
// https://spec.graphql.org/draft/#Name
1388-
if (/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(value)) {
1389-
return { kind: Kind.ENUM, value };
1390-
}
1391-
return { kind: Kind.STRING, value };
1386+
if (typeof value === 'string' && this.getValue(value)) {
1387+
return { kind: Kind.ENUM, value };
1388+
}
1389+
}
1390+
1391+
literalToValue(valueNode: ConstValueNode): mixed {
1392+
if (valueNode.kind === Kind.ENUM && this.getValue(valueNode.value)) {
1393+
return valueNode.value;
13921394
}
13931395
}
13941396

src/type/scalars.js

+61-18
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
import { inspect } from '../jsutils/inspect';
22
import { isObjectLike } from '../jsutils/isObjectLike';
3+
import { isSignedInt32 } from '../jsutils/isSignedInt32';
34

45
import type { ConstValueNode } from '../language/ast';
56
import { Kind } from '../language/kinds';
67
import { print } from '../language/printer';
78

89
import { GraphQLError } from '../error/GraphQLError';
910

11+
import { defaultScalarLiteralToValue } from '../utilities/literalToValue';
12+
import { defaultScalarValueToLiteral } from '../utilities/valueToLiteral';
13+
1014
import type { GraphQLNamedType } from './definition';
1115
import { GraphQLScalarType } from './definition';
1216

13-
// As per the GraphQL Spec, Integers are only treated as valid when a valid
14-
// 32-bit signed integer, providing the broadest support across platforms.
15-
//
16-
// n.b. JavaScript's integers are safe between -(2^53 - 1) and 2^53 - 1 because
17-
// they are internally represented as IEEE 754 doubles.
18-
const MAX_INT = 2147483647;
19-
const MIN_INT = -2147483648;
20-
2117
function serializeInt(outputValue: mixed): number {
2218
const coercedValue = serializeObject(outputValue);
2319

@@ -35,7 +31,7 @@ function serializeInt(outputValue: mixed): number {
3531
`Int cannot represent non-integer value: ${inspect(coercedValue)}`,
3632
);
3733
}
38-
if (num > MAX_INT || num < MIN_INT) {
34+
if (!isSignedInt32(num)) {
3935
throw new GraphQLError(
4036
'Int cannot represent non 32-bit signed integer value: ' +
4137
inspect(coercedValue),
@@ -50,7 +46,7 @@ function coerceInt(inputValue: mixed): number {
5046
`Int cannot represent non-integer value: ${inspect(inputValue)}`,
5147
);
5248
}
53-
if (inputValue > MAX_INT || inputValue < MIN_INT) {
49+
if (!isSignedInt32(inputValue)) {
5450
throw new GraphQLError(
5551
`Int cannot represent non 32-bit signed integer value: ${inputValue}`,
5652
);
@@ -72,14 +68,27 @@ export const GraphQLInt: GraphQLScalarType = new GraphQLScalarType({
7268
);
7369
}
7470
const num = parseInt(valueNode.value, 10);
75-
if (num > MAX_INT || num < MIN_INT) {
71+
if (!isSignedInt32(num)) {
7672
throw new GraphQLError(
7773
`Int cannot represent non 32-bit signed integer value: ${valueNode.value}`,
7874
valueNode,
7975
);
8076
}
8177
return num;
8278
},
79+
valueToLiteral(value) {
80+
if (isSignedInt32(value)) {
81+
return defaultScalarValueToLiteral(value);
82+
}
83+
},
84+
literalToValue(valueNode) {
85+
if (valueNode.kind === Kind.INT) {
86+
const value = defaultScalarLiteralToValue(valueNode);
87+
if (isSignedInt32(value)) {
88+
return value;
89+
}
90+
}
91+
},
8392
});
8493

8594
function serializeFloat(outputValue: mixed): number {
@@ -126,6 +135,17 @@ export const GraphQLFloat: GraphQLScalarType = new GraphQLScalarType({
126135
}
127136
return parseFloat(valueNode.value);
128137
},
138+
valueToLiteral(value) {
139+
const literal = defaultScalarValueToLiteral(value);
140+
if (literal.kind === Kind.FLOAT || literal.kind === Kind.INT) {
141+
return literal;
142+
}
143+
},
144+
literalToValue(valueNode) {
145+
if (valueNode.kind === Kind.FLOAT || valueNode.kind === Kind.INT) {
146+
return defaultScalarLiteralToValue(valueNode);
147+
}
148+
},
129149
});
130150

131151
// Support serializing objects with custom valueOf() or toJSON() functions -
@@ -190,6 +210,17 @@ export const GraphQLString: GraphQLScalarType = new GraphQLScalarType({
190210
}
191211
return valueNode.value;
192212
},
213+
valueToLiteral(value) {
214+
const literal = defaultScalarValueToLiteral(value);
215+
if (literal.kind === Kind.STRING) {
216+
return literal;
217+
}
218+
},
219+
literalToValue(valueNode) {
220+
if (valueNode.kind === Kind.STRING) {
221+
return defaultScalarLiteralToValue(valueNode);
222+
}
223+
},
193224
});
194225

195226
function serializeBoolean(outputValue: mixed): boolean {
@@ -229,6 +260,17 @@ export const GraphQLBoolean: GraphQLScalarType = new GraphQLScalarType({
229260
}
230261
return valueNode.value;
231262
},
263+
valueToLiteral(value) {
264+
const literal = defaultScalarValueToLiteral(value);
265+
if (literal.kind === Kind.BOOLEAN) {
266+
return literal;
267+
}
268+
},
269+
literalToValue(valueNode) {
270+
if (valueNode.kind === Kind.BOOLEAN) {
271+
return defaultScalarLiteralToValue(valueNode);
272+
}
273+
},
232274
});
233275

234276
function serializeID(outputValue: mixed): string {
@@ -270,17 +312,18 @@ export const GraphQLID: GraphQLScalarType = new GraphQLScalarType({
270312
return valueNode.value;
271313
},
272314
valueToLiteral(value: mixed): ?ConstValueNode {
273-
// ID types can use Int literals.
274-
if (typeof value === 'string') {
275-
if (/^-?(?:0|[1-9][0-9]*)$/.test(value)) {
276-
return { kind: Kind.INT, value };
277-
}
278-
return { kind: Kind.STRING, value };
315+
// ID types can use number values and Int literals.
316+
const stringValue = Number.isInteger(value) ? String(value) : value;
317+
if (typeof stringValue === 'string') {
318+
// Will parse as an IntValue.
319+
return /^-?(?:0|[1-9][0-9]*)$/.test(stringValue)
320+
? { kind: Kind.INT, value: stringValue }
321+
: { kind: Kind.STRING, value: stringValue, block: false };
279322
}
280323
},
281324
literalToValue(valueNode: ConstValueNode): mixed {
282325
// ID Int literals are represented as string values.
283-
if (valueNode.kind === Kind.INT || valueNode.kind === Kind.STRING) {
326+
if (valueNode.kind === Kind.STRING || valueNode.kind === Kind.INT) {
284327
return valueNode.value;
285328
}
286329
},

0 commit comments

Comments
 (0)