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/index.js CHANGED
@@ -196,6 +196,94 @@ 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
+ const STEP_ERROR_CODES = {
202
+ parsing: 1,
203
+ serialization: 2,
204
+ deserialization: 3
205
+ };
206
+ function getErrorMessageProd(type) {
207
+ return `Seroval Error (step: ${STEP_ERROR_CODES[type]})`;
208
+ }
209
+ const getErrorMessage = (type, cause) => getErrorMessageProd(type);
210
+ var SerovalError = class extends Error {
211
+ constructor(type, cause) {
212
+ super(getErrorMessage(type, cause));
213
+ this.cause = cause;
214
+ }
215
+ };
216
+ var SerovalParserError = class extends SerovalError {
217
+ constructor(cause) {
218
+ super("parsing", cause);
219
+ }
220
+ };
221
+ var SerovalSerializationError = class extends SerovalError {
222
+ constructor(cause) {
223
+ super("serialization", cause);
224
+ }
225
+ };
226
+ var SerovalDeserializationError = class extends SerovalError {
227
+ constructor(cause) {
228
+ super("deserialization", cause);
229
+ }
230
+ };
231
+ function getSpecificErrorMessage(code) {
232
+ return `Seroval Error (specific: ${code})`;
233
+ }
234
+ var SerovalUnsupportedTypeError = class extends Error {
235
+ constructor(value) {
236
+ super(getSpecificErrorMessage(1));
237
+ this.value = value;
238
+ }
239
+ };
240
+ var SerovalUnsupportedNodeError = class extends Error {
241
+ constructor(node) {
242
+ super(getSpecificErrorMessage(2));
243
+ }
244
+ };
245
+ var SerovalMissingPluginError = class extends Error {
246
+ constructor(tag) {
247
+ super(getSpecificErrorMessage(3));
248
+ }
249
+ };
250
+ var SerovalMissingInstanceError = class extends Error {
251
+ constructor(tag) {
252
+ super(getSpecificErrorMessage(4));
253
+ }
254
+ };
255
+ var SerovalMissingReferenceError = class extends Error {
256
+ constructor(value) {
257
+ super(getSpecificErrorMessage(5));
258
+ this.value = value;
259
+ }
260
+ };
261
+ var SerovalMissingReferenceForIdError = class extends Error {
262
+ constructor(id) {
263
+ super(getSpecificErrorMessage(6));
264
+ }
265
+ };
266
+ var SerovalUnknownTypedArrayError = class extends Error {
267
+ constructor(name) {
268
+ super(getSpecificErrorMessage(7));
269
+ }
270
+ };
271
+ var SerovalMalformedNodeError = class extends Error {
272
+ constructor(node) {
273
+ super(getSpecificErrorMessage(8));
274
+ }
275
+ };
276
+ var SerovalConflictedNodeIdError = class extends Error {
277
+ constructor(node) {
278
+ super(getSpecificErrorMessage(9));
279
+ }
280
+ };
281
+ var SerovalDepthLimitError = class extends Error {
282
+ constructor(limit) {
283
+ super(getSpecificErrorMessage(9));
284
+ }
285
+ };
286
+ //#endregion
199
287
  //#region src/core/keys.ts
200
288
  const REFERENCES_KEY = "__SEROVAL_REFS__";
201
289
  const GLOBAL_CONTEXT_R = `self.\$R`;
