Skip to content

Commit 1b2a3b7

Browse files
committed
fix(client): check compatibility with check function
1 parent 797f9af commit 1b2a3b7

File tree

2 files changed

+47
-17
lines changed

2 files changed

+47
-17
lines changed

presto-client/src/client.ts

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,7 @@ import {
88
QueryInfo,
99
Table,
1010
} from './types'
11-
12-
function digitsToBigInt(_: string, value: unknown, { source }: { source: string }) {
13-
// Ignore non-numbers
14-
if (typeof value !== 'number') return value
15-
16-
// If not an integer, use the value
17-
// TODO: Check if Presto can return floats that could also lose precision
18-
if (!Number.isInteger(value)) return value
19-
20-
// If number is a safe integer, we can use it
21-
if (Number.isSafeInteger(value)) return value
22-
23-
return BigInt(source)
24-
}
11+
import { parseWithBigInts, isJsonParseContextAvailable } from './utils'
2512

2613
export class PrestoClient {
2714
private baseUrl: string
@@ -351,9 +338,13 @@ export class PrestoClient {
351338

352339
private async prestoConversionToJSON({ response }: { response: Response }): Promise<unknown> {
353340
const text = await response.text()
354-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
355-
// @ts-ignore JSON.parse with a 3 argument reviver is a stage 3 proposal with some support, allow it here.
356-
return JSON.parse(text, digitsToBigInt)
341+
if (isJsonParseContextAvailable()) {
342+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
343+
// @ts-ignore JSON.parse with a 3 argument reviver is a stage 3 proposal with some support, allow it here.
344+
return JSON.parse(text, parseWithBigInts)
345+
} else {
346+
return JSON.parse(text)
347+
}
357348
}
358349
}
359350

presto-client/src/utils.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Parses a JSON including bigger numbers into BigInts
3+
* @param _ Key
4+
* @param value Parsed value
5+
* @param context Context with source text
6+
* @returns Parsed object with BigInts where required
7+
*/
8+
export function parseWithBigInts(_: string, value: unknown, { source }: { source: string }) {
9+
// Ignore non-numbers
10+
if (typeof value !== 'number') return value
11+
12+
// If not an integer, use the value
13+
// TODO: Check if Presto can return floats that could also lose precision
14+
if (!Number.isInteger(value)) return value
15+
16+
// If number is a safe integer, we can use it
17+
if (Number.isSafeInteger(value)) return value
18+
19+
return BigInt(source)
20+
}
21+
22+
/**
23+
* Checks if JSON.parse reviver callback has a context parameter
24+
* See also:
25+
* - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#browser_compatibility
26+
* - https://github.com/tc39/proposal-json-parse-with-source
27+
*
28+
* This implementation is based on suggestion here:
29+
* - https://github.com/tc39/proposal-json-parse-with-source/issues/40
30+
*/
31+
export function isJsonParseContextAvailable() {
32+
let contextAvailable
33+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
34+
// @ts-ignore
35+
JSON.parse('"x"', function (key, value, x) {
36+
contextAvailable = typeof x !== 'undefined'
37+
})
38+
return contextAvailable
39+
}

0 commit comments

Comments
 (0)