seroval 1.6.1 → 1.6.3

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/dist/dev/index.js CHANGED
@@ -196,6 +196,101 @@ function deserializeString(str) {
196
196
  return str.replace(/(\\\\|\\"|\\n|\\r|\\b|\\t|\\f|\\u2028|\\u2029|\\x3C)/g, deserializeReplacer);
197
197
  }
198
198
  //#endregion
199
+ //#region src/core/errors.ts
200
+ const { toString: objectToString } = Object.prototype;
201
+ function getErrorMessageDev(type, cause) {
202
+ if (cause instanceof Error) return `Seroval caught an error during the ${type} process.
203
+
204
+ ${cause.name}
205
+ ${cause.message}
206
+
207
+ - For more information, please check the "cause" property of this error.
208
+ - If you believe this is an error in Seroval, please submit an issue at https://github.com/lxsmnsyc/seroval/issues/new`;
209
+ return `Seroval caught an error during the ${type} process.
210
+
211
+ "${objectToString.call(cause)}"
212
+
213
+ For more information, please check the "cause" property of this error.`;
214
+ }
215
+ const getErrorMessage = (type, cause) => getErrorMessageDev(type, cause);
216
+ var SerovalError = class extends Error {
217
+ constructor(type, cause) {
218
+ super(getErrorMessage(type, cause));
219
+ this.cause = cause;
220
+ }
221
+ };
222
+ var SerovalParserError = class extends SerovalError {
223
+ constructor(cause) {
224
+ super("parsing", cause);
225
+ }
226
+ };
227
+ var SerovalSerializationError = class extends SerovalError {
228
+ constructor(cause) {
229
+ super("serialization", cause);
230
+ }
231
+ };
232
+ var SerovalDeserializationError = class extends SerovalError {
233
+ constructor(cause) {
234
+ super("deserialization", cause);
235
+ }
236
+ };
237
+ var SerovalUnsupportedTypeError = class extends Error {
238
+ constructor(value) {
239
+ super(`The value ${objectToString.call(value)} of type "${typeof value}" cannot be parsed/serialized.
240
+
241
+ There are few workarounds for this problem:
242
+ - Transform the value in a way that it can be serialized.
243
+ - If the reference is present on multiple runtimes (isomorphic), you can use the Reference API to map the references.`);
244
+ this.value = value;
245
+ }
246
+ };
247
+ var SerovalUnsupportedNodeError = class extends Error {
248
+ constructor(node) {
249
+ super("Unsupported node type \"" + node.t + "\".");
250
+ }
251
+ };
252
+ var SerovalMissingPluginError = class extends Error {
253
+ constructor(tag) {
254
+ super("Missing plugin for tag \"" + tag + "\".");
255
+ }
256
+ };
257
+ var SerovalMissingInstanceError = class extends Error {
258
+ constructor(tag) {
259
+ super("Missing \"" + tag + "\" instance.");
260
+ }
261
+ };
262
+ var SerovalMissingReferenceError = class extends Error {
263
+ constructor(value) {
264
+ super("Missing reference for the value \"" + objectToString.call(value) + "\" of type \"" + typeof value + "\"");
265
+ this.value = value;
266
+ }
267
+ };
268
+ var SerovalMissingReferenceForIdError = class extends Error {
269
+ constructor(id) {
270
+ super("Missing reference for id \"" + serializeString(id) + "\"");
271
+ }
272
+ };
273
+ var SerovalUnknownTypedArrayError = class extends Error {
274
+ constructor(name) {
275
+ super("Unknown TypedArray \"" + name + "\"");
276
+ }
277
+ };
278
+ var SerovalMalformedNodeError = class extends Error {
279
+ constructor(node) {
280
+ super("Malformed node type \"" + node.t + "\".");
281
+ }
282
+ };
283
+ var SerovalConflictedNodeIdError = class extends Error {
284
+ constructor(node) {
285
+ super("Conflicted node id \"" + node.i + "\".");
286
+ }
287
+ };
288
+ var SerovalDepthLimitError = class extends Error {
289
+ constructor(limit) {
290
+ super("Depth limit of " + limit + " reached");
291
+ }
292
+ };
293
+ //#endregion
199
294
  //#region src/core/keys.ts
200
295
  const REFERENCES_KEY = "__SEROVAL_REFS__";
201
296
  const GLOBAL_CONTEXT_R = `self.\$R`;
@@ -272,14 +367,16 @@ function getErrorOptions(error, features) {
272
367
  const names = Object.getOwnPropertyNames(error);
273
368
  for (let i = 0, len = names.length, name; i < len; i++) {
274
369
  name = names[i];
275
- if (name !== "name" && name !== "message") if (name === "stack") {
276
- if (features & 4) {
370
+ if (name !== "name" && name !== "message") {
371
+ if (name === "stack") {
372
+ if (features & 4) {
373
+ options = options || {};
374
+ options[name] = error[name];
375
+ }
376
+ } else {
277
377
  options = options || {};
278
378
  options[name] = error[name];
279
379
  }
280
- } else {
281
- options = options || {};
282
- options[name] = error[name];
283
380
  }
284
381
  }
285
382
  return options;
@@ -337,13 +434,17 @@ function createArrayNode(id, current, parsedItems) {
337
434
  function createBoxedNode(id, boxed) {
338
435
  return createSerovalNode(21, id, void 0, void 0, void 0, void 0, void 0, void 0, boxed, void 0, void 0, void 0);
339
436
  }
437
+ const MAX_TYPED_ARRAY_LENGTH = 1e6;
340
438
  function createTypedArrayNode(id, current, buffer) {
439
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
341
440
  return createSerovalNode(15, id, void 0, current.constructor.name, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.length);
342
441
  }
343
442
  function createBigIntTypedArrayNode(id, current, buffer) {
443
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
344
444
  return createSerovalNode(16, id, void 0, current.constructor.name, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.length);
345
445
  }
346
446
  function createDataViewNode(id, current, buffer) {
447
+ if (current.byteLength > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
347
448
  return createSerovalNode(20, id, void 0, void 0, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.byteLength);
348
449
  }
349
450
  function createErrorNode(id, current, options) {
@@ -377,101 +478,6 @@ function createSequenceNode(id, sequence, throwAt, doneAt) {
377
478
  return createSerovalNode(35, id, throwAt, void 0, void 0, void 0, void 0, sequence, void 0, void 0, void 0, doneAt);
378
479
  }
379
480
  //#endregion
380
- //#region src/core/errors.ts
381
- const { toString: objectToString } = Object.prototype;
382
- function getErrorMessageDev(type, cause) {
383
- if (cause instanceof Error) return `Seroval caught an error during the ${type} process.
384
-
385
- ${cause.name}
386
- ${cause.message}
387
-
388
- - For more information, please check the "cause" property of this error.
389
- - If you believe this is an error in Seroval, please submit an issue at https://github.com/lxsmnsyc/seroval/issues/new`;
390
- return `Seroval caught an error during the ${type} process.
391
-
392
- "${objectToString.call(cause)}"
393
-
394
- For more information, please check the "cause" property of this error.`;
395
- }
396
- const getErrorMessage = (type, cause) => getErrorMessageDev(type, cause);
397
- var SerovalError = class extends Error {
398
- constructor(type, cause) {
399
- super(getErrorMessage(type, cause));
400
- this.cause = cause;
401
- }
402
- };
403
- var SerovalParserError = class extends SerovalError {
404
- constructor(cause) {
405
- super("parsing", cause);
406
- }
407
- };
408
- var SerovalSerializationError = class extends SerovalError {
409
- constructor(cause) {
410
- super("serialization", cause);
411
- }
412
- };
413
- var SerovalDeserializationError = class extends SerovalError {
414
- constructor(cause) {
415
- super("deserialization", cause);
416
- }
417
- };
418
- var SerovalUnsupportedTypeError = class extends Error {
419
- constructor(value) {
420
- super(`The value ${objectToString.call(value)} of type "${typeof value}" cannot be parsed/serialized.
421
-
422
- There are few workarounds for this problem:
423
- - Transform the value in a way that it can be serialized.
424
- - If the reference is present on multiple runtimes (isomorphic), you can use the Reference API to map the references.`);
425
- this.value = value;
426
- }
427
- };
428
- var SerovalUnsupportedNodeError = class extends Error {
429
- constructor(node) {
430
- super("Unsupported node type \"" + node.t + "\".");
431
- }
432
- };
433
- var SerovalMissingPluginError = class extends Error {
434
- constructor(tag) {
435
- super("Missing plugin for tag \"" + tag + "\".");
436
- }
437
- };
438
- var SerovalMissingInstanceError = class extends Error {
439
- constructor(tag) {
440
- super("Missing \"" + tag + "\" instance.");
441
- }
442
- };
443
- var SerovalMissingReferenceError = class extends Error {
444
- constructor(value) {
445
- super("Missing reference for the value \"" + objectToString.call(value) + "\" of type \"" + typeof value + "\"");
446
- this.value = value;
447
- }
448
- };
449
- var SerovalMissingReferenceForIdError = class extends Error {
450
- constructor(id) {
451
- super("Missing reference for id \"" + serializeString(id) + "\"");
452
- }
453
- };
454
- var SerovalUnknownTypedArrayError = class extends Error {
455
- constructor(name) {
456
- super("Unknown TypedArray \"" + name + "\"");
457
- }
458
- };
459
- var SerovalMalformedNodeError = class extends Error {
460
- constructor(node) {
461
- super("Malformed node type \"" + node.t + "\".");
462
- }
463
- };
464
- var SerovalConflictedNodeIdError = class extends Error {
465
- constructor(node) {
466
- super("Conflicted node id \"" + node.i + "\".");
467
- }
468
- };
469
- var SerovalDepthLimitError = class extends Error {
470
- constructor(limit) {
471
- super("Depth limit of " + limit + " reached");
472
- }
473
- };
474
- //#endregion
475
481
  //#region src/core/opaque-reference.ts
476
482
  /**
477
483
  * An opaque reference allows hiding values from the serializer.
@@ -1059,7 +1065,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1059
1065
  case DataView: return parseDataView$1(ctx, depth, id, current);
1060
1066
  case Map: return parseMap$1(ctx, depth, id, current);
1061
1067
  case Set: return parseSet$1(ctx, depth, id, current);
1062
- default: break;
1063
1068
  }
1064
1069
  if (currentClass === Promise || current instanceof Promise) return parsePromise$1(ctx, depth, id, current);
1065
1070
  const currentFeatures = ctx.base.features;
@@ -1067,7 +1072,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1067
1072
  if (currentFeatures & 16) switch (currentClass) {
1068
1073
  case BigInt64Array:
1069
1074
  case BigUint64Array: return parseBigIntTypedArray$1(ctx, depth, id, current);
1070
- default: break;
1071
1075
  }
1072
1076
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError$1(ctx, depth, id, current);
1073
1077
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -1079,7 +1083,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1079
1083
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
1080
1084
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
1081
1085
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
1082
- default: break;
1083
1086
  }
1084
1087
  if (current instanceof Error) return parseError$1(ctx, depth, id, current);
1085
1088
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject$1(ctx, depth, id, current, !!currentClass);
@@ -1242,6 +1245,9 @@ function guardIndexedValue(ctx, id) {
1242
1245
  });
1243
1246
  if (ctx.refs.has(id)) throw new Error("Conflicted ref id: " + id);
1244
1247
  }
1248
+ function isThennable(value) {
1249
+ return !!value && typeof value === "object" && "then" in value && typeof value.then === "function";
1250
+ }
1245
1251
  function assignIndexedValueVanilla(ctx, id, value) {
1246
1252
  guardIndexedValue(ctx.base, id);
1247
1253
  if (ctx.state.marked.has(id)) ctx.base.refs.set(id, value);
@@ -1376,14 +1382,14 @@ function deserializeTypedArray(ctx, depth, node) {
1376
1382
  const construct = getTypedArrayConstructor(node.c);
1377
1383
  const source = deserialize$1(ctx, depth, node.f);
1378
1384
  const offset = (_node$b = node.b) !== null && _node$b !== void 0 ? _node$b : 0;
1379
- if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1385
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1380
1386
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1381
1387
  }
1382
1388
  function deserializeDataView(ctx, depth, node) {
1383
1389
  var _node$b2;
1384
1390
  const source = deserialize$1(ctx, depth, node.f);
1385
1391
  const offset = (_node$b2 = node.b) !== null && _node$b2 !== void 0 ? _node$b2 : 0;
1386
- if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1392
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1387
1393
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1388
1394
  }
1389
1395
  function deserializeDictionary(ctx, depth, node, result) {
@@ -1404,6 +1410,7 @@ function deserializePromise(ctx, depth, node) {
1404
1410
  const deferred = PROMISE_CONSTRUCTOR();
1405
1411
  const result = assignIndexedValue$1(ctx, node.i, deferred.p);
1406
1412
  const deserialized = deserialize$1(ctx, depth, node.f);
1413
+ if (isThennable(deserialized)) throw new SerovalMalformedNodeError(node.f);
1407
1414
  if (node.s) deferred.s(deserialized);
1408
1415
  else deferred.f(deserialized);
1409
1416
  return result;
@@ -1427,20 +1434,14 @@ function deserializePromiseConstructor(ctx, node) {
1427
1434
  assignNodeType(ctx, node.s, 22);
1428
1435
  return value;
1429
1436
  }
1430
- function deserializePromiseResolve(ctx, depth, node) {
1431
- const deferred = ctx.base.refs.get(node.i);
1432
- if (deferred) {
1433
- validateNodeType(ctx, node, node.i, 22);
1434
- deferred.s(deserialize$1(ctx, depth, node.a[1]));
1435
- return;
1436
- }
1437
- throw new SerovalMissingInstanceError("Promise");
1438
- }
1439
- function deserializePromiseReject(ctx, depth, node) {
1437
+ function deserializePromiseFulfill(ctx, depth, node) {
1440
1438
  const deferred = ctx.base.refs.get(node.i);
1441
1439
  if (deferred) {
1442
1440
  validateNodeType(ctx, node, node.i, 22);
1443
- deferred.f(deserialize$1(ctx, depth, node.a[1]));
1441
+ const deserialized = deserialize$1(ctx, depth, node.a[1]);
1442
+ if (isThennable(deserialized)) throw new SerovalMalformedNodeError(node.a[1]);
1443
+ if (node.t === 23) deferred.s(deserialized);
1444
+ else deferred.f(deserialized);
1444
1445
  return;
1445
1446
  }
1446
1447
  throw new SerovalMissingInstanceError("Promise");
@@ -1529,8 +1530,8 @@ function deserialize$1(ctx, depth, node) {
1529
1530
  case 21: return deserializeBoxed(ctx, depth, node);
1530
1531
  case 25: return deserializePlugin(ctx, depth, node);
1531
1532
  case 22: return deserializePromiseConstructor(ctx, node);
1532
- case 23: return deserializePromiseResolve(ctx, depth, node);
1533
- case 24: return deserializePromiseReject(ctx, depth, node);
1533
+ case 23:
1534
+ case 24: return deserializePromiseFulfill(ctx, depth, node);
1534
1535
  case 28: return deserializeIteratorFactoryInstance(ctx, depth, node);
1535
1536
  case 30: return deserializeAsyncIteratorFactoryInstance(ctx, depth, node);
1536
1537
  case 31: return deserializeStreamConstructor(ctx, depth, node);
@@ -1923,9 +1924,10 @@ function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value)
1923
1924
  const serialized = serialize$1(ctx, value);
1924
1925
  const check = Number(key);
1925
1926
  const isIdentifier = check >= 0 && check.toString() === key || isValidIdentifier(key);
1926
- if (isIndexedValueInStack(base, value)) if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1927
- else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1928
- else {
1927
+ if (isIndexedValueInStack(base, value)) {
1928
+ if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1929
+ else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1930
+ } else {
1929
1931
  const parentAssignment = base.assignments;
1930
1932
  base.assignments = mainAssignments;
1931
1933
  if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
@@ -2552,7 +2554,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2552
2554
  case DataView: return parseDataView(ctx, depth, id, current);
2553
2555
  case Map: return parseMap(ctx, depth, id, current);
2554
2556
  case Set: return parseSet(ctx, depth, id, current);
2555
- default: break;
2556
2557
  }
2557
2558
  if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
2558
2559
  const currentFeatures = ctx.base.features;
@@ -2560,7 +2561,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2560
2561
  if (currentFeatures & 16) switch (currentClass) {
2561
2562
  case BigInt64Array:
2562
2563
  case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
2563
- default: break;
2564
2564
  }
2565
2565
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
2566
2566
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -2572,7 +2572,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2572
2572
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
2573
2573
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
2574
2574
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
2575
- default: break;
2576
2575
  }
2577
2576
  if (current instanceof Error) return parseError(ctx, depth, id, current);
2578
2577
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject(ctx, depth, id, current, !!currentClass);