@tanstack/start-client-core 1.126.2 → 1.127.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/createMiddleware.cjs.map +1 -1
- package/dist/cjs/createMiddleware.d.cts +2 -1
- package/dist/cjs/createServerFn.cjs +5 -4
- package/dist/cjs/createServerFn.cjs.map +1 -1
- package/dist/cjs/createServerFn.d.cts +2 -1
- package/dist/cjs/index.cjs +2 -4
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +5 -3
- package/dist/cjs/serializer.cjs +152 -0
- package/dist/cjs/serializer.cjs.map +1 -0
- package/dist/cjs/serializer.d.cts +23 -0
- package/dist/cjs/tests/serializer.test.d.cts +1 -0
- package/dist/esm/createMiddleware.d.ts +2 -1
- package/dist/esm/createMiddleware.js.map +1 -1
- package/dist/esm/createServerFn.d.ts +2 -1
- package/dist/esm/createServerFn.js +6 -5
- package/dist/esm/createServerFn.js.map +1 -1
- package/dist/esm/index.d.ts +5 -3
- package/dist/esm/index.js +3 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/serializer.d.ts +23 -0
- package/dist/esm/serializer.js +152 -0
- package/dist/esm/serializer.js.map +1 -0
- package/dist/esm/tests/serializer.test.d.ts +1 -0
- package/package.json +2 -2
- package/src/createMiddleware.ts +1 -1
- package/src/createServerFn.ts +11 -8
- package/src/index.tsx +13 -15
- package/src/serializer.ts +206 -0
- package/src/tests/serializer.test.tsx +151 -0
package/src/createServerFn.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { default as invariant } from 'tiny-invariant'
|
|
2
2
|
import { default as warning } from 'tiny-warning'
|
|
3
3
|
import { isNotFound, isRedirect } from '@tanstack/router-core'
|
|
4
|
-
import { mergeHeaders
|
|
4
|
+
import { mergeHeaders } from '@tanstack/router-core/ssr/client'
|
|
5
5
|
import { globalMiddleware } from './registerGlobalMiddleware'
|
|
6
6
|
|
|
7
|
+
import { startSerializer } from './serializer'
|
|
8
|
+
import type {
|
|
9
|
+
SerializerParse,
|
|
10
|
+
SerializerStringify,
|
|
11
|
+
SerializerStringifyBy,
|
|
12
|
+
} from './serializer'
|
|
7
13
|
import type {
|
|
8
14
|
AnyValidator,
|
|
9
15
|
Constrain,
|
|
10
16
|
Expand,
|
|
11
17
|
ResolveValidatorInput,
|
|
12
|
-
SerializerParse,
|
|
13
|
-
SerializerStringify,
|
|
14
|
-
SerializerStringifyBy,
|
|
15
18
|
Validator,
|
|
16
19
|
} from '@tanstack/router-core'
|
|
17
20
|
import type { JsonResponse } from '@tanstack/router-core/ssr/client'
|
|
@@ -737,7 +740,7 @@ setServerFnStaticCache(() => {
|
|
|
737
740
|
const [cachedResult, readError] = await fs
|
|
738
741
|
.readFile(filePath, 'utf-8')
|
|
739
742
|
.then((c) => [
|
|
740
|
-
|
|
743
|
+
startSerializer.parse(c) as {
|
|
741
744
|
ctx: unknown
|
|
742
745
|
error: any
|
|
743
746
|
},
|
|
@@ -767,7 +770,7 @@ setServerFnStaticCache(() => {
|
|
|
767
770
|
await fs.mkdir(path.dirname(filePath), { recursive: true })
|
|
768
771
|
|
|
769
772
|
// Store the result with fs
|
|
770
|
-
await fs.writeFile(filePath,
|
|
773
|
+
await fs.writeFile(filePath, startSerializer.stringify(response))
|
|
771
774
|
},
|
|
772
775
|
fetchItem: async (ctx) => {
|
|
773
776
|
const hash = jsonToFilenameSafeString(ctx.data)
|
|
@@ -780,7 +783,7 @@ setServerFnStaticCache(() => {
|
|
|
780
783
|
method: 'GET',
|
|
781
784
|
})
|
|
782
785
|
.then((r) => r.text())
|
|
783
|
-
.then((d) =>
|
|
786
|
+
.then((d) => startSerializer.parse(d))
|
|
784
787
|
|
|
785
788
|
staticClientCache?.set(url, result)
|
|
786
789
|
}
|
|
@@ -802,7 +805,7 @@ export function extractFormDataContext(formData: FormData) {
|
|
|
802
805
|
}
|
|
803
806
|
|
|
804
807
|
try {
|
|
805
|
-
const context =
|
|
808
|
+
const context = startSerializer.parse(serializedContext)
|
|
806
809
|
return {
|
|
807
810
|
context,
|
|
808
811
|
data: formData,
|
package/src/index.tsx
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
export type {
|
|
2
2
|
DehydratedRouter,
|
|
3
|
-
ClientExtractedBaseEntry,
|
|
4
|
-
TsrSsrGlobal as StartSsrGlobal,
|
|
5
|
-
ClientExtractedEntry,
|
|
6
3
|
JsonResponse,
|
|
7
|
-
SsrMatch,
|
|
8
|
-
ClientExtractedPromise,
|
|
9
|
-
ClientExtractedStream,
|
|
10
|
-
ResolvePromiseState,
|
|
11
4
|
} from '@tanstack/router-core/ssr/client'
|
|
12
5
|
|
|
13
|
-
export {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
6
|
+
export { hydrate, json, mergeHeaders } from '@tanstack/router-core/ssr/client'
|
|
7
|
+
|
|
8
|
+
export { startSerializer } from './serializer'
|
|
9
|
+
|
|
10
|
+
export type {
|
|
11
|
+
StartSerializer,
|
|
12
|
+
Serializable,
|
|
13
|
+
SerializerParse,
|
|
14
|
+
SerializerParseBy,
|
|
15
|
+
SerializerStringify,
|
|
16
|
+
SerializerStringifyBy,
|
|
17
|
+
SerializerExtensions,
|
|
18
|
+
} from './serializer'
|
|
19
19
|
|
|
20
20
|
export {
|
|
21
21
|
createIsomorphicFn,
|
|
@@ -60,8 +60,6 @@ export {
|
|
|
60
60
|
globalMiddleware,
|
|
61
61
|
} from './registerGlobalMiddleware'
|
|
62
62
|
export type {
|
|
63
|
-
ServerFn as FetchFn,
|
|
64
|
-
ServerFnCtx as FetchFnCtx,
|
|
65
63
|
CompiledFetcherFnOptions,
|
|
66
64
|
CompiledFetcherFn,
|
|
67
65
|
Fetcher,
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { isPlainObject } from '@tanstack/router-core'
|
|
2
|
+
|
|
3
|
+
export interface StartSerializer {
|
|
4
|
+
stringify: (obj: unknown) => string
|
|
5
|
+
parse: (str: string) => unknown
|
|
6
|
+
encode: <T>(value: T) => T
|
|
7
|
+
decode: <T>(value: T) => T
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type SerializerStringifyBy<T, TSerializable> = T extends TSerializable
|
|
11
|
+
? T
|
|
12
|
+
: T extends (...args: Array<any>) => any
|
|
13
|
+
? 'Function is not serializable'
|
|
14
|
+
: { [K in keyof T]: SerializerStringifyBy<T[K], TSerializable> }
|
|
15
|
+
|
|
16
|
+
export type SerializerParseBy<T, TSerializable> = T extends TSerializable
|
|
17
|
+
? T
|
|
18
|
+
: unknown extends SerializerExtensions['ReadableStream']
|
|
19
|
+
? { [K in keyof T]: SerializerParseBy<T[K], TSerializable> }
|
|
20
|
+
: T extends SerializerExtensions['ReadableStream']
|
|
21
|
+
? ReadableStream
|
|
22
|
+
: { [K in keyof T]: SerializerParseBy<T[K], TSerializable> }
|
|
23
|
+
|
|
24
|
+
export interface DefaultSerializerExtensions {
|
|
25
|
+
ReadableStream: unknown
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface SerializerExtensions extends DefaultSerializerExtensions {}
|
|
29
|
+
|
|
30
|
+
export type Serializable = Date | undefined | Error | FormData | bigint
|
|
31
|
+
|
|
32
|
+
export type SerializerStringify<T> = SerializerStringifyBy<T, Serializable>
|
|
33
|
+
|
|
34
|
+
export type SerializerParse<T> = SerializerParseBy<T, Serializable>
|
|
35
|
+
export const startSerializer: StartSerializer = {
|
|
36
|
+
stringify: (value: any) =>
|
|
37
|
+
JSON.stringify(value, function replacer(key, val) {
|
|
38
|
+
const ogVal = this[key]
|
|
39
|
+
const serializer = serializers.find((t) => t.stringifyCondition(ogVal))
|
|
40
|
+
|
|
41
|
+
if (serializer) {
|
|
42
|
+
return serializer.stringify(ogVal)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return val
|
|
46
|
+
}),
|
|
47
|
+
parse: (value: string) =>
|
|
48
|
+
JSON.parse(value, function parser(key, val) {
|
|
49
|
+
const ogVal = this[key]
|
|
50
|
+
if (isPlainObject(ogVal)) {
|
|
51
|
+
const serializer = serializers.find((t) => t.parseCondition(ogVal))
|
|
52
|
+
|
|
53
|
+
if (serializer) {
|
|
54
|
+
return serializer.parse(ogVal)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return val
|
|
59
|
+
}),
|
|
60
|
+
encode: (value: any) => {
|
|
61
|
+
// When encoding, dive first
|
|
62
|
+
if (Array.isArray(value)) {
|
|
63
|
+
return value.map((v) => startSerializer.encode(v))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (isPlainObject(value)) {
|
|
67
|
+
return Object.fromEntries(
|
|
68
|
+
Object.entries(value).map(([key, v]) => [
|
|
69
|
+
key,
|
|
70
|
+
startSerializer.encode(v),
|
|
71
|
+
]),
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const serializer = serializers.find((t) => t.stringifyCondition(value))
|
|
76
|
+
if (serializer) {
|
|
77
|
+
return serializer.stringify(value)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return value
|
|
81
|
+
},
|
|
82
|
+
decode: (value: any) => {
|
|
83
|
+
// Attempt transform first
|
|
84
|
+
if (isPlainObject(value)) {
|
|
85
|
+
const serializer = serializers.find((t) => t.parseCondition(value))
|
|
86
|
+
if (serializer) {
|
|
87
|
+
return serializer.parse(value)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (Array.isArray(value)) {
|
|
92
|
+
return value.map((v) => startSerializer.decode(v))
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (isPlainObject(value)) {
|
|
96
|
+
return Object.fromEntries(
|
|
97
|
+
Object.entries(value).map(([key, v]) => [
|
|
98
|
+
key,
|
|
99
|
+
startSerializer.decode(v),
|
|
100
|
+
]),
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return value
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
const createSerializer = <TKey extends string, TInput, TSerialized>(
|
|
108
|
+
key: TKey,
|
|
109
|
+
check: (value: any) => value is TInput,
|
|
110
|
+
toValue: (value: TInput) => TSerialized,
|
|
111
|
+
fromValue: (value: TSerialized) => TInput,
|
|
112
|
+
) => ({
|
|
113
|
+
key,
|
|
114
|
+
stringifyCondition: check,
|
|
115
|
+
stringify: (value: any) => ({ [`$${key}`]: toValue(value) }),
|
|
116
|
+
parseCondition: (value: any) => Object.hasOwn(value, `$${key}`),
|
|
117
|
+
parse: (value: any) => fromValue(value[`$${key}`]),
|
|
118
|
+
})
|
|
119
|
+
// Keep these ordered by predicted frequency
|
|
120
|
+
// Make sure to keep DefaultSerializable in sync with these serializers
|
|
121
|
+
// Also, make sure that they are unit tested in serializer.test.tsx
|
|
122
|
+
const serializers = [
|
|
123
|
+
createSerializer(
|
|
124
|
+
// Key
|
|
125
|
+
'undefined',
|
|
126
|
+
// Check
|
|
127
|
+
(v): v is undefined => v === undefined,
|
|
128
|
+
// To
|
|
129
|
+
() => 0,
|
|
130
|
+
// From
|
|
131
|
+
() => undefined,
|
|
132
|
+
),
|
|
133
|
+
createSerializer(
|
|
134
|
+
// Key
|
|
135
|
+
'date',
|
|
136
|
+
// Check
|
|
137
|
+
(v): v is Date => v instanceof Date,
|
|
138
|
+
// To
|
|
139
|
+
(v) => v.toISOString(),
|
|
140
|
+
// From
|
|
141
|
+
(v) => new Date(v),
|
|
142
|
+
),
|
|
143
|
+
createSerializer(
|
|
144
|
+
// Key
|
|
145
|
+
'error',
|
|
146
|
+
// Check
|
|
147
|
+
(v): v is Error => v instanceof Error,
|
|
148
|
+
// To
|
|
149
|
+
(v) => ({
|
|
150
|
+
...v,
|
|
151
|
+
message: v.message,
|
|
152
|
+
stack: process.env.NODE_ENV === 'development' ? v.stack : undefined,
|
|
153
|
+
cause: v.cause,
|
|
154
|
+
}),
|
|
155
|
+
// From
|
|
156
|
+
(v) => Object.assign(new Error(v.message), v),
|
|
157
|
+
),
|
|
158
|
+
createSerializer(
|
|
159
|
+
// Key
|
|
160
|
+
'formData',
|
|
161
|
+
// Check
|
|
162
|
+
(v): v is FormData => v instanceof FormData,
|
|
163
|
+
// To
|
|
164
|
+
(v) => {
|
|
165
|
+
const entries: Record<
|
|
166
|
+
string,
|
|
167
|
+
Array<FormDataEntryValue> | FormDataEntryValue
|
|
168
|
+
> = {}
|
|
169
|
+
v.forEach((value, key) => {
|
|
170
|
+
const entry = entries[key]
|
|
171
|
+
if (entry !== undefined) {
|
|
172
|
+
if (Array.isArray(entry)) {
|
|
173
|
+
entry.push(value)
|
|
174
|
+
} else {
|
|
175
|
+
entries[key] = [entry, value]
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
entries[key] = value
|
|
179
|
+
}
|
|
180
|
+
})
|
|
181
|
+
return entries
|
|
182
|
+
},
|
|
183
|
+
// From
|
|
184
|
+
(v) => {
|
|
185
|
+
const formData = new FormData()
|
|
186
|
+
Object.entries(v).forEach(([key, value]) => {
|
|
187
|
+
if (Array.isArray(value)) {
|
|
188
|
+
value.forEach((val) => formData.append(key, val))
|
|
189
|
+
} else {
|
|
190
|
+
formData.append(key, value)
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
return formData
|
|
194
|
+
},
|
|
195
|
+
),
|
|
196
|
+
createSerializer(
|
|
197
|
+
// Key
|
|
198
|
+
'bigint',
|
|
199
|
+
// Check
|
|
200
|
+
(v): v is bigint => typeof v === 'bigint',
|
|
201
|
+
// To
|
|
202
|
+
(v) => v.toString(),
|
|
203
|
+
// From
|
|
204
|
+
(v) => BigInt(v),
|
|
205
|
+
),
|
|
206
|
+
] as const
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { startSerializer as serializer } from '../serializer'
|
|
3
|
+
|
|
4
|
+
describe('transformer.stringify', () => {
|
|
5
|
+
it('should stringify dates', () => {
|
|
6
|
+
const date = new Date('2021-08-19T20:00:00.000Z')
|
|
7
|
+
expect(serializer.stringify(date)).toMatchInlineSnapshot(`
|
|
8
|
+
"{"$date":"2021-08-19T20:00:00.000Z"}"
|
|
9
|
+
`)
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it('should stringify undefined', () => {
|
|
13
|
+
expect(serializer.stringify(undefined)).toMatchInlineSnapshot(
|
|
14
|
+
`"{"$undefined":0}"`,
|
|
15
|
+
)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('should stringify object foo="bar"', () => {
|
|
19
|
+
expect(serializer.stringify({ foo: 'bar' })).toMatchInlineSnapshot(`
|
|
20
|
+
"{"foo":"bar"}"
|
|
21
|
+
`)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('should stringify object foo=undefined', () => {
|
|
25
|
+
expect(serializer.stringify({ foo: undefined })).toMatchInlineSnapshot(
|
|
26
|
+
`"{"foo":{"$undefined":0}}"`,
|
|
27
|
+
)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('should stringify object foo=Date', () => {
|
|
31
|
+
const date = new Date('2021-08-19T20:00:00.000Z')
|
|
32
|
+
expect(serializer.stringify({ foo: date })).toMatchInlineSnapshot(`
|
|
33
|
+
"{"foo":{"$date":"2021-08-19T20:00:00.000Z"}}"
|
|
34
|
+
`)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('should stringify empty FormData', () => {
|
|
38
|
+
const formData = new FormData()
|
|
39
|
+
expect(serializer.stringify(formData)).toMatchInlineSnapshot(
|
|
40
|
+
`"{"$formData":{}}"`,
|
|
41
|
+
)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('should stringify FormData with key-value pairs of foo="bar",name="Sean"', () => {
|
|
45
|
+
const formData = new FormData()
|
|
46
|
+
formData.append('foo', 'bar')
|
|
47
|
+
formData.append('name', 'Sean')
|
|
48
|
+
expect(serializer.stringify(formData)).toMatchInlineSnapshot(
|
|
49
|
+
`"{"$formData":{"foo":"bar","name":"Sean"}}"`,
|
|
50
|
+
)
|
|
51
|
+
})
|
|
52
|
+
it('should stringify FormData with multiple values for the same key', () => {
|
|
53
|
+
const formData = new FormData()
|
|
54
|
+
formData.append('foo', 'bar')
|
|
55
|
+
formData.append('foo', 'baz')
|
|
56
|
+
expect(serializer.stringify(formData)).toMatchInlineSnapshot(
|
|
57
|
+
`"{"$formData":{"foo":["bar","baz"]}}"`,
|
|
58
|
+
)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('should stringify bigint', () => {
|
|
62
|
+
const bigint = BigInt('9007199254740992')
|
|
63
|
+
expect(serializer.stringify(bigint)).toMatchInlineSnapshot(
|
|
64
|
+
`"{"$bigint":"9007199254740992"}"`,
|
|
65
|
+
)
|
|
66
|
+
})
|
|
67
|
+
it('should stringify object foo=bigint', () => {
|
|
68
|
+
const bigint = BigInt('9007199254740992')
|
|
69
|
+
expect(serializer.stringify({ foo: bigint })).toMatchInlineSnapshot(
|
|
70
|
+
`"{"foo":{"$bigint":"9007199254740992"}}"`,
|
|
71
|
+
)
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
describe('transformer.parse', () => {
|
|
76
|
+
it('should parse dates', () => {
|
|
77
|
+
const date = new Date('2021-08-19T20:00:00.000Z')
|
|
78
|
+
const str = serializer.stringify(date)
|
|
79
|
+
expect(serializer.parse(str)).toEqual(date)
|
|
80
|
+
expect(serializer.parse(str) instanceof Date).toBe(true)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('should parse undefined', () => {
|
|
84
|
+
const str = serializer.stringify(undefined)
|
|
85
|
+
expect(serializer.parse(str)).toBeUndefined()
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('should parse object foo="bar"', () => {
|
|
89
|
+
const obj = { foo: 'bar' }
|
|
90
|
+
const str = serializer.stringify(obj)
|
|
91
|
+
expect(serializer.parse(str)).toEqual(obj)
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('should parse object foo=undefined', () => {
|
|
95
|
+
const obj = { foo: undefined }
|
|
96
|
+
const str = serializer.stringify(obj)
|
|
97
|
+
expect(serializer.parse(str)).toEqual(obj)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('should parse object foo=Date', () => {
|
|
101
|
+
const date = new Date('2021-08-19T20:00:00.000Z')
|
|
102
|
+
const obj = { foo: date }
|
|
103
|
+
const str = serializer.stringify(obj)
|
|
104
|
+
expect(serializer.parse(str)).toEqual(obj)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('should parse empty FormData', () => {
|
|
108
|
+
const formData = new FormData()
|
|
109
|
+
const str = serializer.stringify(formData)
|
|
110
|
+
const parsed = serializer.parse(str) as FormData
|
|
111
|
+
expect(parsed).toBeInstanceOf(FormData)
|
|
112
|
+
expect([...parsed.entries()]).toEqual([])
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it('should parse FormData with key-value pairs of foo="bar",name="Sean"', () => {
|
|
116
|
+
const formData = new FormData()
|
|
117
|
+
formData.append('foo', 'bar')
|
|
118
|
+
formData.append('name', 'Sean')
|
|
119
|
+
const str = serializer.stringify(formData)
|
|
120
|
+
const parsed = serializer.parse(str) as FormData
|
|
121
|
+
expect(parsed).toBeInstanceOf(FormData)
|
|
122
|
+
expect([...parsed.entries()]).toEqual([
|
|
123
|
+
['foo', 'bar'],
|
|
124
|
+
['name', 'Sean'],
|
|
125
|
+
])
|
|
126
|
+
})
|
|
127
|
+
it('should parse FormData with multiple values for the same key', () => {
|
|
128
|
+
const formData = new FormData()
|
|
129
|
+
formData.append('foo', 'bar')
|
|
130
|
+
formData.append('foo', 'baz')
|
|
131
|
+
const str = serializer.stringify(formData)
|
|
132
|
+
const parsed = serializer.parse(str) as FormData
|
|
133
|
+
expect(parsed).toBeInstanceOf(FormData)
|
|
134
|
+
expect([...parsed.entries()]).toEqual([
|
|
135
|
+
['foo', 'bar'],
|
|
136
|
+
['foo', 'baz'],
|
|
137
|
+
])
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
it('should parse bigint', () => {
|
|
141
|
+
const bigint = BigInt('9007199254740992')
|
|
142
|
+
const str = serializer.stringify(bigint)
|
|
143
|
+
expect(serializer.parse(str)).toEqual(bigint)
|
|
144
|
+
})
|
|
145
|
+
it('should parse object foo=bigint', () => {
|
|
146
|
+
const bigint = BigInt('9007199254740992')
|
|
147
|
+
const obj = { foo: bigint }
|
|
148
|
+
const str = serializer.stringify(obj)
|
|
149
|
+
expect(serializer.parse(str)).toEqual(obj)
|
|
150
|
+
})
|
|
151
|
+
})
|