@awsless/json 0.0.9 → 0.0.11
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/README.MD +42 -18
- package/dist/index.cjs +55 -14
- package/dist/index.d.cts +42 -4
- package/dist/index.d.ts +42 -4
- package/dist/index.js +42 -15
- package/package.json +5 -5
package/README.MD
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
|
|
2
1
|
# @awsless/json
|
|
3
2
|
|
|
4
3
|
The `@awsless/json` package adds support for more JavaScript native types to JSON.
|
|
5
4
|
|
|
6
5
|
Features:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
|
|
7
|
+
- Lightweight / Using the JS native JSON parser.
|
|
8
|
+
- JSON backwards compatible.
|
|
9
|
+
- No precision loss.
|
|
10
|
+
- Includes support for basic JS types.
|
|
11
|
+
- Extendable.
|
|
12
12
|
|
|
13
13
|
## The Problem
|
|
14
14
|
|
|
15
15
|
JSON doesn't have support for types like:
|
|
16
|
+
|
|
16
17
|
- `undefined`
|
|
17
18
|
- `NaN`
|
|
18
19
|
- `Infinity`
|
|
@@ -33,7 +34,7 @@ Additionally, the native `JSON.parse/stringify` functions do not address the pot
|
|
|
33
34
|
## Basic Usage
|
|
34
35
|
|
|
35
36
|
```ts
|
|
36
|
-
import { parse, stringify } from '@awsless/json'
|
|
37
|
+
import { parse, stringify } from '@awsless/json'
|
|
37
38
|
|
|
38
39
|
// The output will be {"$bigint":"1"}
|
|
39
40
|
const json = stringify(1n)
|
|
@@ -47,7 +48,7 @@ const value = parse(json)
|
|
|
47
48
|
In some situations, you may not have control over the JSON parser being used. In these instances, your JSON can still be parsed, but the output may be incorrect. We can correct the inaccurate output by using the `patch` function.
|
|
48
49
|
|
|
49
50
|
```ts
|
|
50
|
-
import { stringify, patch } from '@awsless/json'
|
|
51
|
+
import { stringify, patch } from '@awsless/json'
|
|
51
52
|
|
|
52
53
|
const json = stringify(1n)
|
|
53
54
|
|
|
@@ -63,7 +64,7 @@ const fixed = patch(broken)
|
|
|
63
64
|
We let you extend JSON to support your own custom types.
|
|
64
65
|
|
|
65
66
|
```ts
|
|
66
|
-
import { parse, stringify, Serializable } from '@awsless/json'
|
|
67
|
+
import { parse, stringify, Serializable, setGlobalTypes } from '@awsless/json'
|
|
67
68
|
|
|
68
69
|
class Custom {
|
|
69
70
|
readonly value
|
|
@@ -80,10 +81,33 @@ const $custom: Serializable<Custom, string> = {
|
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
// Stringify your custom type.
|
|
83
|
-
const json = stringify(new Custom('example'), {
|
|
84
|
+
const json = stringify(new Custom('example'), {
|
|
85
|
+
types: { $custom },
|
|
86
|
+
})
|
|
84
87
|
|
|
85
88
|
// Parse the json with your custom type.
|
|
86
|
-
const value = parse(json, {
|
|
89
|
+
const value = parse(json, {
|
|
90
|
+
types: { $custom },
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// Additionally, you can globally add your own extensions.
|
|
94
|
+
setGlobalTypes({ $custom })
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Preserve undefined object properties
|
|
98
|
+
|
|
99
|
+
The native `JSON.stringify` will strip undefined object properties to generate smaller JSON output. We do the same thing but we have a special option to opt out of this behavior if correctness is important to you.
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
const input = { key: undefined }
|
|
103
|
+
|
|
104
|
+
const smallerJson = stringify(input, {
|
|
105
|
+
preserveUndefinedValues: true,
|
|
106
|
+
}) // {}
|
|
107
|
+
|
|
108
|
+
const moreCorrectJson = stringify(input, {
|
|
109
|
+
preserveUndefinedValues: true,
|
|
110
|
+
}) // {"key":{"$undefined":0}}
|
|
87
111
|
```
|
|
88
112
|
|
|
89
113
|
## Precision Loss
|
|
@@ -91,15 +115,15 @@ const value = parse(json, { $custom })
|
|
|
91
115
|
When using the native `JSON.parse/stringify` functions you could lose precision when parsing native numbers. And you don't always have the ability to extend JSON with your own custom types. For example when you’re communicating with a third-party API. For this reason, we have 2 utility functions that will parse the native JSON number type to your own precision-safe alternative.
|
|
92
116
|
|
|
93
117
|
> [!NOTE]
|
|
94
|
-
> These utility functions will only work in environments that support `JSON.rawJSON`
|
|
95
|
-
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/rawJSON#browser_compatibility
|
|
118
|
+
> These utility functions will only work in environments that support `JSON.rawJSON` > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/rawJSON#browser_compatibility
|
|
96
119
|
|
|
97
120
|
```ts
|
|
98
|
-
import { safeNumberParse, safeNumberStringify } from '@awsless/json'
|
|
99
|
-
import { BigFloat, eq } from '@awsless/big-float'
|
|
121
|
+
import { safeNumberParse, safeNumberStringify } from '@awsless/json'
|
|
122
|
+
import { BigFloat, eq } from '@awsless/big-float'
|
|
123
|
+
|
|
124
|
+
const one = new BigFloat(1)
|
|
100
125
|
|
|
101
|
-
const
|
|
102
|
-
const json = safeNumberStringify(ONE, {
|
|
126
|
+
const json = safeNumberStringify(one, {
|
|
103
127
|
is: v => v instanceof BigFloat,
|
|
104
128
|
stringify: v => v.toString(),
|
|
105
129
|
})
|
|
@@ -110,7 +134,7 @@ const result = safeNumberParse('1', {
|
|
|
110
134
|
parse: v => new BigFloat(v),
|
|
111
135
|
})
|
|
112
136
|
|
|
113
|
-
console.log(eq(
|
|
137
|
+
console.log(eq(one, result)) // true
|
|
114
138
|
```
|
|
115
139
|
|
|
116
140
|
## Known Issue's
|
package/dist/index.cjs
CHANGED
|
@@ -20,14 +20,28 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
$bigfloat: () => $bigfloat,
|
|
24
|
+
$bigint: () => $bigint,
|
|
25
|
+
$binary: () => $binary,
|
|
26
|
+
$date: () => $date,
|
|
27
|
+
$duration: () => $duration,
|
|
28
|
+
$infinity: () => $infinity,
|
|
29
|
+
$map: () => $map,
|
|
30
|
+
$mockdate: () => $mockdate,
|
|
31
|
+
$nan: () => $nan,
|
|
32
|
+
$regexp: () => $regexp,
|
|
33
|
+
$set: () => $set,
|
|
34
|
+
$undefined: () => $undefined,
|
|
35
|
+
$url: () => $url,
|
|
23
36
|
createReplacer: () => createReplacer,
|
|
24
37
|
createReviver: () => createReviver,
|
|
25
38
|
createSafeNumberReplacer: () => createSafeNumberReplacer,
|
|
26
39
|
createSafeNumberReviver: () => createSafeNumberReviver,
|
|
27
|
-
parse: () =>
|
|
40
|
+
parse: () => parse2,
|
|
28
41
|
patch: () => patch,
|
|
29
42
|
safeNumberParse: () => safeNumberParse,
|
|
30
43
|
safeNumberStringify: () => safeNumberStringify,
|
|
44
|
+
setGlobalTypes: () => setGlobalTypes,
|
|
31
45
|
stringify: () => stringify,
|
|
32
46
|
unpatch: () => unpatch
|
|
33
47
|
});
|
|
@@ -37,7 +51,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
37
51
|
var import_big_float = require("@awsless/big-float");
|
|
38
52
|
var $bigfloat = {
|
|
39
53
|
is: (v) => v instanceof import_big_float.BigFloat,
|
|
40
|
-
parse: (v) =>
|
|
54
|
+
parse: (v) => (0, import_big_float.parse)(v),
|
|
41
55
|
stringify: (v) => v.toString()
|
|
42
56
|
};
|
|
43
57
|
|
|
@@ -145,11 +159,11 @@ var baseTypes = {
|
|
|
145
159
|
};
|
|
146
160
|
|
|
147
161
|
// src/parse.ts
|
|
148
|
-
var
|
|
162
|
+
var parse2 = (json, options) => {
|
|
149
163
|
const replacements = [];
|
|
150
164
|
const result = JSON.parse(
|
|
151
165
|
json,
|
|
152
|
-
createReviver(types, (target, key, value) => {
|
|
166
|
+
createReviver(options?.types, (target, key, value) => {
|
|
153
167
|
replacements.push([target, key, value]);
|
|
154
168
|
})
|
|
155
169
|
);
|
|
@@ -174,12 +188,10 @@ var createReviver = (types = {}, registerReplacement) => {
|
|
|
174
188
|
const stringified = original[typeName];
|
|
175
189
|
if ("parse" in type) {
|
|
176
190
|
return type.parse(stringified);
|
|
177
|
-
} else
|
|
191
|
+
} else {
|
|
178
192
|
const result = type.replace(stringified);
|
|
179
|
-
registerReplacement(this, key, result);
|
|
193
|
+
registerReplacement?.(this, key, result);
|
|
180
194
|
return result;
|
|
181
|
-
} else {
|
|
182
|
-
return type.replace(stringified);
|
|
183
195
|
}
|
|
184
196
|
}
|
|
185
197
|
}
|
|
@@ -189,16 +201,19 @@ var createReviver = (types = {}, registerReplacement) => {
|
|
|
189
201
|
};
|
|
190
202
|
|
|
191
203
|
// src/stringify.ts
|
|
192
|
-
var stringify = (value,
|
|
193
|
-
return JSON.stringify(value, createReplacer(
|
|
204
|
+
var stringify = (value, options) => {
|
|
205
|
+
return JSON.stringify(value, createReplacer(options));
|
|
194
206
|
};
|
|
195
|
-
var createReplacer = (
|
|
196
|
-
types = {
|
|
207
|
+
var createReplacer = (options) => {
|
|
208
|
+
const types = {
|
|
197
209
|
...baseTypes,
|
|
198
|
-
...types
|
|
210
|
+
...options?.types
|
|
199
211
|
};
|
|
200
212
|
return function(key, value) {
|
|
201
213
|
const original = this[key];
|
|
214
|
+
if (!options?.preserveUndefinedValues && key && typeof original === "undefined" && typeof this === "object" && !Array.isArray(this)) {
|
|
215
|
+
return value;
|
|
216
|
+
}
|
|
202
217
|
for (const [typeName, type] of Object.entries(types)) {
|
|
203
218
|
if (type.is(original)) {
|
|
204
219
|
return {
|
|
@@ -212,12 +227,17 @@ var createReplacer = (types = {}) => {
|
|
|
212
227
|
|
|
213
228
|
// src/patch.ts
|
|
214
229
|
var patch = (value, types = {}) => {
|
|
215
|
-
return
|
|
230
|
+
return parse2(JSON.stringify(value), types);
|
|
216
231
|
};
|
|
217
232
|
var unpatch = (value, types = {}) => {
|
|
218
233
|
return JSON.parse(stringify(value, types));
|
|
219
234
|
};
|
|
220
235
|
|
|
236
|
+
// src/global.ts
|
|
237
|
+
var setGlobalTypes = (types) => {
|
|
238
|
+
Object.assign(baseTypes, types);
|
|
239
|
+
};
|
|
240
|
+
|
|
221
241
|
// src/safe-number/parse.ts
|
|
222
242
|
var safeNumberParse = (json, props) => {
|
|
223
243
|
return JSON.parse(
|
|
@@ -248,8 +268,28 @@ var createSafeNumberReplacer = (props) => {
|
|
|
248
268
|
return value;
|
|
249
269
|
};
|
|
250
270
|
};
|
|
271
|
+
|
|
272
|
+
// src/type/mockdate.ts
|
|
273
|
+
var $mockdate = {
|
|
274
|
+
is: (v) => typeof v === "object" && v !== null && "toISOString" in v && typeof v.toISOString === "function" && "getTime" in v && typeof v.getTime === "function" && "toUTCString" in v && typeof v.toUTCString === "function",
|
|
275
|
+
parse: (v) => new Date(v),
|
|
276
|
+
stringify: (v) => v.toISOString()
|
|
277
|
+
};
|
|
251
278
|
// Annotate the CommonJS export names for ESM import in node:
|
|
252
279
|
0 && (module.exports = {
|
|
280
|
+
$bigfloat,
|
|
281
|
+
$bigint,
|
|
282
|
+
$binary,
|
|
283
|
+
$date,
|
|
284
|
+
$duration,
|
|
285
|
+
$infinity,
|
|
286
|
+
$map,
|
|
287
|
+
$mockdate,
|
|
288
|
+
$nan,
|
|
289
|
+
$regexp,
|
|
290
|
+
$set,
|
|
291
|
+
$undefined,
|
|
292
|
+
$url,
|
|
253
293
|
createReplacer,
|
|
254
294
|
createReviver,
|
|
255
295
|
createSafeNumberReplacer,
|
|
@@ -258,6 +298,7 @@ var createSafeNumberReplacer = (props) => {
|
|
|
258
298
|
patch,
|
|
259
299
|
safeNumberParse,
|
|
260
300
|
safeNumberStringify,
|
|
301
|
+
setGlobalTypes,
|
|
261
302
|
stringify,
|
|
262
303
|
unpatch
|
|
263
304
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { BigFloat } from '@awsless/big-float';
|
|
2
|
+
import { Duration } from '@awsless/duration';
|
|
3
|
+
|
|
1
4
|
type Serializable<I, O> = {
|
|
2
5
|
is: (value: unknown) => boolean;
|
|
3
6
|
stringify: (value: I) => O;
|
|
@@ -11,13 +14,22 @@ type SerializableTypes = Record<string, Serializable<any, any>>;
|
|
|
11
14
|
declare const patch: (value: unknown, types?: SerializableTypes) => any;
|
|
12
15
|
declare const unpatch: (value: unknown, types?: SerializableTypes) => any;
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
type Options$1 = {
|
|
18
|
+
types?: SerializableTypes;
|
|
19
|
+
};
|
|
20
|
+
declare const parse: (json: string, options?: Options$1) => any;
|
|
15
21
|
type Reviver$1 = (this: any, key: string, value: any) => any;
|
|
16
22
|
declare const createReviver: (types?: SerializableTypes, registerReplacement?: (target: any, key: string, value: unknown) => void) => Reviver$1;
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
type Options = {
|
|
25
|
+
types?: SerializableTypes;
|
|
26
|
+
preserveUndefinedValues?: boolean;
|
|
27
|
+
};
|
|
28
|
+
declare const stringify: (value: unknown, options?: Options) => string;
|
|
19
29
|
type Replacer$1 = (this: any, key: string, value: any) => any;
|
|
20
|
-
declare const createReplacer: (
|
|
30
|
+
declare const createReplacer: (options?: Options) => Replacer$1;
|
|
31
|
+
|
|
32
|
+
declare const setGlobalTypes: (types: SerializableTypes) => void;
|
|
21
33
|
|
|
22
34
|
type Props$1 = {
|
|
23
35
|
parse: (value: string) => unknown;
|
|
@@ -36,4 +48,30 @@ declare const safeNumberStringify: <T>(value: unknown, props: Props<T>) => strin
|
|
|
36
48
|
type Replacer = (this: any, key: string, value: any) => any;
|
|
37
49
|
declare const createSafeNumberReplacer: <T>(props: Props<T>) => Replacer;
|
|
38
50
|
|
|
39
|
-
|
|
51
|
+
declare const $bigfloat: Serializable<BigFloat, string>;
|
|
52
|
+
|
|
53
|
+
declare const $bigint: Serializable<bigint, string>;
|
|
54
|
+
|
|
55
|
+
declare const $binary: Serializable<Uint8Array, string>;
|
|
56
|
+
|
|
57
|
+
declare const $date: Serializable<Date, string>;
|
|
58
|
+
|
|
59
|
+
declare const $duration: Serializable<Duration, string>;
|
|
60
|
+
|
|
61
|
+
declare const $infinity: Serializable<typeof Infinity, 1 | 0>;
|
|
62
|
+
|
|
63
|
+
declare const $map: Serializable<Map<unknown, unknown>, [unknown, unknown][]>;
|
|
64
|
+
|
|
65
|
+
declare const $mockdate: Serializable<Date, string>;
|
|
66
|
+
|
|
67
|
+
declare const $nan: Serializable<typeof NaN, 0>;
|
|
68
|
+
|
|
69
|
+
declare const $regexp: Serializable<RegExp, [string, string]>;
|
|
70
|
+
|
|
71
|
+
declare const $set: Serializable<Set<unknown>, unknown[]>;
|
|
72
|
+
|
|
73
|
+
declare const $undefined: Serializable<undefined, 0>;
|
|
74
|
+
|
|
75
|
+
declare const $url: Serializable<URL, string>;
|
|
76
|
+
|
|
77
|
+
export { $bigfloat, $bigint, $binary, $date, $duration, $infinity, $map, $mockdate, $nan, $regexp, $set, $undefined, $url, type Serializable, createReplacer, createReviver, createSafeNumberReplacer, createSafeNumberReviver, parse, patch, safeNumberParse, safeNumberStringify, setGlobalTypes, stringify, unpatch };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { BigFloat } from '@awsless/big-float';
|
|
2
|
+
import { Duration } from '@awsless/duration';
|
|
3
|
+
|
|
1
4
|
type Serializable<I, O> = {
|
|
2
5
|
is: (value: unknown) => boolean;
|
|
3
6
|
stringify: (value: I) => O;
|
|
@@ -11,13 +14,22 @@ type SerializableTypes = Record<string, Serializable<any, any>>;
|
|
|
11
14
|
declare const patch: (value: unknown, types?: SerializableTypes) => any;
|
|
12
15
|
declare const unpatch: (value: unknown, types?: SerializableTypes) => any;
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
type Options$1 = {
|
|
18
|
+
types?: SerializableTypes;
|
|
19
|
+
};
|
|
20
|
+
declare const parse: (json: string, options?: Options$1) => any;
|
|
15
21
|
type Reviver$1 = (this: any, key: string, value: any) => any;
|
|
16
22
|
declare const createReviver: (types?: SerializableTypes, registerReplacement?: (target: any, key: string, value: unknown) => void) => Reviver$1;
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
type Options = {
|
|
25
|
+
types?: SerializableTypes;
|
|
26
|
+
preserveUndefinedValues?: boolean;
|
|
27
|
+
};
|
|
28
|
+
declare const stringify: (value: unknown, options?: Options) => string;
|
|
19
29
|
type Replacer$1 = (this: any, key: string, value: any) => any;
|
|
20
|
-
declare const createReplacer: (
|
|
30
|
+
declare const createReplacer: (options?: Options) => Replacer$1;
|
|
31
|
+
|
|
32
|
+
declare const setGlobalTypes: (types: SerializableTypes) => void;
|
|
21
33
|
|
|
22
34
|
type Props$1 = {
|
|
23
35
|
parse: (value: string) => unknown;
|
|
@@ -36,4 +48,30 @@ declare const safeNumberStringify: <T>(value: unknown, props: Props<T>) => strin
|
|
|
36
48
|
type Replacer = (this: any, key: string, value: any) => any;
|
|
37
49
|
declare const createSafeNumberReplacer: <T>(props: Props<T>) => Replacer;
|
|
38
50
|
|
|
39
|
-
|
|
51
|
+
declare const $bigfloat: Serializable<BigFloat, string>;
|
|
52
|
+
|
|
53
|
+
declare const $bigint: Serializable<bigint, string>;
|
|
54
|
+
|
|
55
|
+
declare const $binary: Serializable<Uint8Array, string>;
|
|
56
|
+
|
|
57
|
+
declare const $date: Serializable<Date, string>;
|
|
58
|
+
|
|
59
|
+
declare const $duration: Serializable<Duration, string>;
|
|
60
|
+
|
|
61
|
+
declare const $infinity: Serializable<typeof Infinity, 1 | 0>;
|
|
62
|
+
|
|
63
|
+
declare const $map: Serializable<Map<unknown, unknown>, [unknown, unknown][]>;
|
|
64
|
+
|
|
65
|
+
declare const $mockdate: Serializable<Date, string>;
|
|
66
|
+
|
|
67
|
+
declare const $nan: Serializable<typeof NaN, 0>;
|
|
68
|
+
|
|
69
|
+
declare const $regexp: Serializable<RegExp, [string, string]>;
|
|
70
|
+
|
|
71
|
+
declare const $set: Serializable<Set<unknown>, unknown[]>;
|
|
72
|
+
|
|
73
|
+
declare const $undefined: Serializable<undefined, 0>;
|
|
74
|
+
|
|
75
|
+
declare const $url: Serializable<URL, string>;
|
|
76
|
+
|
|
77
|
+
export { $bigfloat, $bigint, $binary, $date, $duration, $infinity, $map, $mockdate, $nan, $regexp, $set, $undefined, $url, type Serializable, createReplacer, createReviver, createSafeNumberReplacer, createSafeNumberReviver, parse, patch, safeNumberParse, safeNumberStringify, setGlobalTypes, stringify, unpatch };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/type/bigfloat.ts
|
|
2
|
-
import { BigFloat } from "@awsless/big-float";
|
|
2
|
+
import { BigFloat, parse } from "@awsless/big-float";
|
|
3
3
|
var $bigfloat = {
|
|
4
4
|
is: (v) => v instanceof BigFloat,
|
|
5
|
-
parse: (v) =>
|
|
5
|
+
parse: (v) => parse(v),
|
|
6
6
|
stringify: (v) => v.toString()
|
|
7
7
|
};
|
|
8
8
|
|
|
@@ -110,11 +110,11 @@ var baseTypes = {
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
// src/parse.ts
|
|
113
|
-
var
|
|
113
|
+
var parse2 = (json, options) => {
|
|
114
114
|
const replacements = [];
|
|
115
115
|
const result = JSON.parse(
|
|
116
116
|
json,
|
|
117
|
-
createReviver(types, (target, key, value) => {
|
|
117
|
+
createReviver(options?.types, (target, key, value) => {
|
|
118
118
|
replacements.push([target, key, value]);
|
|
119
119
|
})
|
|
120
120
|
);
|
|
@@ -139,12 +139,10 @@ var createReviver = (types = {}, registerReplacement) => {
|
|
|
139
139
|
const stringified = original[typeName];
|
|
140
140
|
if ("parse" in type) {
|
|
141
141
|
return type.parse(stringified);
|
|
142
|
-
} else
|
|
142
|
+
} else {
|
|
143
143
|
const result = type.replace(stringified);
|
|
144
|
-
registerReplacement(this, key, result);
|
|
144
|
+
registerReplacement?.(this, key, result);
|
|
145
145
|
return result;
|
|
146
|
-
} else {
|
|
147
|
-
return type.replace(stringified);
|
|
148
146
|
}
|
|
149
147
|
}
|
|
150
148
|
}
|
|
@@ -154,16 +152,19 @@ var createReviver = (types = {}, registerReplacement) => {
|
|
|
154
152
|
};
|
|
155
153
|
|
|
156
154
|
// src/stringify.ts
|
|
157
|
-
var stringify = (value,
|
|
158
|
-
return JSON.stringify(value, createReplacer(
|
|
155
|
+
var stringify = (value, options) => {
|
|
156
|
+
return JSON.stringify(value, createReplacer(options));
|
|
159
157
|
};
|
|
160
|
-
var createReplacer = (
|
|
161
|
-
types = {
|
|
158
|
+
var createReplacer = (options) => {
|
|
159
|
+
const types = {
|
|
162
160
|
...baseTypes,
|
|
163
|
-
...types
|
|
161
|
+
...options?.types
|
|
164
162
|
};
|
|
165
163
|
return function(key, value) {
|
|
166
164
|
const original = this[key];
|
|
165
|
+
if (!options?.preserveUndefinedValues && key && typeof original === "undefined" && typeof this === "object" && !Array.isArray(this)) {
|
|
166
|
+
return value;
|
|
167
|
+
}
|
|
167
168
|
for (const [typeName, type] of Object.entries(types)) {
|
|
168
169
|
if (type.is(original)) {
|
|
169
170
|
return {
|
|
@@ -177,12 +178,17 @@ var createReplacer = (types = {}) => {
|
|
|
177
178
|
|
|
178
179
|
// src/patch.ts
|
|
179
180
|
var patch = (value, types = {}) => {
|
|
180
|
-
return
|
|
181
|
+
return parse2(JSON.stringify(value), types);
|
|
181
182
|
};
|
|
182
183
|
var unpatch = (value, types = {}) => {
|
|
183
184
|
return JSON.parse(stringify(value, types));
|
|
184
185
|
};
|
|
185
186
|
|
|
187
|
+
// src/global.ts
|
|
188
|
+
var setGlobalTypes = (types) => {
|
|
189
|
+
Object.assign(baseTypes, types);
|
|
190
|
+
};
|
|
191
|
+
|
|
186
192
|
// src/safe-number/parse.ts
|
|
187
193
|
var safeNumberParse = (json, props) => {
|
|
188
194
|
return JSON.parse(
|
|
@@ -213,15 +219,36 @@ var createSafeNumberReplacer = (props) => {
|
|
|
213
219
|
return value;
|
|
214
220
|
};
|
|
215
221
|
};
|
|
222
|
+
|
|
223
|
+
// src/type/mockdate.ts
|
|
224
|
+
var $mockdate = {
|
|
225
|
+
is: (v) => typeof v === "object" && v !== null && "toISOString" in v && typeof v.toISOString === "function" && "getTime" in v && typeof v.getTime === "function" && "toUTCString" in v && typeof v.toUTCString === "function",
|
|
226
|
+
parse: (v) => new Date(v),
|
|
227
|
+
stringify: (v) => v.toISOString()
|
|
228
|
+
};
|
|
216
229
|
export {
|
|
230
|
+
$bigfloat,
|
|
231
|
+
$bigint,
|
|
232
|
+
$binary,
|
|
233
|
+
$date,
|
|
234
|
+
$duration,
|
|
235
|
+
$infinity,
|
|
236
|
+
$map,
|
|
237
|
+
$mockdate,
|
|
238
|
+
$nan,
|
|
239
|
+
$regexp,
|
|
240
|
+
$set,
|
|
241
|
+
$undefined,
|
|
242
|
+
$url,
|
|
217
243
|
createReplacer,
|
|
218
244
|
createReviver,
|
|
219
245
|
createSafeNumberReplacer,
|
|
220
246
|
createSafeNumberReviver,
|
|
221
|
-
parse,
|
|
247
|
+
parse2 as parse,
|
|
222
248
|
patch,
|
|
223
249
|
safeNumberParse,
|
|
224
250
|
safeNumberStringify,
|
|
251
|
+
setGlobalTypes,
|
|
225
252
|
stringify,
|
|
226
253
|
unpatch
|
|
227
254
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awsless/json",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@awsless/big-float": "^0.
|
|
45
|
-
"@awsless/duration": "^0.0.
|
|
44
|
+
"@awsless/big-float": "^0.1.5",
|
|
45
|
+
"@awsless/duration": "^0.0.4"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@awsless/big-float": "^0.
|
|
49
|
-
"@awsless/duration": "^0.0.
|
|
48
|
+
"@awsless/big-float": "^0.1.5",
|
|
49
|
+
"@awsless/duration": "^0.0.4"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"test": "pnpm code test",
|