@awsless/json 0.0.4 → 0.0.6
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 -6
- package/dist/index.cjs +47 -3
- package/dist/index.d.cts +23 -5
- package/dist/index.d.ts +23 -5
- package/dist/index.js +41 -2
- package/package.json +1 -1
package/README.MD
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
|
|
4
4
|
The `@awsless/json` package adds support for more JavaScript native types to JSON.
|
|
5
5
|
|
|
6
|
+
Features:
|
|
7
|
+
- Lightweight / Using the JS native JSON parser.
|
|
8
|
+
- JSON backwards compatible.
|
|
9
|
+
- No precision loss.
|
|
10
|
+
- Includes support basic JS types.
|
|
11
|
+
- Extendable.
|
|
12
|
+
|
|
6
13
|
## The Problem
|
|
7
14
|
|
|
8
15
|
JSON doesn't have support for types like:
|
|
@@ -15,6 +22,8 @@ JSON doesn't have support for types like:
|
|
|
15
22
|
|
|
16
23
|
Having to decode & encode these type of values can get quite annoying. We try to solve this problem by encoding these types using valid JSON syntax.
|
|
17
24
|
|
|
25
|
+
Also `JSON.parse/stringify` don't solve the potential loss of precision problem.
|
|
26
|
+
|
|
18
27
|
## Basic Usage
|
|
19
28
|
|
|
20
29
|
```ts
|
|
@@ -65,24 +74,51 @@ const $custom: Serializable<Custom, string> = {
|
|
|
65
74
|
stringify: v => v.value,
|
|
66
75
|
}
|
|
67
76
|
|
|
68
|
-
// Stringify your custom type
|
|
77
|
+
// Stringify your custom type.
|
|
69
78
|
const json = stringify(new Custom('example'), { $custom })
|
|
70
79
|
|
|
71
|
-
// Parse the json with your custom type
|
|
80
|
+
// Parse the json with your custom type.
|
|
72
81
|
const value = parse(json, { $custom })
|
|
73
82
|
```
|
|
74
83
|
|
|
84
|
+
## Precision Loss
|
|
85
|
+
|
|
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.
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { safeNumberParse, safeNumberStringify } from '@awsless/json';
|
|
90
|
+
import { BigFloat } from '@awsless/big-float';
|
|
91
|
+
|
|
92
|
+
const value = new BigFloat(1)
|
|
93
|
+
const json = safeNumberStringify(ONE, {
|
|
94
|
+
is: v => v instanceof BigFloat,
|
|
95
|
+
stringify: v => v.toString(),
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
console.log(json) // '1'
|
|
99
|
+
|
|
100
|
+
const result = safeNumberParse('1', {
|
|
101
|
+
parse: v => new BigFloat(v),
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
console.log(eq(value, result)) // true
|
|
105
|
+
```
|
|
106
|
+
|
|
75
107
|
## Known Issue's
|
|
76
108
|
|
|
77
|
-
|
|
109
|
+
### Don't use the $ character inside your JSON.
|
|
110
|
+
|
|
111
|
+
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
|
+
|
|
113
|
+
### Object properties with `undefined` as value type will be stripped away.
|
|
78
114
|
|
|
79
115
|
```ts
|
|
80
|
-
// Will result in an empty object
|
|
116
|
+
// Will result in an empty object.
|
|
81
117
|
const result = parse(stringify({ key: undefined }))
|
|
82
118
|
|
|
83
|
-
// Will log false
|
|
119
|
+
// Will log false.
|
|
84
120
|
console.log('key' in result)
|
|
85
121
|
|
|
86
|
-
// Will log true
|
|
122
|
+
// Will log true.
|
|
87
123
|
console.log(result.key === undefined)
|
|
88
124
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -22,9 +22,14 @@ var src_exports = {};
|
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
createReplacer: () => createReplacer,
|
|
24
24
|
createReviver: () => createReviver,
|
|
25
|
+
createSafeNumberReplacer: () => createSafeNumberReplacer,
|
|
26
|
+
createSafeNumberReviver: () => createSafeNumberReviver,
|
|
25
27
|
parse: () => parse,
|
|
26
28
|
patch: () => patch,
|
|
27
|
-
|
|
29
|
+
safeNumberParse: () => safeNumberParse,
|
|
30
|
+
safeNumberStringify: () => safeNumberStringify,
|
|
31
|
+
stringify: () => stringify,
|
|
32
|
+
unpatch: () => unpatch
|
|
28
33
|
});
|
|
29
34
|
module.exports = __toCommonJS(src_exports);
|
|
30
35
|
|
|
@@ -130,13 +135,52 @@ var createReplacer = (types = {}) => {
|
|
|
130
135
|
|
|
131
136
|
// src/patch.ts
|
|
132
137
|
var patch = (value, types = {}) => {
|
|
133
|
-
return parse(stringify(value
|
|
138
|
+
return parse(JSON.stringify(value), types);
|
|
139
|
+
};
|
|
140
|
+
var unpatch = (value, types = {}) => {
|
|
141
|
+
return JSON.parse(stringify(value, types));
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// src/safe-number/parse.ts
|
|
145
|
+
var safeNumberParse = (json, props) => {
|
|
146
|
+
return JSON.parse(
|
|
147
|
+
json,
|
|
148
|
+
// @ts-ignore
|
|
149
|
+
createSafeNumberReviver(props)
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
var createSafeNumberReviver = (props) => {
|
|
153
|
+
return function(_, value, context) {
|
|
154
|
+
if (typeof value === "number") {
|
|
155
|
+
return props.parse(context.source);
|
|
156
|
+
}
|
|
157
|
+
return value;
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// src/safe-number/stringify.ts
|
|
162
|
+
var safeNumberStringify = (value, props) => {
|
|
163
|
+
return JSON.stringify(value, createSafeNumberReplacer(props));
|
|
164
|
+
};
|
|
165
|
+
var createSafeNumberReplacer = (props) => {
|
|
166
|
+
return function(key, value) {
|
|
167
|
+
const original = this[key];
|
|
168
|
+
if (props.is(original)) {
|
|
169
|
+
return JSON.rawJSON(props.stringify(original));
|
|
170
|
+
}
|
|
171
|
+
return value;
|
|
172
|
+
};
|
|
134
173
|
};
|
|
135
174
|
// Annotate the CommonJS export names for ESM import in node:
|
|
136
175
|
0 && (module.exports = {
|
|
137
176
|
createReplacer,
|
|
138
177
|
createReviver,
|
|
178
|
+
createSafeNumberReplacer,
|
|
179
|
+
createSafeNumberReviver,
|
|
139
180
|
parse,
|
|
140
181
|
patch,
|
|
141
|
-
|
|
182
|
+
safeNumberParse,
|
|
183
|
+
safeNumberStringify,
|
|
184
|
+
stringify,
|
|
185
|
+
unpatch
|
|
142
186
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -5,14 +5,32 @@ type Serializable<I, O> = {
|
|
|
5
5
|
};
|
|
6
6
|
type SerializableTypes = Record<string, Serializable<any, any>>;
|
|
7
7
|
|
|
8
|
-
declare const patch:
|
|
8
|
+
declare const patch: (value: unknown, types?: SerializableTypes) => any;
|
|
9
|
+
declare const unpatch: (value: unknown, types?: SerializableTypes) => any;
|
|
9
10
|
|
|
10
11
|
declare const parse: (json: string, types?: SerializableTypes) => any;
|
|
11
|
-
type Reviver = (this: any, key: string, value: any) => any;
|
|
12
|
-
declare const createReviver: (types?: SerializableTypes) => Reviver;
|
|
12
|
+
type Reviver$1 = (this: any, key: string, value: any) => any;
|
|
13
|
+
declare const createReviver: (types?: SerializableTypes) => Reviver$1;
|
|
13
14
|
|
|
14
15
|
declare const stringify: (value: unknown, types?: SerializableTypes) => string;
|
|
16
|
+
type Replacer$1 = (this: any, key: string, value: any) => any;
|
|
17
|
+
declare const createReplacer: (types?: SerializableTypes) => Replacer$1;
|
|
18
|
+
|
|
19
|
+
type Props$1 = {
|
|
20
|
+
parse: (value: string) => unknown;
|
|
21
|
+
};
|
|
22
|
+
declare const safeNumberParse: (json: string, props: Props$1) => any;
|
|
23
|
+
type Reviver = (this: any, key: string, value: any, context: {
|
|
24
|
+
source: string;
|
|
25
|
+
}) => any;
|
|
26
|
+
declare const createSafeNumberReviver: (props: Props$1) => Reviver;
|
|
27
|
+
|
|
28
|
+
type Props<T> = {
|
|
29
|
+
is: (value: unknown) => value is T;
|
|
30
|
+
stringify: (value: T) => string;
|
|
31
|
+
};
|
|
32
|
+
declare const safeNumberStringify: <T>(value: unknown, props: Props<T>) => string;
|
|
15
33
|
type Replacer = (this: any, key: string, value: any) => any;
|
|
16
|
-
declare const
|
|
34
|
+
declare const createSafeNumberReplacer: <T>(props: Props<T>) => Replacer;
|
|
17
35
|
|
|
18
|
-
export { type Serializable, createReplacer, createReviver, parse, patch, stringify };
|
|
36
|
+
export { type Serializable, createReplacer, createReviver, createSafeNumberReplacer, createSafeNumberReviver, parse, patch, safeNumberParse, safeNumberStringify, stringify, unpatch };
|
package/dist/index.d.ts
CHANGED
|
@@ -5,14 +5,32 @@ type Serializable<I, O> = {
|
|
|
5
5
|
};
|
|
6
6
|
type SerializableTypes = Record<string, Serializable<any, any>>;
|
|
7
7
|
|
|
8
|
-
declare const patch:
|
|
8
|
+
declare const patch: (value: unknown, types?: SerializableTypes) => any;
|
|
9
|
+
declare const unpatch: (value: unknown, types?: SerializableTypes) => any;
|
|
9
10
|
|
|
10
11
|
declare const parse: (json: string, types?: SerializableTypes) => any;
|
|
11
|
-
type Reviver = (this: any, key: string, value: any) => any;
|
|
12
|
-
declare const createReviver: (types?: SerializableTypes) => Reviver;
|
|
12
|
+
type Reviver$1 = (this: any, key: string, value: any) => any;
|
|
13
|
+
declare const createReviver: (types?: SerializableTypes) => Reviver$1;
|
|
13
14
|
|
|
14
15
|
declare const stringify: (value: unknown, types?: SerializableTypes) => string;
|
|
16
|
+
type Replacer$1 = (this: any, key: string, value: any) => any;
|
|
17
|
+
declare const createReplacer: (types?: SerializableTypes) => Replacer$1;
|
|
18
|
+
|
|
19
|
+
type Props$1 = {
|
|
20
|
+
parse: (value: string) => unknown;
|
|
21
|
+
};
|
|
22
|
+
declare const safeNumberParse: (json: string, props: Props$1) => any;
|
|
23
|
+
type Reviver = (this: any, key: string, value: any, context: {
|
|
24
|
+
source: string;
|
|
25
|
+
}) => any;
|
|
26
|
+
declare const createSafeNumberReviver: (props: Props$1) => Reviver;
|
|
27
|
+
|
|
28
|
+
type Props<T> = {
|
|
29
|
+
is: (value: unknown) => value is T;
|
|
30
|
+
stringify: (value: T) => string;
|
|
31
|
+
};
|
|
32
|
+
declare const safeNumberStringify: <T>(value: unknown, props: Props<T>) => string;
|
|
15
33
|
type Replacer = (this: any, key: string, value: any) => any;
|
|
16
|
-
declare const
|
|
34
|
+
declare const createSafeNumberReplacer: <T>(props: Props<T>) => Replacer;
|
|
17
35
|
|
|
18
|
-
export { type Serializable, createReplacer, createReviver, parse, patch, stringify };
|
|
36
|
+
export { type Serializable, createReplacer, createReviver, createSafeNumberReplacer, createSafeNumberReviver, parse, patch, safeNumberParse, safeNumberStringify, stringify, unpatch };
|
package/dist/index.js
CHANGED
|
@@ -100,12 +100,51 @@ var createReplacer = (types = {}) => {
|
|
|
100
100
|
|
|
101
101
|
// src/patch.ts
|
|
102
102
|
var patch = (value, types = {}) => {
|
|
103
|
-
return parse(stringify(value
|
|
103
|
+
return parse(JSON.stringify(value), types);
|
|
104
|
+
};
|
|
105
|
+
var unpatch = (value, types = {}) => {
|
|
106
|
+
return JSON.parse(stringify(value, types));
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// src/safe-number/parse.ts
|
|
110
|
+
var safeNumberParse = (json, props) => {
|
|
111
|
+
return JSON.parse(
|
|
112
|
+
json,
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
createSafeNumberReviver(props)
|
|
115
|
+
);
|
|
116
|
+
};
|
|
117
|
+
var createSafeNumberReviver = (props) => {
|
|
118
|
+
return function(_, value, context) {
|
|
119
|
+
if (typeof value === "number") {
|
|
120
|
+
return props.parse(context.source);
|
|
121
|
+
}
|
|
122
|
+
return value;
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// src/safe-number/stringify.ts
|
|
127
|
+
var safeNumberStringify = (value, props) => {
|
|
128
|
+
return JSON.stringify(value, createSafeNumberReplacer(props));
|
|
129
|
+
};
|
|
130
|
+
var createSafeNumberReplacer = (props) => {
|
|
131
|
+
return function(key, value) {
|
|
132
|
+
const original = this[key];
|
|
133
|
+
if (props.is(original)) {
|
|
134
|
+
return JSON.rawJSON(props.stringify(original));
|
|
135
|
+
}
|
|
136
|
+
return value;
|
|
137
|
+
};
|
|
104
138
|
};
|
|
105
139
|
export {
|
|
106
140
|
createReplacer,
|
|
107
141
|
createReviver,
|
|
142
|
+
createSafeNumberReplacer,
|
|
143
|
+
createSafeNumberReviver,
|
|
108
144
|
parse,
|
|
109
145
|
patch,
|
|
110
|
-
|
|
146
|
+
safeNumberParse,
|
|
147
|
+
safeNumberStringify,
|
|
148
|
+
stringify,
|
|
149
|
+
unpatch
|
|
111
150
|
};
|