@@ -272,14 +360,16 @@ function getErrorOptions(error, features) {
272
360
  const names = Object.getOwnPropertyNames(error);
273
361
  for (let i = 0, len = names.length, name; i < len; i++) {
274
362
  name = names[i];
275
- if (name !== "name" && name !== "message") if (name === "stack") {
276
- if (features & 4) {
363
+ if (name !== "name" && name !== "message") {
364
+ if (name === "stack") {
365
+ if (features & 4) {
366
+ options = options || {};
367
+ options[name] = error[name];
368
+ }
369
+ } else {
277
370
  options = options || {};
278
371
  options[name] = error[name];
279
372
  }
280
- } else {
281
- options = options || {};
282
- options[name] = error[name];
283
373
  }
284
374
  }
285
375
  return options;
@@ -337,13 +427,17 @@ function createArrayNode(id, current, parsedItems) {
337
427
  function createBoxedNode(id, boxed) {
338
428
  return createSerovalNode(21, id, void 0, void 0, void 0, void 0, void 0, void 0, boxed, void 0, void 0, void 0);
339
429
  }
430
+ const MAX_TYPED_ARRAY_LENGTH = 1e6;
340
431
  function createTypedArrayNode(id, current, buffer) {
432
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
341
433
  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
434
  }
343
435
  function createBigIntTypedArrayNode(id, current, buffer) {
436
+ if (current.length > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
344
437
  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
438
  }
346
439
  function createDataViewNode(id, current, buffer) {
440
+ if (current.byteLength > MAX_TYPED_ARRAY_LENGTH) throw new SerovalUnsupportedTypeError(current);
347
441
  return createSerovalNode(20, id, void 0, void 0, void 0, void 0, void 0, void 0, buffer, current.byteOffset, void 0, current.byteLength);
348
442
  }
349
443
  function createErrorNode(id, current, options) {
@@ -377,94 +471,6 @@ function createSequenceNode(id, sequence, throwAt, doneAt) {
377
471
  return createSerovalNode(35, id, throwAt, void 0, void 0, void 0, void 0, sequence, void 0, void 0, void 0, doneAt);
378
472
  }
379
473
  //#endregion
380
- //#region src/core/errors.ts
381
- const { toString: objectToString } = Object.prototype;
382
- const STEP_ERROR_CODES = {
383
- parsing: 1,
384
- serialization: 2,
385
- deserialization: 3
386
- };
387
- function getErrorMessageProd(type) {
388
- return `Seroval Error (step: ${STEP_ERROR_CODES[type]})`;
389
- }
390
- const getErrorMessage = (type, cause) => getErrorMessageProd(type);
391
- var SerovalError = class extends Error {
392
- constructor(type, cause) {
393
- super(getErrorMessage(type, cause));
394
- this.cause = cause;
395
- }
396
- };
397
- var SerovalParserError = class extends SerovalError {
398
- constructor(cause) {
399
- super("parsing", cause);
400
- }
401
- };
402
- var SerovalSerializationError = class extends SerovalError {
403
- constructor(cause) {
404
- super("serialization", cause);
405
- }
406
- };
407
- var SerovalDeserializationError = class extends SerovalError {
408
- constructor(cause) {
409
- super("deserialization", cause);
410
- }
411
- };
412
- function getSpecificErrorMessage(code) {
413
- return `Seroval Error (specific: ${code})`;
414
- }
415
- var SerovalUnsupportedTypeError = class extends Error {
416
- constructor(value) {
417
- super(getSpecificErrorMessage(1));
418
- this.value = value;
419
- }
420
- };
421
- var SerovalUnsupportedNodeError = class extends Error {
422
- constructor(node) {
423
- super(getSpecificErrorMessage(2));
424
- }
425
- };
426
- var SerovalMissingPluginError = class extends Error {
427
- constructor(tag) {
428
- super(getSpecificErrorMessage(3));
429
- }
430
- };
431
- var SerovalMissingInstanceError = class extends Error {
432
- constructor(tag) {
433
- super(getSpecificErrorMessage(4));
434
- }
435
- };
436
- var SerovalMissingReferenceError = class extends Error {
437
- constructor(value) {
438
- super(getSpecificErrorMessage(5));
439
- this.value = value;
440
- }
441
- };
442
- var SerovalMissingReferenceForIdError = class extends Error {
443
- constructor(id) {
444
- super(getSpecificErrorMessage(6));
445
- }
446
- };
447
- var SerovalUnknownTypedArrayError = class extends Error {
448
- constructor(name) {
449
- super(getSpecificErrorMessage(7));
450
- }
451
- };
452
- var SerovalMalformedNodeError = class extends Error {
453
- constructor(node) {
454
- super(getSpecificErrorMessage(8));
455
- }
456
- };
457
- var SerovalConflictedNodeIdError = class extends Error {
458
- constructor(node) {
459
- super(getSpecificErrorMessage(9));
460
- }
461
- };
462
- var SerovalDepthLimitError = class extends Error {
463
- constructor(limit) {
464
- super(getSpecificErrorMessage(9));
465
- }
466
- };
467
- //#endregion
468
474
  //#region src/core/opaque-reference.ts
469
475
  /**
470
476
  * An opaque reference allows hiding values from the serializer.
@@ -1052,7 +1058,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1052
1058
  case DataView: return parseDataView$1(ctx, depth, id, current);
1053
1059
  case Map: return parseMap$1(ctx, depth, id, current);
1054
1060
  case Set: return parseSet$1(ctx, depth, id, current);
1055
- default: break;
1056
1061
  }
1057
1062
  if (currentClass === Promise || current instanceof Promise) return parsePromise$1(ctx, depth, id, current);
1058
1063
  const currentFeatures = ctx.base.features;
@@ -1060,7 +1065,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1060
1065
  if (currentFeatures & 16) switch (currentClass) {
1061
1066
  case BigInt64Array:
1062
1067
  case BigUint64Array: return parseBigIntTypedArray$1(ctx, depth, id, current);
1063
- default: break;
1064
1068
  }
1065
1069
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError$1(ctx, depth, id, current);
1066
1070
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -1072,7 +1076,6 @@ async function parseObjectAsync(ctx, depth, id, current) {
1072
1076
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
1073
1077
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
1074
1078
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
1075
- default: break;
1076
1079
  }
1077
1080
  if (current instanceof Error) return parseError$1(ctx, depth, id, current);
1078
1081
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject$1(ctx, depth, id, current, !!currentClass);
@@ -1235,6 +1238,9 @@ function guardIndexedValue(ctx, id) {
1235
1238
  });
1236
1239
  if (ctx.refs.has(id)) throw new Error("Conflicted ref id: " + id);
1237
1240
  }
1241
+ function isThennable(value) {
1242
+ return !!value && typeof value === "object" && "then" in value && typeof value.then === "function";
1243
+ }
1238
1244
  function assignIndexedValueVanilla(ctx, id, value) {
1239
1245
  guardIndexedValue(ctx.base, id);
1240
1246
  if (ctx.state.marked.has(id)) ctx.base.refs.set(id, value);
@@ -1369,14 +1375,14 @@ function deserializeTypedArray(ctx, depth, node) {
1369
1375
  const construct = getTypedArrayConstructor(node.c);
1370
1376
  const source = deserialize$1(ctx, depth, node.f);
1371
1377
  const offset = (_node$b = node.b) !== null && _node$b !== void 0 ? _node$b : 0;
1372
- if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1378
+ if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1373
1379
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1374
1380
  }
1375
1381
  function deserializeDataView(ctx, depth, node) {
1376
1382
  var _node$b2;
1377
1383
  const source = deserialize$1(ctx, depth, node.f);
1378
1384
  const offset = (_node$b2 = node.b) !== null && _node$b2 !== void 0 ? _node$b2 : 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 DataView(source, offset, node.l));
1381
1387
  }
1382
1388
  function deserializeDictionary(ctx, depth, node, result) {
@@ -1397,6 +1403,7 @@ function deserializePromise(ctx, depth, node) {
1397
1403
  const deferred = PROMISE_CONSTRUCTOR();
1398
1404
  const result = assignIndexedValue$1(ctx, node.i, deferred.p);
1399
1405
  const deserialized = deserialize$1(ctx, depth, node.f);
1406
+ if (isThennable(deserialized)) throw new SerovalMalformedNodeError(node.f);
1400
1407
  if (node.s) deferred.s(deserialized);
1401
1408
  else deferred.f(deserialized);
1402
1409
  return result;
@@ -1420,20 +1427,14 @@ function deserializePromiseConstructor(ctx, node) {
1420
1427
  assignNodeType(ctx, node.s, 22);
1421
1428
  return value;
1422
1429
  }
1423
- function deserializePromiseResolve(ctx, depth, node) {
1430
+ function deserializePromiseFulfill(ctx, depth, node) {
1424
1431
  const deferred = ctx.base.refs.get(node.i);
1425
1432
  if (deferred) {
1426
1433
  validateNodeType(ctx, node, node.i, 22);
1427
- deferred.s(deserialize$1(ctx, depth, node.a[1]));
1428
- return;
1429
- }
1430
- throw new SerovalMissingInstanceError("Promise");
1431
- }
1432
- function deserializePromiseReject(ctx, depth, node) {
1433
- const deferred = ctx.base.refs.get(node.i);
1434
- if (deferred) {
1435
- validateNodeType(ctx, node, node.i, 22);
1436
- deferred.f(deserialize$1(ctx, depth, node.a[1]));
1434
+ const deserialized = deserialize$1(ctx, depth, node.a[1]);
1435
+ if (isThennable(deserialized)) throw new SerovalMalformedNodeError(node.a[1]);
1436
+ if (node.t === 23) deferred.s(deserialized);
1437
+ else deferred.f(deserialized);
1437
1438
  return;
1438
1439
  }
1439
1440
  throw new SerovalMissingInstanceError("Promise");
@@ -1522,8 +1523,8 @@ function deserialize$1(ctx, depth, node) {
1522
1523
  case 21: return deserializeBoxed(ctx, depth, node);
1523
1524
  case 25: return deserializePlugin(ctx, depth, node);
1524
1525
  case 22: return deserializePromiseConstructor(ctx, node);
1525
- case 23: return deserializePromiseResolve(ctx, depth, node);
1526
- case 24: return deserializePromiseReject(ctx, depth, node);
1526
+ case 23:
1527
+ case 24: return deserializePromiseFulfill(ctx, depth, node);
1527
1528
  case 28: return deserializeIteratorFactoryInstance(ctx, depth, node);
1528
1529
  case 30: return deserializeAsyncIteratorFactoryInstance(ctx, depth, node);
1529
1530
  case 31: return deserializeStreamConstructor(ctx, depth, node);
@@ -1916,9 +1917,10 @@ function serializeStringKeyAssignment(ctx, source, mainAssignments, key, value)
1916
1917
  const serialized = serialize$1(ctx, value);
1917
1918
  const check = Number(key);
1918
1919
  const isIdentifier = check >= 0 && check.toString() === key || isValidIdentifier(key);
1919
- if (isIndexedValueInStack(base, value)) if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1920
- else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1921
- else {
1920
+ if (isIndexedValueInStack(base, value)) {
1921
+ if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
1922
+ else createArrayAssign(ctx, source.i, isIdentifier ? key : "\"" + key + "\"", serialized);
1923
+ } else {
1922
1924
  const parentAssignment = base.assignments;
1923
1925
  base.assignments = mainAssignments;
1924
1926
  if (isIdentifier && check !== check) createObjectAssign(ctx, source.i, key, serialized);
@@ -2545,7 +2547,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2545
2547
  case DataView: return parseDataView(ctx, depth, id, current);
2546
2548
  case Map: return parseMap(ctx, depth, id, current);
2547
2549
  case Set: return parseSet(ctx, depth, id, current);
2548
- default: break;
2549
2550
  }
2550
2551
  if (currentClass === Promise || current instanceof Promise) return parsePromise(ctx, depth, id, current);
2551
2552
  const currentFeatures = ctx.base.features;
@@ -2553,7 +2554,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2553
2554
  if (currentFeatures & 16) switch (currentClass) {
2554
2555
  case BigInt64Array:
2555
2556
  case BigUint64Array: return parseBigIntTypedArray(ctx, depth, id, current);
2556
- default: break;
2557
2557
  }
2558
2558
  if (currentFeatures & 1 && typeof AggregateError !== "undefined" && (currentClass === AggregateError || current instanceof AggregateError)) return parseAggregateError(ctx, depth, id, current);
2559
2559
  if (currentFeatures & 64 && typeof Temporal !== "undefined") switch (currentClass) {
@@ -2565,7 +2565,6 @@ function parseObjectPhase2(ctx, depth, id, current, currentClass) {
2565
2565
  case Temporal.PlainTime: return createTemporalNode(id, 5, current);
2566
2566
  case Temporal.PlainYearMonth: return createTemporalNode(id, 6, current);
2567
2567
  case Temporal.ZonedDateTime: return createTemporalNode(id, 7, current);
2568
- default: break;
2569
2568
  }
2570
2569
  if (current instanceof Error) return parseError(ctx, depth, id, current);
2571
2570
  if (SYM_ITERATOR in current || SYM_ASYNC_ITERATOR in current) return parsePlainObject(ctx, depth, id, current, !!currentClass);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "seroval",
3
3
  "type": "module",
4
- "version": "1.6.1",
4
+ "version": "1.6.3",
5
5
  "files": [
6
6
  "dist"
7
7
  ],
@@ -16,15 +16,15 @@
16
16
  "serialization"
17
17
  ],
18
18
  "devDependencies": {
19
- "@types/node": "^24.10.0",
20
- "@vitest/ui": "^4.0.6",
21
- "esbuild": "^0.28.1",
22
- "temporal-polyfill": "^0.3.2",
19
+ "@types/node": "^26.2.0",
20
+ "@vitest/ui": "^4.1.10",
21
+ "esbuild": "^0.28.2",
22
+ "temporal-polyfill": "^1.0.3",
23
23
  "ts-prune": "^0.10.3",
24
24
  "tsdown": "^0.22.14",
25
25
  "tslib": "^2.8.1",
26
26
  "typescript": "^7.0.2",
27
- "vitest": "^4.0.6"
27
+ "vitest": "^4.1.10"
28
28
  },
29
29
  "private": false,
30
30
  "description": "Stringify JS values",