@awsless/json 0.0.8 → 0.0.10

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 CHANGED
@@ -24,6 +24,7 @@ JSON doesn't have support for types like:
24
24
  - `Date`
25
25
  - `BigInt`
26
26
  - `BigFloat` - npm package @awsless/bit-float
27
+ - `Duration` - npm package @awsless/duration
27
28
 
28
29
  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.
29
30
 
@@ -117,16 +118,3 @@ console.log(eq(value, result)) // true
117
118
  ### Don't use the `$` character inside your JSON.
118
119
 
119
120
  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.
120
-
121
- ### Object properties with `undefined` as value type will be stripped away.
122
-
123
- ```ts
124
- // Will result in an empty object.
125
- const result = parse(stringify({ key: undefined }))
126
-
127
- // Will log false.
128
- console.log('key' in result)
129
-
130
- // Will log true.
131
- console.log(result.key === undefined)
132
- ```
package/dist/index.cjs CHANGED
@@ -18,8 +18,9 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
20
  // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ $mockdate: () => $mockdate,
23
24
  createReplacer: () => createReplacer,
24
25
  createReviver: () => createReviver,
25
26
  createSafeNumberReplacer: () => createSafeNumberReplacer,
@@ -28,10 +29,11 @@ __export(src_exports, {
28
29
  patch: () => patch,
29
30
  safeNumberParse: () => safeNumberParse,
30
31
  safeNumberStringify: () => safeNumberStringify,
32
+ setGlobalTypes: () => setGlobalTypes,
31
33
  stringify: () => stringify,
32
34
  unpatch: () => unpatch
33
35
  });
34
- module.exports = __toCommonJS(src_exports);
36
+ module.exports = __toCommonJS(index_exports);
35
37
 
36
38
  // src/type/bigfloat.ts
37
39
  var import_big_float = require("@awsless/big-float");
@@ -64,10 +66,24 @@ var $infinity = {
64
66
  stringify: (v) => v > 0 ? 1 : 0
65
67
  };
66
68
 
69
+ // src/type/undefined.ts
70
+ var $undefined = {
71
+ is: (v) => typeof v === "undefined",
72
+ replace: (_) => void 0,
73
+ stringify: (_) => 0
74
+ };
75
+ var isUndefined = (value) => {
76
+ return typeof value === "object" && value !== null && Object.keys(value).length === 1 && "$undefined" in value && value.$undefined === 0;
77
+ };
78
+
67
79
  // src/type/map.ts
68
80
  var $map = {
69
81
  is: (v) => v instanceof Map,
70
- parse: (v) => new Map(v),
82
+ parse: (v) => new Map(
83
+ v.map((pair) => {
84
+ return pair.map((i) => isUndefined(i) ? void 0 : i);
85
+ })
86
+ ),
71
87
  stringify: (v) => Array.from(v)
72
88
  };
73
89
 
