Skip to content

Commit c933c9e

Browse files
committed
refactor(client): move compatibility check to custom reviver
Also, update sample nestjs app to include custom JSON.stringify replacer
1 parent 1b2a3b7 commit c933c9e

File tree

3 files changed

+22
-29
lines changed

3 files changed

+22
-29
lines changed

apps/nest-server/src/app/app.service.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,14 @@ export class AppService {
4848
const results = await client.query(
4949
`select returnflag, linestatus, sum(quantity) as sum_qty, sum(extendedprice) as sum_base_price, sum(extendedprice * (1 - discount)) as sum_disc_price, sum(extendedprice * (1 - discount) * (1 + tax)) as sum_charge, avg(quantity) as avg_qty, avg(extendedprice) as avg_price, avg(discount) as avg_disc, count(*) as count_order from lineitem where shipdate <= date '1998-12-01' group by returnflag, linestatus order by returnflag, linestatus`,
5050
)
51-
return { columns: results.columns, rows: results.data }
51+
return {
52+
columns: results.columns,
53+
rows: JSON.stringify(results.data, (key, value) => {
54+
if (typeof value !== 'bigint') return value
55+
56+
return value.toString()
57+
}),
58+
}
5259
} catch (error) {
5360
return (error as PrestoError).message
5461
}

presto-client/src/client.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
QueryInfo,
99
Table,
1010
} from './types'
11-
import { parseWithBigInts, isJsonParseContextAvailable } from './utils'
11+
import { parseWithBigInts } from './utils'
1212

1313
export class PrestoClient {
1414
private baseUrl: string
@@ -338,13 +338,9 @@ export class PrestoClient {
338338

339339
private async prestoConversionToJSON({ response }: { response: Response }): Promise<unknown> {
340340
const text = await response.text()
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-
}
341+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
342+
// @ts-ignore JSON.parse with a 3 argument reviver is a stage 3 proposal with some support, allow it here.
343+
return JSON.parse(text, parseWithBigInts)
348344
}
349345
}
350346

presto-client/src/utils.ts

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
/**
22
* Parses a JSON including bigger numbers into BigInts
3+
* This function checks if JSON.parse reviver callback has a context parameter
4+
* and falls back onto the default parsing if not.
5+
* See also:
6+
* - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#browser_compatibility
7+
* - https://github.com/tc39/proposal-json-parse-with-source
38
* @param _ Key
49
* @param value Parsed value
510
* @param context Context with source text
611
* @returns Parsed object with BigInts where required
712
*/
8-
export function parseWithBigInts(_: string, value: unknown, { source }: { source: string }) {
13+
export function parseWithBigInts(_: string, value: unknown, context: { source: string }) {
14+
if (!context) return value // Context is not available, fallback to default parse
15+
const { source } = context
16+
if (!source) return value // Source is not available, fallback to default parse
17+
918
// Ignore non-numbers
1019
if (typeof value !== 'number') return value
1120

@@ -18,22 +27,3 @@ export function parseWithBigInts(_: string, value: unknown, { source }: { source
1827

1928
return BigInt(source)
2029
}
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)