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