@@ -88,7 +104,7 @@ var $regexp = {
88
104
  // src/type/set.ts
89
105
  var $set = {
90
106
  is: (v) => v instanceof Set,
91
- parse: (v) => new Set(v),
107
+ parse: (v) => new Set(v.map((i) => isUndefined(i) ? void 0 : i)),
92
108
  stringify: (v) => Array.from(v)
93
109
  };
94
110
 
@@ -99,13 +115,6 @@ var $binary = {
99
115
  stringify: (v) => btoa(String.fromCharCode(...v))
100
116
  };
101
117
 
102
- // src/type/undefined.ts
103
- var $undefined = {
104
- is: (v) => typeof v === "undefined",
105
- parse: (_) => void 0,
106
- stringify: (_) => 0
107
- };
108
-
109
118
  // src/type/url.ts
110
119
  var $url = {
111
120
  is: (v) => v instanceof URL,
@@ -139,9 +148,19 @@ var baseTypes = {
139
148
 
140
149
  // src/parse.ts
141
150
  var parse = (json, types = {}) => {
142
- return JSON.parse(json, createReviver(types));
151
+ const replacements = [];
152
+ const result = JSON.parse(
153
+ json,
154
+ createReviver(types, (target, key, value) => {
155
+ replacements.push([target, key, value]);
156
+ })
157
+ );
158
+ for (const [target, key, value] of replacements) {
159
+ target[key] = value;
160
+ }
161
+ return result;
143
162
  };
144
- var createReviver = (types = {}) => {
163
+ var createReviver = (types = {}, registerReplacement) => {
145
164
  types = {
146
165
  ...baseTypes,
147
166
  ...types
@@ -154,7 +173,16 @@ var createReviver = (types = {}) => {
154
173
  const typeName = keys[0];
155
174
  if (typeName in types && types[typeName]) {
156
175
  const type = types[typeName];
157
- return type.parse(original[typeName]);
176
+ const stringified = original[typeName];
177
+ if ("parse" in type) {
178
+ return type.parse(stringified);
179
+ } else if (registerReplacement) {
180
+ const result = type.replace(stringified);
181
+ registerReplacement(this, key, result);
182
+ return result;
183
+ } else {
184
+ return type.replace(stringified);
185
+ }
158
186
  }
159
187
  }
160
188
  }
@@ -192,6 +220,18 @@ var unpatch = (value, types = {}) => {
192
220
  return JSON.parse(stringify(value, types));
193
221
  };
194
222
 
223
+ // src/global.ts
224
+ var setGlobalTypes = (types) => {
225
+ Object.assign(baseTypes, types);
226
+ };
227
+
228
+ // src/type/mockdate.ts
229
+ var $mockdate = {
230
+ 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",
231
+ parse: (v) => new Date(v),
232
+ stringify: (v) => v.toISOString()
233
+ };
234
+
195
235
  // src/safe-number/parse.ts
196
236
  var safeNumberParse = (json, props) => {
197
237
  return JSON.parse(
@@ -224,6 +264,7 @@ var createSafeNumberReplacer = (props) => {
224
264
  };
225
265
  // Annotate the CommonJS export names for ESM import in node:
226
266
  0 && (module.exports = {
267
+ $mockdate,
227
268
  createReplacer,
228
269
  createReviver,
229
270
  createSafeNumberReplacer,
@@ -232,6 +273,7 @@ var createSafeNumberReplacer = (props) => {
232
273
  patch,
233
274
  safeNumberParse,
234
275
  safeNumberStringify,
276
+ setGlobalTypes,
235
277
  stringify,
236
278
  unpatch
237
279
  });
package/dist/index.d.cts CHANGED
@@ -1,8 +1,11 @@
1
1
  type Serializable<I, O> = {
2
2
  is: (value: unknown) => boolean;
3
- parse: (value: O) => I;
4
3
  stringify: (value: I) => O;
5
- };
4
+ } & ({
5
+ parse: (value: O) => I;
6
+ } | {
7
+ replace: (value: O) => I;
8
+ });
6
9
  type SerializableTypes = Record<string, Serializable<any, any>>;
7
10
 
8
11
  declare const patch: (value: unknown, types?: SerializableTypes) => any;
@@ -10,12 +13,16 @@ declare const unpatch: (value: unknown, types?: SerializableTypes) => any;
10
13
 
11
14
  declare const parse: (json: string, types?: SerializableTypes) => any;
12
15
  type Reviver$1 = (this: any, key: string, value: any) => any;
13
- declare const createReviver: (types?: SerializableTypes) => Reviver$1;
16
+ declare const createReviver: (types?: SerializableTypes, registerReplacement?: (target: any, key: string, value: unknown) => void) => Reviver$1;
14
17
 
15
18
  declare const stringify: (value: unknown, types?: SerializableTypes) => string;
16
19
  type Replacer$1 = (this: any, key: string, value: any) => any;
17
20
  declare const createReplacer: (types?: SerializableTypes) => Replacer$1;
18
21
 
22
+ declare const setGlobalTypes: (types: SerializableTypes) => void;
23
+
24
+ declare const $mockdate: Serializable<Date, string>;
25
+
19
26
  type Props$1 = {
20
27
  parse: (value: string) => unknown;
21
28
  };
@@ -33,4 +40,4 @@ declare const safeNumberStringify: <T>(value: unknown, props: Props<T>) => strin
33
40
  type Replacer = (this: any, key: string, value: any) => any;
34
41
  declare const createSafeNumberReplacer: <T>(props: Props<T>) => Replacer;
35
42
 
36
- export { type Serializable, createReplacer, createReviver, createSafeNumberReplacer, createSafeNumberReviver, parse, patch, safeNumberParse, safeNumberStringify, stringify, unpatch };
43
+ export { $mockdate, type Serializable, createReplacer, createReviver, createSafeNumberReplacer, createSafeNumberReviver, parse, patch, safeNumberParse, safeNumberStringify, setGlobalTypes, stringify, unpatch };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  type Serializable<I, O> = {
2
2
  is: (value: unknown) => boolean;
3
- parse: (value: O) => I;
4
3
  stringify: (value: I) => O;
5
- };
4
+ } & ({
5
+ parse: (value: O) => I;
6
+ } | {
7
+ replace: (value: O) => I;
8
+ });
6
9
  type SerializableTypes = Record<string, Serializable<any, any>>;
7
10
 
8
11
  declare const patch: (value: unknown, types?: SerializableTypes) => any;
@@ -10,12 +13,16 @@ declare const unpatch: (value: unknown, types?: SerializableTypes) => any;
10
13
 
11
14
  declare const parse: (json: string, types?: SerializableTypes) => any;
12
15
  type Reviver$1 = (this: any, key: string, value: any) => any;
13
- declare const createReviver: (types?: SerializableTypes) => Reviver$1;
16
+ declare const createReviver: (types?: SerializableTypes, registerReplacement?: (target: any, key: string, value: unknown) => void) => Reviver$1;
14
17
 
15
18
  declare const stringify: (value: unknown, types?: SerializableTypes) => string;
16
19
  type Replacer$1 = (this: any, key: string, value: any) => any;
17
20
  declare const createReplacer: (types?: SerializableTypes) => Replacer$1;
18
21
 
22
+ declare const setGlobalTypes: (types: SerializableTypes) => void;
23
+
24
+ declare const $mockdate: Serializable<Date, string>;
25
+
19
26
  type Props$1 = {
20
27
  parse: (value: string) => unknown;
21
28
  };
@@ -33,4 +40,4 @@ declare const safeNumberStringify: <T>(value: unknown, props: Props<T>) => strin
33
40
  type Replacer = (this: any, key: string, value: any) => any;
34
41
  declare const createSafeNumberReplacer: <T>(props: Props<T>) => Replacer;
35
42
 
36
- export { type Serializable, createReplacer, createReviver, createSafeNumberReplacer, createSafeNumberReviver, parse, patch, safeNumberParse, safeNumberStringify, stringify, unpatch };
43
+ export { $mockdate, type Serializable, createReplacer, createReviver, createSafeNumberReplacer, createSafeNumberReviver, parse, patch, safeNumberParse, safeNumberStringify, setGlobalTypes, stringify, unpatch };
package/dist/index.js CHANGED
@@ -29,10 +29,24 @@ var $infinity = {
29
29
  stringify: (v) => v > 0 ? 1 : 0
30
30
  };
31
31
 
32
+ // src/type/undefined.ts
33
+ var $undefined = {
34
+ is: (v) => typeof v === "undefined",
35
+ replace: (_) => void 0,
36
+ stringify: (_) => 0
37
+ };
38
+ var isUndefined = (value) => {
39
+ return typeof value === "object" && value !== null && Object.keys(value).length === 1 && "$undefined" in value && value.$undefined === 0;
40
+ };
41
+
32
42
  // src/type/map.ts
33
43
  var $map = {
34
44
  is: (v) => v instanceof Map,
35
- parse: (v) => new Map(v),
45
+ parse: (v) => new Map(
46
+ v.map((pair) => {
47
+ return pair.map((i) => isUndefined(i) ? void 0 : i);
48
+ })
49
+ ),
36
50
  stringify: (v) => Array.from(v)
37
51
  };
38
52
 
@@ -53,7 +67,7 @@ var $regexp = {
53
67
  // src/type/set.ts
54
68
  var $set = {
55
69
  is: (v) => v instanceof Set,
56
- parse: (v) => new Set(v),
70
+ parse: (v) => new Set(v.map((i) => isUndefined(i) ? void 0 : i)),
57
71
  stringify: (v) => Array.from(v)
58
72
  };
59
73
 
@@ -64,13 +78,6 @@ var $binary = {
64
78
  stringify: (v) => btoa(String.fromCharCode(...v))
65
79
  };
66
80
 
67
- // src/type/undefined.ts
68
- var $undefined = {
69
- is: (v) => typeof v === "undefined",
70
- parse: (_) => void 0,
71
- stringify: (_) => 0
72
- };
73
-
74
81
  // src/type/url.ts
75
82
  var $url = {
76
83
  is: (v) => v instanceof URL,
@@ -104,9 +111,19 @@ var baseTypes = {
104
111
 
105
112
  // src/parse.ts
106
113
  var parse = (json, types = {}) => {
107
- return JSON.parse(json, createReviver(types));
114
+ const replacements = [];
115
+ const result = JSON.parse(
116
+ json,
117
+ createReviver(types, (target, key, value) => {
118
+ replacements.push([target, key, value]);
119
+ })
120
+ );
121
+ for (const [target, key, value] of replacements) {
122
+ target[key] = value;
123
+ }
124
+ return result;
108
125
  };
109
- var createReviver = (types = {}) => {
126
+ var createReviver = (types = {}, registerReplacement) => {
110
127
  types = {
111
128
  ...baseTypes,
112
129
  ...types
@@ -119,7 +136,16 @@ var createReviver = (types = {}) => {
119
136
  const typeName = keys[0];
120
137
  if (typeName in types && types[typeName]) {
121
138
  const type = types[typeName];
122
- return type.parse(original[typeName]);
139
+ const stringified = original[typeName];
140
+ if ("parse" in type) {
141
+ return type.parse(stringified);
142
+ } else if (registerReplacement) {
143
+ const result = type.replace(stringified);
144
+ registerReplacement(this, key, result);
145
+ return result;
146
+ } else {
147
+ return type.replace(stringified);
148
+ }
123
149
  }
124
150
  }
125
151
  }
@@ -157,6 +183,18 @@ var unpatch = (value, types = {}) => {
157
183
  return JSON.parse(stringify(value, types));
158
184
  };
159
185
 
186
+ // src/global.ts
187
+ var setGlobalTypes = (types) => {
188
+ Object.assign(baseTypes, types);
189
+ };
190
+
191
+ // src/type/mockdate.ts
192
+ var $mockdate = {
193
+ 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",
194
+ parse: (v) => new Date(v),
195
+ stringify: (v) => v.toISOString()
196
+ };
197
+
160
198
  // src/safe-number/parse.ts
161
199
  var safeNumberParse = (json, props) => {
162
200
  return JSON.parse(
@@ -188,6 +226,7 @@ var createSafeNumberReplacer = (props) => {
188
226
  };
189
227
  };
190
228
  export {
229
+ $mockdate,
191
230
  createReplacer,
192
231
  createReviver,
193
232
  createSafeNumberReplacer,
@@ -196,6 +235,7 @@ export {
196
235
  patch,
197
236
  safeNumberParse,
198
237
  safeNumberStringify,
238
+ setGlobalTypes,
199
239
  stringify,
200
240
  unpatch
201
241
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awsless/json",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
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.0.4",
45
- "@awsless/duration": "^0.0.2"
44
+ "@awsless/big-float": "^0.0.6",
45
+ "@awsless/duration": "^0.0.3"
46
46
  },
47
47
  "devDependencies": {
48
- "@awsless/big-float": "^0.0.4",
49
- "@awsless/duration": "^0.0.2"
48
+ "@awsless/duration": "^0.0.3",
49
+ "@awsless/big-float": "^0.0.6"
50
50
  },
51
51
  "scripts": {
52
52
  "test": "pnpm code test",