seroval 0.4.0-alpha.17 → 0.4.0-alpha.18

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
@@ -53,16 +53,17 @@ object.map.set('mutual', object.set);
53
53
  object.set.add(object.array);
54
54
 
55
55
  const result = serialize(object);
56
+ console.log(result);
56
57
  ```
57
58
 
58
59
  Output (as a string):
59
60
 
60
61
  ```js
61
- ((h,j,k,m)=>(m={number:[0.5623457676854244,-0,NaN,1/0,-1/0],string:["hello world","\x3Cscript>Hello World\x3C/script>"],boolean:[!0,!1],null:null,undefined:void 0,bigint:9007199254740991n,array:h=[,,,,j=new Map([["hello","world"],["mutual",k=new Set(["hello","world"])]])],regexp:/[a-z0-9]+/i,date:new Date("2023-03-14T11:16:24.879Z"),map:j,set:k},h[3]=h,j.set("self",j),k.add(k).add(h),m.self=m,m))()
62
+ ((h,j,k,m)=>(m={number:[0.9039984824241858,-0,NaN,1/0,-1/0],string:["hello world","\x3Cscript>Hello World\x3C/script>"],boolean:[!0,!1],null:null,undefined:void 0,bigint:9007199254740991n,array:h=[,,,,j=new Map([["hello","world"],["mutual",k=new Set(["hello","world"])]])],regexp:/[a-z0-9]+/i,date:new Date("2023-03-16T11:57:24.849Z"),map:j,set:k},h[3]=h,j.set("self",j),k.add(k).add(h),m.self=m,m))()
62
63
 
63
64
  // Formatted for readability
64
65
  ((h, j, k, m) => (m = {
65
- number: [0.5623457676854244, -0, NaN, 1 / 0, -1 / 0],
66
+ number: [0.9039984824241858, -0, NaN, 1 / 0, -1 / 0],
66
67
  string: ["hello world", "\x3Cscript>Hello World\x3C/script>"],
67
68
  boolean: [!0, !1],
68
69
  null: null,
@@ -73,7 +74,7 @@ Output (as a string):
73
74
  ["mutual", k = new Set(["hello", "world"])]
74
75
  ])],
75
76
  regexp: /[a-z0-9]+/i,
76
- date: new Date("2023-03-14T11:16:24.879Z"),
77
+ date: new Date("2023-03-16T11:57:24.849Z"),
77
78
  map: j,
78
79
  set: k
79
80
  }, h[3] = h, j.set("self", j), k.add(k).add(h), m.self = m, m))()
@@ -97,6 +98,7 @@ a.set('children', [c, d]);
97
98
  b.set('children', [c, d]);
98
99
 
99
100
  const result = serialize({ a, b, c, d });
101
+ console.log(result);
100
102
  ```
101
103
 
102
104
  Output (as a string):
@@ -133,9 +135,43 @@ const value = undefined;
133
135
  console.log(deserialize(serialize(value)) === value);
134
136
  ```
135
137
 
