seroval 0.4.0-alpha.8 → 0.4.0
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 +81 -55
- package/dist/cjs/development/index.cjs +999 -831
- package/dist/cjs/development/index.cjs.map +4 -4
- package/dist/cjs/production/index.cjs +2 -2
- package/dist/esm/development/index.mjs +999 -831
- package/dist/esm/development/index.mjs.map +4 -4
- package/dist/esm/production/index.mjs +2 -2
- package/dist/types/compat.d.ts +10 -25
- package/dist/types/context.d.ts +17 -15
- package/dist/types/index.d.ts +2 -1
- package/dist/types/tree/primitives.d.ts +17 -0
- package/dist/types/tree/serialize.d.ts +1 -1
- package/dist/types/tree/shared.d.ts +4 -8
- package/dist/types/tree/types.d.ts +108 -59
- package/dist/types/types.d.ts +3 -2
- package/package.json +2 -2
- package/src/compat.ts +10 -246
- package/src/context.ts +37 -26
- package/src/index.ts +33 -41
- package/src/quote.ts +1 -1
- package/src/tree/async.ts +362 -163
- package/src/tree/primitives.ts +150 -0
- package/src/tree/serialize.ts +308 -282
- package/src/tree/shared.ts +43 -119
- package/src/tree/sync.ts +295 -146
- package/src/tree/types.ts +143 -65
- package/src/types.ts +4 -1
- package/dist/types/checks.d.ts +0 -5
- package/src/checks.ts +0 -40
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.
|
|
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.
|
|
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-
|
|
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 `
|
|
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,
|
|
211
|
-
console.log('Target is', target)
|
|
246
|
+
function serializeWithTarget(value, disabledFeatures) {
|
|
212
247
|
const result = serialize(value, {
|
|
213
|
-
|
|
248
|
+
disabledFeatures,
|
|
214
249
|
});
|
|
215
250
|
console.log(result);
|
|
216
251
|
}
|
|
217
252
|
|
|
218
|
-
serializeWithTarget(y,
|
|
219
|
-
serializeWithTarget(y,
|
|
253
|
+
serializeWithTarget(y, Feature.ArrowFunction | Feature.ObjectAssign);
|
|
254
|
+
serializeWithTarget(y, 0);
|
|
220
255
|
```
|
|
221
256
|
|
|
222
|
-
|
|
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
|
-
|
|
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
|
|
235
|
-
targets: ['chrome85', 'edge85'],
|
|
236
|
-
});
|
|
237
|
-
```
|
|
267
|
+
import { serialize, Feature } from 'seroval';
|
|
238
268
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
-
|
|
257
|
-
|
|
274
|
+
serialize(myValue, {
|
|
275
|
+
disabledFeatures: ES2017FLAG,
|
|
276
|
+
})
|
|
277
|
+
```
|
|
258
278
|
|
|
259
|
-
|
|
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
|
-
- `
|
|
264
|
-
- Used for iterables, uses `Symbol.iterator` instead.
|
|
265
|
-
-
|
|
266
|
-
- Uses function expressions for top-level
|
|
267
|
-
- `
|
|
268
|
-
|
|
269
|
-
- `
|
|
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
|
-
-
|
|
294
|
+
- [`MethodShorthand`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions)
|
|
272
295
|
- Uses function expressions instead.
|
|
273
|
-
- `Object
|
|
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
|
|
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
|
|
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
|
|