@awsless/json 0.0.6 → 0.0.8
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 +16 -8
- package/dist/index.cjs +53 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +53 -2
- package/package.json +12 -4
package/README.MD
CHANGED
|
@@ -7,29 +7,33 @@ Features:
|
|
|
7
7
|
- Lightweight / Using the JS native JSON parser.
|
|
8
8
|
- JSON backwards compatible.
|
|
9
9
|
- No precision loss.
|
|
10
|
-
- Includes support basic JS types.
|
|
10
|
+
- Includes support for basic JS types.
|
|
11
11
|
- Extendable.
|
|
12
12
|
|
|
13
13
|
## The Problem
|
|
14
14
|
|
|
15
15
|
JSON doesn't have support for types like:
|
|
16
16
|
- `undefined`
|
|
17
|
+
- `NaN`
|
|
18
|
+
- `Infinity`
|
|
19
|
+
- `Uint8Array`
|
|
20
|
+
- `RegExp`
|
|
17
21
|
- `Set`
|
|
18
22
|
- `Map`
|
|
23
|
+
- `URL`
|
|
19
24
|
- `Date`
|
|
20
25
|
- `BigInt`
|
|
21
26
|
- `BigFloat` - npm package @awsless/bit-float
|
|
22
27
|
|
|
23
|
-
Having to
|
|
28
|
+
Having to encode & decode these type of values can get quite annoying. We try to solve this problem by encoding these types using valid JSON syntax.
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
Additionally, the native `JSON.parse/stringify` functions do not address the potential loss of precision problem.
|
|
26
31
|
|
|
27
32
|
## Basic Usage
|
|
28
33
|
|
|
29
34
|
```ts
|
|
30
35
|
import { parse, stringify } from '@awsless/json';
|
|
31
36
|
|
|
32
|
-
// Stringify a bigint.
|
|
33
37
|
// The output will be {"$bigint":"1"}
|
|
34
38
|
const json = stringify(1n)
|
|
35
39
|
|
|
@@ -39,7 +43,7 @@ const value = parse(json)
|
|
|
39
43
|
|
|
40
44
|
## Patching incorrectly parsed JSON that was parsed with a different JSON parser
|
|
41
45
|
|
|
42
|
-
In some
|
|
46
|
+
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.
|
|
43
47
|
|
|
44
48
|
```ts
|
|
45
49
|
import { stringify, patch } from '@awsless/json';
|
|
@@ -83,11 +87,15 @@ const value = parse(json, { $custom })
|
|
|
83
87
|
|
|
84
88
|
## Precision Loss
|
|
85
89
|
|
|
86
|
-
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.
|
|
90
|
+
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.
|
|
91
|
+
|
|
92
|
+
> [!NOTE]
|
|
93
|
+
> These utility functions will only work in environments that support `JSON.rawJSON`
|
|
94
|
+
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/rawJSON#browser_compatibility
|
|
87
95
|
|
|
88
96
|
```ts
|
|
89
97
|
import { safeNumberParse, safeNumberStringify } from '@awsless/json';
|
|
90
|
-
import { BigFloat } from '@awsless/big-float';
|
|
98
|
+
import { BigFloat, eq } from '@awsless/big-float';
|
|
91
99
|
|
|
92
100
|
const value = new BigFloat(1)
|
|
93
101
|
const json = safeNumberStringify(ONE, {
|
|
@@ -106,7 +114,7 @@ console.log(eq(value, result)) // true
|
|
|
106
114
|
|
|
107
115
|
## Known Issue's
|
|
108
116
|
|
|
109
|
-
### Don't use the
|
|
117
|
+
### Don't use the `$` character inside your JSON.
|
|
110
118
|
|
|
111
119
|
We use the `$` character to encode our special types inside JSON. In order to prevent parsing errors we recommend to avoid using the `$` character inside your object property names.
|
|
112
120
|
|
package/dist/index.cjs
CHANGED
|
@@ -55,6 +55,15 @@ var $date = {
|
|
|
55
55
|
stringify: (v) => v.toISOString()
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
+
// src/type/infinity.ts
|
|
59
|
+
var P = Infinity;
|
|
60
|
+
var N = -Infinity;
|
|
61
|
+
var $infinity = {
|
|
62
|
+
is: (v) => v === P || v === N,
|
|
63
|
+
parse: (v) => v === 1 ? P : N,
|
|
64
|
+
stringify: (v) => v > 0 ? 1 : 0
|
|
65
|
+
};
|
|
66
|
+
|
|
58
67
|
// src/type/map.ts
|
|
59
68
|
var $map = {
|
|
60
69
|
is: (v) => v instanceof Map,
|
|
@@ -62,6 +71,20 @@ var $map = {
|
|
|
62
71
|
stringify: (v) => Array.from(v)
|
|
63
72
|
};
|
|
64
73
|
|
|
74
|
+
// src/type/nan.ts
|
|
75
|
+
var $nan = {
|
|
76
|
+
is: (v) => typeof v === "number" && isNaN(v),
|
|
77
|
+
parse: (_) => NaN,
|
|
78
|
+
stringify: (_) => 0
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// src/type/regexp.ts
|
|
82
|
+
var $regexp = {
|
|
83
|
+
is: (v) => v instanceof RegExp,
|
|
84
|
+
parse: (v) => new RegExp(v[0], v[1]),
|
|
85
|
+
stringify: (v) => [v.source, v.flags]
|
|
86
|
+
};
|
|
87
|
+
|
|
65
88
|
// src/type/set.ts
|
|
66
89
|
var $set = {
|
|
67
90
|
is: (v) => v instanceof Set,
|
|
@@ -69,6 +92,13 @@ var $set = {
|
|
|
69
92
|
stringify: (v) => Array.from(v)
|
|
70
93
|
};
|
|
71
94
|
|
|
95
|
+
// src/type/binary.ts
|
|
96
|
+
var $binary = {
|
|
97
|
+
is: (v) => v instanceof Uint8Array,
|
|
98
|
+
parse: (v) => Uint8Array.from(atob(v), (c) => c.charCodeAt(0)),
|
|
99
|
+
stringify: (v) => btoa(String.fromCharCode(...v))
|
|
100
|
+
};
|
|
101
|
+
|
|
72
102
|
// src/type/undefined.ts
|
|
73
103
|
var $undefined = {
|
|
74
104
|
is: (v) => typeof v === "undefined",
|
|
@@ -76,14 +106,35 @@ var $undefined = {
|
|
|
76
106
|
stringify: (_) => 0
|
|
77
107
|
};
|
|
78
108
|
|
|
109
|
+
// src/type/url.ts
|
|
110
|
+
var $url = {
|
|
111
|
+
is: (v) => v instanceof URL,
|
|
112
|
+
parse: (v) => new URL(v),
|
|
113
|
+
stringify: (v) => v.toString()
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/type/duration.ts
|
|
117
|
+
var import_duration = require("@awsless/duration");
|
|
118
|
+
var $duration = {
|
|
119
|
+
is: (v) => v instanceof import_duration.Duration,
|
|
120
|
+
parse: (v) => new import_duration.Duration(BigInt(v)),
|
|
121
|
+
stringify: (v) => v.value.toString()
|
|
122
|
+
};
|
|
123
|
+
|
|
79
124
|
// src/type/index.ts
|
|
80
125
|
var baseTypes = {
|
|
81
126
|
$undefined,
|
|
127
|
+
$duration,
|
|
128
|
+
$infinity,
|
|
82
129
|
$bigfloat,
|
|
83
130
|
$bigint,
|
|
131
|
+
$regexp,
|
|
132
|
+
$binary,
|
|
84
133
|
$date,
|
|
85
134
|
$set,
|
|
86
|
-
$map
|
|
135
|
+
$map,
|
|
136
|
+
$nan,
|
|
137
|
+
$url
|
|
87
138
|
};
|
|
88
139
|
|
|
89
140
|
// src/parse.ts
|
|
@@ -150,7 +201,7 @@ var safeNumberParse = (json, props) => {
|
|
|
150
201
|
);
|
|
151
202
|
};
|
|
152
203
|
var createSafeNumberReviver = (props) => {
|
|
153
|
-
return
|
|
204
|
+
return (_, value, context) => {
|
|
154
205
|
if (typeof value === "number") {
|
|
155
206
|
return props.parse(context.source);
|
|
156
207
|
}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -20,6 +20,15 @@ var $date = {
|
|
|
20
20
|
stringify: (v) => v.toISOString()
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
+
// src/type/infinity.ts
|
|
24
|
+
var P = Infinity;
|
|
25
|
+
var N = -Infinity;
|
|
26
|
+
var $infinity = {
|
|
27
|
+
is: (v) => v === P || v === N,
|
|
28
|
+
parse: (v) => v === 1 ? P : N,
|
|
29
|
+
stringify: (v) => v > 0 ? 1 : 0
|
|
30
|
+
};
|
|
31
|
+
|
|
23
32
|
// src/type/map.ts
|
|
24
33
|
var $map = {
|
|
25
34
|
is: (v) => v instanceof Map,
|
|
@@ -27,6 +36,20 @@ var $map = {
|
|
|
27
36
|
stringify: (v) => Array.from(v)
|
|
28
37
|
};
|
|
29
38
|
|
|
39
|
+
// src/type/nan.ts
|
|
40
|
+
var $nan = {
|
|
41
|
+
is: (v) => typeof v === "number" && isNaN(v),
|
|
42
|
+
parse: (_) => NaN,
|
|
43
|
+
stringify: (_) => 0
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// src/type/regexp.ts
|
|
47
|
+
var $regexp = {
|
|
48
|
+
is: (v) => v instanceof RegExp,
|
|
49
|
+
parse: (v) => new RegExp(v[0], v[1]),
|
|
50
|
+
stringify: (v) => [v.source, v.flags]
|
|
51
|
+
};
|
|
52
|
+
|
|
30
53
|
// src/type/set.ts
|
|
31
54
|
var $set = {
|
|
32
55
|
is: (v) => v instanceof Set,
|
|
@@ -34,6 +57,13 @@ var $set = {
|
|
|
34
57
|
stringify: (v) => Array.from(v)
|
|
35
58
|
};
|
|
36
59
|
|
|
60
|
+
// src/type/binary.ts
|
|
61
|
+
var $binary = {
|
|
62
|
+
is: (v) => v instanceof Uint8Array,
|
|
63
|
+
parse: (v) => Uint8Array.from(atob(v), (c) => c.charCodeAt(0)),
|
|
64
|
+
stringify: (v) => btoa(String.fromCharCode(...v))
|
|
65
|
+
};
|
|
66
|
+
|
|
37
67
|
// src/type/undefined.ts
|
|
38
68
|
var $undefined = {
|
|
39
69
|
is: (v) => typeof v === "undefined",
|
|
@@ -41,14 +71,35 @@ var $undefined = {
|
|
|
41
71
|
stringify: (_) => 0
|
|
42
72
|
};
|
|
43
73
|
|
|
74
|
+
// src/type/url.ts
|
|
75
|
+
var $url = {
|
|
76
|
+
is: (v) => v instanceof URL,
|
|
77
|
+
parse: (v) => new URL(v),
|
|
78
|
+
stringify: (v) => v.toString()
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// src/type/duration.ts
|
|
82
|
+
import { Duration } from "@awsless/duration";
|
|
83
|
+
var $duration = {
|
|
84
|
+
is: (v) => v instanceof Duration,
|
|
85
|
+
parse: (v) => new Duration(BigInt(v)),
|
|
86
|
+
stringify: (v) => v.value.toString()
|
|
87
|
+
};
|
|
88
|
+
|
|
44
89
|
// src/type/index.ts
|
|
45
90
|
var baseTypes = {
|
|
46
91
|
$undefined,
|
|
92
|
+
$duration,
|
|
93
|
+
$infinity,
|
|
47
94
|
$bigfloat,
|
|
48
95
|
$bigint,
|
|
96
|
+
$regexp,
|
|
97
|
+
$binary,
|
|
49
98
|
$date,
|
|
50
99
|
$set,
|
|
51
|
-
$map
|
|
100
|
+
$map,
|
|
101
|
+
$nan,
|
|
102
|
+
$url
|
|
52
103
|
};
|
|
53
104
|
|
|
54
105
|
// src/parse.ts
|
|
@@ -115,7 +166,7 @@ var safeNumberParse = (json, props) => {
|
|
|
115
166
|
);
|
|
116
167
|
};
|
|
117
168
|
var createSafeNumberReviver = (props) => {
|
|
118
|
-
return
|
|
169
|
+
return (_, value, context) => {
|
|
119
170
|
if (typeof value === "number") {
|
|
120
171
|
return props.parse(context.source);
|
|
121
172
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awsless/json",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -12,7 +12,13 @@
|
|
|
12
12
|
"Map",
|
|
13
13
|
"Set",
|
|
14
14
|
"Date",
|
|
15
|
-
"
|
|
15
|
+
"NaN",
|
|
16
|
+
"Infinity",
|
|
17
|
+
"RegExp",
|
|
18
|
+
"Uint8Array",
|
|
19
|
+
"Binary",
|
|
20
|
+
"undefined",
|
|
21
|
+
"extendable"
|
|
16
22
|
],
|
|
17
23
|
"repository": {
|
|
18
24
|
"type": "git",
|
|
@@ -35,10 +41,12 @@
|
|
|
35
41
|
}
|
|
36
42
|
},
|
|
37
43
|
"peerDependencies": {
|
|
38
|
-
"@awsless/big-float": "^0.0.4"
|
|
44
|
+
"@awsless/big-float": "^0.0.4",
|
|
45
|
+
"@awsless/duration": "^0.0.2"
|
|
39
46
|
},
|
|
40
47
|
"devDependencies": {
|
|
41
|
-
"@awsless/big-float": "^0.0.4"
|
|
48
|
+
"@awsless/big-float": "^0.0.4",
|
|
49
|
+
"@awsless/duration": "^0.0.2"
|
|
42
50
|
},
|
|
43
51
|
"scripts": {
|
|
44
52
|
"test": "pnpm code test",
|