138
+ ## JSON
139
+
140
+ `serialize` and `deserialize` is great for server-to-client communication, but what about the other way? `serialize` may cause an [RCE if used as a payload for requests](https://huntr.dev/bounties/63f1ff91-48f3-4886-a179-103f1ddd8ff8). `seroval` includes `toJSON` and `fromJSON` as an alternative form of serialization.
141
+
142
+ First example above outputs the following json
143
+
144
+ ```js
145
+ import { toJSON } from 'seroval';
146
+ // ...
147
+ const result = toJSON(object);
148
+ console.log(result);
149
+ ```
150
+
151
+ ```json
152
+ {"t":{"t":8,"i":0,"d":{"k":["number","string","boolean","null","undefined","bigint","array","regexp","date","map","set","self"],"v":[{"t":7,"i":1,"a":[{"t":0,"s":0.7047255726239685},{"t":0,"s":"-0"},{"t":0,"s":null},{"t":0,"s":"1/0"},{"t":0,"s":"-1/0"}]},{"t":7,"i":2,"a":[{"t":0,"s":"\"hello world\""},{"t":0,"s":"\"\\x3Cscript>Hello World\\x3C/script>\""}]},{"t":7,"i":3,"a":[{"t":0,"s":"!0"},{"t":0,"s":"!1"}]},{"t":0,"s":null},{"t":0,"s":"void 0"},{"t":1,"s":"9007199254740991n"},{"t":7,"i":4,"a":[null,null,null,{"t":2,"i":4},{"t":6,"i":5,"d":{"k":[{"t":0,"s":"\"hello\""},{"t":0,"s":"\"self\""},{"t":0,"s":"\"mutual\""}],"v":[{"t":0,"s":"\"world\""},{"t":2,"i":5},{"t":5,"i":6,"a":[{"t":0,"s":"\"hello\""},{"t":0,"s":"\"world\""},{"t":2,"i":6},{"t":2,"i":4}]}],"s":3}}]},{"t":4,"i":7,"s":"/[a-z0-9]+/i"},{"t":3,"i":8,"s":"2023-03-16T12:01:29.836Z"},{"t":2,"i":5},{"t":2,"i":6},{"t":2,"i":0}],"s":12}},"r":0,"i":true,"f":8191,"m":[4,5,6,0]}
153
+ ```
154
+
155
+ Then you can feed it to `fromJSON`:
156
+
157
+ ```js
158
+ import { fromJSON } from 'seroval';
159
+
160
+ const revived = fromJSON(result);
161
+ ```
162
+
163
+ Alternatively, if you want to compile the JSON output to JS (like `deserialize`), you can use `compileJSON`
164
+
165
+ ```js
166
+ import { compileJSON, deserialize } from 'seroval';
167
+
168
+ const code = compileJSON(result);
169
+ const revived = deserialize(code);
170
+ ```
171
+
136
172
  ## Promise serialization
137
173
 
138
- `seroval` allows Promise serialization through `serializeAsync`.
174
+ `seroval` allows Promise serialization through `serializeAsync` and `toJSONAsync`.
139
175
 
140
176
  ```js
141
177
  import { serializeAsync } from 'seroval';
@@ -198,88 +234,78 @@ The following values are the only values accepted by `seroval`:
198
234
 
199
235
  ## Compat
200
236
 
201
- `serialize` and `serializeAsync` can accept a `{ target: string | string[] }` options. The `target` property decides what the serialization output would look like. The default target is `es2023`.
237
+ `serialize`, `serializeAsync`, `toJSON` and `toJSONAsync` can accept a `{ disabledFeatures: number }` option. The `disabledFeatures` defines how various code output of `serialize`, `serializeAsync` and `compileJSON`.
202
238
 
203
239
  ```js
204
- import { serialize } from 'seroval';
240
+ import { serialize, Feature } from 'seroval';
205
241
 
206
242
  const y = Object.create(null);
207
243
  y.self = y;
208
244
  y.example = 'Hello World';
209
245
 
210
- function serializeWithTarget(value, target) {
211
- console.log('Target is', target)
246
+ function serializeWithTarget(value, disabledFeatures) {
212
247
  const result = serialize(value, {
213
- target,
248
+ disabledFeatures,
214
249
  });
215
250
  console.log(result);
216
251
  }
217
252
 
218
- serializeWithTarget(y, 'es5');
219
- serializeWithTarget(y, 'es2023');
253
+ serializeWithTarget(y, Feature.ArrowFunction | Feature.ObjectAssign);
254
+ serializeWithTarget(y, 0);
220
255
  ```
221
256
 
222
- Output
223
-
224
- ```
225
- Target is es5
257
+ ```js
226
258
  (function(h){return (h=Object.create(null),h.self=h,h.example="Hello World",h)})()
227
- Target is es2023
228
259
  (h=>(h=Object.assign(Object.create(null),{example:"Hello World"}),h.self=h,h))()
229
260
  ```
230
261
 
231
- You can also combine targets:
262
+ `disabledFeatures` uses bit flags for faster checking, so if you need to disable multiple features, you can use the logical OR symbol (`|`).
263
+
264
+ Here's an `ES2017` flag:
232
265
 
233
266
  ```js
234
- serialize(value, {
235
- targets: ['chrome85', 'edge85'],
236
- });
237
- ```
267
+ import { serialize, Feature } from 'seroval';
238
268
 
239
- Supported runtimes:
240
-
241
- - `es`
242
- - Valid values are `es5`, `es6` and above (e.g. `es2020`).
243
- - Desktop
244
- - `chrome`
245
- - `edge`
246
- - `safari`
247
- - `firefox`
248
- - `opera`
249
- - Mobile
250
- - `ios`
251
- - `samsung`
252
- - Runtimes
253
- - `deno`
254
- - `node`
269
+ const ES2017FLAG =
270
+ Feature.AggregateError // ES2021
271
+ | Feature.BigInt // ES2020
272
+ | Feature.BigIntTypedArray // ES2020;
255
273
 
256
- > **Note**
257
- > Version for runtimes excluding `es` can use semver format (`major.minor.patch`) e.g. `chrome110`, `node0.12`
274
+ serialize(myValue, {
275
+ disabledFeatures: ES2017FLAG,
276
+ })
277
+ ```
258
278
 
259
- Feature flags and compat attempt:
279
+ By default, all feature flags are enabled. The following are the feature flags and their behavior when disabled:
260
280
 
261
- - `AggregateError`
281
+ - [`AggregateError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError)
262
282
  - Compiles down to `Error` instead.
263
- - `Array.prototype.values`
264
- - Used for iterables, uses `Symbol.iterator` instead.
265
- - Arrow functions
266
- - Uses function expressions for top-level, and either method shorthands or function expressions for iterables.
267
- - `BigInt`
268
- - Throws when attempted to use, includes `BigInt64Array` and `BigUint64Array`
269
- - `Map`
283
+ - [`ArrayPrototypeValues`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values)
284
+ - Used for iterables, uses `Symbol.iterator` instead (if `SymbolIterator` is not set).
285
+ - [`ArrowFunction`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
286
+ - Uses function expressions for top-level and for deferred Promise values
287
+ - method shorthands (if `MethodShortand` is not set) or function expressions for iterables.
288
+ - [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)
289
+ - Throws when attempted to use, includes `BigIntTypedArray`
290
+ - [`ErrorPrototypeStack`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack)
291
+ - Skipped when detected.
292
+ - [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
270
293
  - Throws when attempted to use.
271
- - Method shorthands
294
+ - [`MethodShorthand`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions)
272
295
  - Uses function expressions instead.
273
- - `Object.assign`
296
+ - [`ObjectAssign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
274
297
  - Uses manual object assignments instead.
275
- - `Promise`
276
- - Throws when attempted to use, specially in `serializeAsync`.
277
- - `Set`
298
+ - [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
299
+ - Throws when attempted to use in `serializeAsync` and `toJSONAsync`.
300
+ - [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)
278
301
  - Throws when attempted to use.
279
- - `Symbol.iterator`
302
+ - [`SymbolIterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator)
280
303
  - Throws when attempted to use.
281
- - `TypedArray`
304
+ - [`TypedArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)
282
305
  - Throws when attempted to use.
306
+ - [`BigIntTypedArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt64Array)
307
+ - Throws when attempted to use
308
+ - Also throws if `BigInt` is disabled.
283
309
 
284
310
  ## Sponsors
285
311