Skip to content

Commit

Permalink
fix(client): check compatibility with check function
Browse files Browse the repository at this point in the history
  • Loading branch information
alonsovb committed Dec 19, 2024
1 parent 797f9af commit 1b2a3b7
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 17 deletions.
25 changes: 8 additions & 17 deletions presto-client/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,7 @@ import {
QueryInfo,
Table,
} from './types'

function digitsToBigInt(_: string, value: unknown, { source }: { source: string }) {
// Ignore non-numbers
if (typeof value !== 'number') return value

// If not an integer, use the value
// TODO: Check if Presto can return floats that could also lose precision
if (!Number.isInteger(value)) return value

// If number is a safe integer, we can use it
if (Number.isSafeInteger(value)) return value

return BigInt(source)
}
import { parseWithBigInts, isJsonParseContextAvailable } from './utils'

export class PrestoClient {
private baseUrl: string
Expand Down Expand Up @@ -351,9 +338,13 @@ export class PrestoClient {

private async prestoConversionToJSON({ response }: { response: Response }): Promise<unknown> {
const text = await response.text()
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore JSON.parse with a 3 argument reviver is a stage 3 proposal with some support, allow it here.
return JSON.parse(text, digitsToBigInt)
if (isJsonParseContextAvailable()) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore JSON.parse with a 3 argument reviver is a stage 3 proposal with some support, allow it here.
return JSON.parse(text, parseWithBigInts)
} else {
return JSON.parse(text)
}
}
}

Expand Down
39 changes: 39 additions & 0 deletions presto-client/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Parses a JSON including bigger numbers into BigInts
* @param _ Key
* @param value Parsed value
* @param context Context with source text
* @returns Parsed object with BigInts where required
*/
export function parseWithBigInts(_: string, value: unknown, { source }: { source: string }) {
// Ignore non-numbers
if (typeof value !== 'number') return value

// If not an integer, use the value
// TODO: Check if Presto can return floats that could also lose precision
if (!Number.isInteger(value)) return value

// If number is a safe integer, we can use it
if (Number.isSafeInteger(value)) return value

return BigInt(source)
}

/**
* Checks if JSON.parse reviver callback has a context parameter
* See also:
* - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#browser_compatibility
* - https://github.com/tc39/proposal-json-parse-with-source
*
* This implementation is based on suggestion here:
* - https://github.com/tc39/proposal-json-parse-with-source/issues/40
*/
export function isJsonParseContextAvailable() {
let contextAvailable
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
JSON.parse('"x"', function (key, value, x) {
contextAvailable = typeof x !== 'undefined'
})
return contextAvailable
}

0 comments on commit 1b2a3b7

Please sign in to comment.