From ef0585a16796a27e93c82865bcc1fbd1c6e5c5b3 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Mon, 27 Mar 2023 10:40:46 +0300 Subject: [PATCH] Safer serialization for `BigInt` --- .changeset/witty-cherries-tickle.md | 6 ++++ src/scalars/BigInt.ts | 48 +++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 .changeset/witty-cherries-tickle.md diff --git a/.changeset/witty-cherries-tickle.md b/.changeset/witty-cherries-tickle.md new file mode 100644 index 000000000..fa5e06b85 --- /dev/null +++ b/.changeset/witty-cherries-tickle.md @@ -0,0 +1,6 @@ +--- +'graphql-scalars': patch +--- + +If JSON serializer is missing for `BigInt` use `number` serialization for safe integers and `string` +for unsafe integers by warning the users. diff --git a/src/scalars/BigInt.ts b/src/scalars/BigInt.ts index 1fc847634..bf4ce8f40 100644 --- a/src/scalars/BigInt.ts +++ b/src/scalars/BigInt.ts @@ -3,7 +3,33 @@ import { GraphQLScalarType, GraphQLScalarTypeConfig, print } from 'graphql'; import { createGraphQLError } from '../error.js'; import { serializeObject } from './utilities.js'; -export const GraphQLBigIntConfig: GraphQLScalarTypeConfig = /*#__PURE__*/ { +let warned = false; + +function isSafeInteger(val: bigint): boolean { + return val <= Number.MAX_SAFE_INTEGER && val >= Number.MIN_SAFE_INTEGER; +} + +function serializeSafeBigInt(val: bigint): bigint | number | string { + if ('toJSON' in BigInt.prototype) { + return val; + } + if (isSafeInteger(val)) { + return Number(val); + } + if (!warned) { + warned = true; + console.warn( + 'By default, BigInts are not serialized to JSON as numbers but instead as strings which may lead an unintegrity in your data. ' + + 'To fix this, you can use "json-bigint-patch" to enable correct serialization for BigInts.', + ); + } + return val.toString(); +} + +export const GraphQLBigIntConfig: GraphQLScalarTypeConfig< + bigint | number, + bigint | string | number +> = /*#__PURE__*/ { name: 'BigInt', description: 'The `BigInt` scalar type represents non-fractional signed whole numeric values.', serialize(outputValue) { @@ -33,22 +59,14 @@ export const GraphQLBigIntConfig: GraphQLScalarTypeConfig