@common.js/serialize-error 11.0.2 → 13.0.1

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
@@ -2,4 +2,4 @@
2
2
 
3
3
  The [serialize-error](https://www.npmjs.com/package/serialize-error) package exported as CommonJS modules.
4
4
 
5
- Exported from [serialize-error@11.0.2](https://www.npmjs.com/package/serialize-error/v/11.0.2) using https://github.com/etienne-martin/common.js.
5
+ Exported from [serialize-error@13.0.1](https://www.npmjs.com/package/serialize-error/v/13.0.1) using https://github.com/etienne-martin/common.js.
@@ -1,8 +1,44 @@
1
+ export type ErrorFactory<T extends Error> = () => T;
2
+
1
3
  /**
2
- Map of error constructors to recreate from the serialize `name` property. If the name is not found in this map, the errors will be deserialized as simple `Error` instances.
4
+ Let `serialize-error` know about your custom error constructors so that when `{name: 'MyCustomError', message: 'It broke'}` is found, it uses the right error constructor. If "MyCustomError" isn't found in the global list of known constructors, it defaults to the base `Error` error constructor.
3
5
 
4
- Warning: Only simple and standard error constructors are supported, like `new MyCustomError(name)`. If your error constructor *requires* a second parameter or does not accept a string as first parameter, adding it to this map *will* break the deserialization.
5
- */
6
- declare const errorConstructors: Map<string, ErrorConstructor>;
6
+ @param constructor - The error constructor to add.
7
+ @param factory - Factory function to create instances. Optional if the constructor can be called without arguments, required if it needs arguments.
8
+
9
+ @example
10
+ ```
11
+ // Constructor that works without arguments - factory is optional
12
+ addKnownErrorConstructor(Error);
13
+ addKnownErrorConstructor(TypeError);
14
+
15
+ class MyError extends Error {
16
+ name = 'MyError';
7
17
 
8
- export default errorConstructors;
18
+ constructor(message?: string) {
19
+ super(message);
20
+ this.name = 'MyError';
21
+ }
22
+ }
23
+ addKnownErrorConstructor(MyError);
24
+
25
+ // Constructor that requires arguments - factory is required
26
+ class CustomError extends Error {
27
+ name = 'CustomError';
28
+
29
+ constructor(message: string, options: {code: string}) {
30
+ super(message);
31
+ this.code = options.code;
32
+ }
33
+ }
34
+ addKnownErrorConstructor(CustomError, () => new CustomError('', {code: 'ERR_UNICORN'}));
35
+ ```
36
+ */
37
+ export function addKnownErrorConstructor<T extends Error>(
38
+ constructor: new () => T,
39
+ factory?: ErrorFactory<T>
40
+ ): void;
41
+ export function addKnownErrorConstructor<T extends Error>(
42
+ constructor: new (...arguments_: [any, ...any[]]) => T,
43
+ factory: ErrorFactory<T>
44
+ ): void;
@@ -2,20 +2,40 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "default", {
6
- enumerable: true,
7
- get: function() {
8
- return _default;
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ errorConstructors: function() {
13
+ return errorConstructors;
14
+ },
15
+ errorFactories: function() {
16
+ return errorFactories;
17
+ },
18
+ addKnownErrorConstructor: function() {
19
+ return addKnownErrorConstructor;
9
20
  }
10
21
  });
22
+ function _instanceof(left, right) {
23
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
24
+ return !!right[Symbol.hasInstance](left);
25
+ } else {
26
+ return left instanceof right;
27
+ }
28
+ }
11
29
  var list = [
12
30
  // Native ES errors https://262.ecma-international.org/12.0/#sec-well-known-intrinsic-objects
31
+ Error,
13
32
  EvalError,
14
33
  RangeError,
15
34
  ReferenceError,
16
35
  SyntaxError,
17
36
  TypeError,
18
37
  URIError,
38
+ AggregateError,
19
39
  // Built-in errors
20
40
  globalThis.DOMException,
21
41
  // Node-specific errors
@@ -30,4 +50,44 @@ var list = [
30
50
  ];
31
51
  });
32
52
  var errorConstructors = new Map(list);
33
- var _default = errorConstructors;
53
+ var errorFactories = new Map();
54
+ function addKnownErrorConstructor(constructor, factory) {
55
+ var instance;
56
+ var resolvedName;
57
+ if (factory) {
58
+ if (typeof factory !== "function") {
59
+ throw new TypeError("Factory must be a function");
60
+ }
61
+ // Verify factory can execute without throwing
62
+ try {
63
+ instance = factory();
64
+ } catch (error) {
65
+ throw new Error("Factory is not compatible", {
66
+ cause: error
67
+ });
68
+ }
69
+ if (!_instanceof(instance, constructor)) {
70
+ throw new TypeError("Factory must return an instance of the constructor");
71
+ }
72
+ resolvedName = instance.name;
73
+ } else {
74
+ try {
75
+ instance = new constructor();
76
+ } catch (error1) {
77
+ throw new Error('Constructor "'.concat(constructor.name, '" is not compatible'), {
78
+ cause: error1
79
+ });
80
+ }
81
+ resolvedName = instance.name;
82
+ }
83
+ if (!resolvedName || typeof resolvedName !== "string") {
84
+ throw new TypeError('Error instances must have a non-empty string "name" property');
85
+ }
86
+ if (errorConstructors.has(resolvedName)) {
87
+ throw new Error('Error constructor "'.concat(resolvedName, '" is already known'));
88
+ }
89
+ errorConstructors.set(resolvedName, constructor);
90
+ if (factory) {
91
+ errorFactories.set(resolvedName, factory);
92
+ }
93
+ }
package/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import {Primitive, JsonObject} from 'type-fest';
1
+ import {type JsonObject} from 'type-fest';
2
2
 
3
- export {default as errorConstructors} from './error-constructors.js';
3
+ export {addKnownErrorConstructor, type ErrorFactory} from './error-constructors.js';
4
+ export {default as NonError} from 'non-error';
4
5
 
5
6
  export type ErrorObject = {
6
7
  name?: string;
@@ -19,7 +20,7 @@ export type ErrorLike = {
19
20
  code?: string;
20
21
  };
21
22
 
22
- export interface Options {
23
+ export type Options = {
23
24
  /**
24
25
  The maximum depth of properties to preserve when serializing/deserializing.
25
26
 
@@ -33,10 +34,10 @@ export interface Options {
33
34
  error.one = {two: {three: {}}};
34
35
 
35
36
  console.log(serializeError(error, {maxDepth: 1}));
36
- //=> {name: 'Error', message: '', one: {}}
37
+ //=> {name: 'Error', message: '🦄', one: {}}
37
38
 
38
39
  console.log(serializeError(error, {maxDepth: 2}));
39
- //=> {name: 'Error', message: '', one: { two: {}}}
40
+ //=> {name: 'Error', message: '🦄', one: { two: {}}}
40
41
  ```
41
42
  */
42
43
  readonly maxDepth?: number;
@@ -47,13 +48,15 @@ export interface Options {
47
48
  @default true
48
49
  */
49
50
  readonly useToJSON?: boolean;
50
- }
51
+ };
51
52
 
52
53
  /**
53
54
  Serialize an `Error` object into a plain object.
54
55
 
55
- - Non-error values are passed through.
56
56
  - Custom properties are preserved.
57
+ - Non-enumerable properties are kept non-enumerable (name, message, stack).
58
+ - Enumerable properties are kept enumerable (all properties besides the non-enumerable ones).
59
+ - Primitive values (including `null`, `undefined`, strings, numbers, etc.) and functions are wrapped in a `NonError` error and serialized.
57
60
  - Buffer properties are replaced with `[object Buffer]`.
58
61
  - Circular references are handled.
59
62
  - If the input object has a `.toJSON()` method, then it's called instead of serializing the object's properties.
@@ -105,9 +108,7 @@ serializeError(error);
105
108
  // => {horn: 'x', name, message, stack}
106
109
  ```
107
110
  */
108
- export function serializeError<ErrorType>(error: ErrorType, options?: Options): ErrorType extends Primitive
109
- ? ErrorType
110
- : ErrorObject;
111
+ export function serializeError(error: unknown, options?: Options): ErrorObject;
111
112
 
112
113
  /**
113
114
  Deserialize a plain object or any value into an `Error` object.
@@ -157,7 +158,7 @@ isErrorLike({
157
158
  isErrorLike(new Error('🦄'));
158
159
  //=> true
159
160
 
160
- isErrorLike(serializeError(new Error('🦄'));
161
+ isErrorLike(serializeError(new Error('🦄')));
161
162
  //=> true
162
163
 
163
164
  isErrorLike({
package/index.js CHANGED
@@ -9,9 +9,6 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
- NonError: function() {
13
- return NonError;
14
- },
15
12
  serializeError: function() {
16
13
  return serializeError;
17
14
  },
@@ -21,107 +18,15 @@ _export(exports, {
21
18
  isErrorLike: function() {
22
19
  return isErrorLike;
23
20
  },
24
- errorConstructors: function() {
25
- return _errorConstructorsJs.default;
21
+ addKnownErrorConstructor: function() {
22
+ return _errorConstructorsJs.addKnownErrorConstructor;
23
+ },
24
+ NonError: function() {
25
+ return _nonError.default;
26
26
  }
27
27
  });
28
- var _errorConstructorsJs = /*#__PURE__*/ _interopRequireDefault(require("./error-constructors.js"));
29
- function _arrayLikeToArray(arr, len) {
30
- if (len == null || len > arr.length) len = arr.length;
31
- for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
32
- return arr2;
33
- }
34
- function _arrayWithHoles(arr) {
35
- if (Array.isArray(arr)) return arr;
36
- }
37
- function _arrayWithoutHoles(arr) {
38
- if (Array.isArray(arr)) return _arrayLikeToArray(arr);
39
- }
40
- function _assertThisInitialized(self) {
41
- if (self === void 0) {
42
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
43
- }
44
- return self;
45
- }
46
- function _classCallCheck(instance, Constructor) {
47
- if (!(instance instanceof Constructor)) {
48
- throw new TypeError("Cannot call a class as a function");
49
- }
50
- }
51
- function isNativeReflectConstruct() {
52
- if (typeof Reflect === "undefined" || !Reflect.construct) return false;
53
- if (Reflect.construct.sham) return false;
54
- if (typeof Proxy === "function") return true;
55
- try {
56
- Date.prototype.toString.call(Reflect.construct(Date, [], function() {}));
57
- return true;
58
- } catch (e) {
59
- return false;
60
- }
61
- }
62
- function _construct(Parent, args, Class) {
63
- if (isNativeReflectConstruct()) {
64
- _construct = Reflect.construct;
65
- } else {
66
- _construct = function _construct(Parent, args, Class) {
67
- var a = [
68
- null
69
- ];
70
- a.push.apply(a, args);
71
- var Constructor = Function.bind.apply(Parent, a);
72
- var instance = new Constructor();
73
- if (Class) _setPrototypeOf(instance, Class.prototype);
74
- return instance;
75
- };
76
- }
77
- return _construct.apply(null, arguments);
78
- }
79
- function _defineProperties(target, props) {
80
- for(var i = 0; i < props.length; i++){
81
- var descriptor = props[i];
82
- descriptor.enumerable = descriptor.enumerable || false;
83
- descriptor.configurable = true;
84
- if ("value" in descriptor) descriptor.writable = true;
85
- Object.defineProperty(target, descriptor.key, descriptor);
86
- }
87
- }
88
- function _createClass(Constructor, protoProps, staticProps) {
89
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
90
- if (staticProps) _defineProperties(Constructor, staticProps);
91
- return Constructor;
92
- }
93
- function _defineProperty(obj, key, value) {
94
- if (key in obj) {
95
- Object.defineProperty(obj, key, {
96
- value: value,
97
- enumerable: true,
98
- configurable: true,
99
- writable: true
100
- });
101
- } else {
102
- obj[key] = value;
103
- }
104
- return obj;
105
- }
106
- function _getPrototypeOf(o) {
107
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
108
- return o.__proto__ || Object.getPrototypeOf(o);
109
- };
110
- return _getPrototypeOf(o);
111
- }
112
- function _inherits(subClass, superClass) {
113
- if (typeof superClass !== "function" && superClass !== null) {
114
- throw new TypeError("Super expression must either be null or a function");
115
- }
116
- subClass.prototype = Object.create(superClass && superClass.prototype, {
117
- constructor: {
118
- value: subClass,
119
- writable: true,
120
- configurable: true
121
- }
122
- });
123
- if (superClass) _setPrototypeOf(subClass, superClass);
124
- }
28
+ var _nonError = /*#__PURE__*/ _interopRequireDefault(require("non-error"));
29
+ var _errorConstructorsJs = require("./error-constructors.js");
125
30
  function _instanceof(left, right) {
126
31
  if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
127
32
  return !!right[Symbol.hasInstance](left);
@@ -134,149 +39,11 @@ function _interopRequireDefault(obj) {
134
39
  default: obj
135
40
  };
136
41
  }
137
- function _isNativeFunction(fn) {
138
- return Function.toString.call(fn).indexOf("[native code]") !== -1;
139
- }
140
- function _iterableToArray(iter) {
141
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
142
- }
143
- function _iterableToArrayLimit(arr, i) {
144
- var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
145
- if (_i == null) return;
146
- var _arr = [];
147
- var _n = true;
148
- var _d = false;
149
- var _s, _e;
150
- try {
151
- for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
152
- _arr.push(_s.value);
153
- if (i && _arr.length === i) break;
154
- }
155
- } catch (err) {
156
- _d = true;
157
- _e = err;
158
- } finally{
159
- try {
160
- if (!_n && _i["return"] != null) _i["return"]();
161
- } finally{
162
- if (_d) throw _e;
163
- }
164
- }
165
- return _arr;
166
- }
167
- function _nonIterableRest() {
168
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
169
- }
170
- function _nonIterableSpread() {
171
- throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
172
- }
173
- function _possibleConstructorReturn(self, call) {
174
- if (call && (_typeof(call) === "object" || typeof call === "function")) {
175
- return call;
176
- }
177
- return _assertThisInitialized(self);
178
- }
179
- function _setPrototypeOf(o, p) {
180
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
181
- o.__proto__ = p;
182
- return o;
183
- };
184
- return _setPrototypeOf(o, p);
185
- }
186
- function _slicedToArray(arr, i) {
187
- return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
188
- }
189
- function _toConsumableArray(arr) {
190
- return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
191
- }
192
42
  var _typeof = function(obj) {
193
43
  "@swc/helpers - typeof";
194
44
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
195
45
  };
196
- function _unsupportedIterableToArray(o, minLen) {
197
- if (!o) return;
198
- if (typeof o === "string") return _arrayLikeToArray(o, minLen);
199
- var n = Object.prototype.toString.call(o).slice(8, -1);
200
- if (n === "Object" && o.constructor) n = o.constructor.name;
201
- if (n === "Map" || n === "Set") return Array.from(n);
202
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
203
- }
204
- function _wrapNativeSuper(Class) {
205
- var _cache = typeof Map === "function" ? new Map() : undefined;
206
- _wrapNativeSuper = function _wrapNativeSuper(Class) {
207
- if (Class === null || !_isNativeFunction(Class)) return Class;
208
- if (typeof Class !== "function") {
209
- throw new TypeError("Super expression must either be null or a function");
210
- }
211
- if (typeof _cache !== "undefined") {
212
- if (_cache.has(Class)) return _cache.get(Class);
213
- _cache.set(Class, Wrapper);
214
- }
215
- function Wrapper() {
216
- return _construct(Class, arguments, _getPrototypeOf(this).constructor);
217
- }
218
- Wrapper.prototype = Object.create(Class.prototype, {
219
- constructor: {
220
- value: Wrapper,
221
- enumerable: false,
222
- writable: true,
223
- configurable: true
224
- }
225
- });
226
- return _setPrototypeOf(Wrapper, Class);
227
- };
228
- return _wrapNativeSuper(Class);
229
- }
230
- function _isNativeReflectConstruct() {
231
- if (typeof Reflect === "undefined" || !Reflect.construct) return false;
232
- if (Reflect.construct.sham) return false;
233
- if (typeof Proxy === "function") return true;
234
- try {
235
- Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
236
- return true;
237
- } catch (e) {
238
- return false;
239
- }
240
- }
241
- function _createSuper(Derived) {
242
- var hasNativeReflectConstruct = _isNativeReflectConstruct();
243
- return function _createSuperInternal() {
244
- var Super = _getPrototypeOf(Derived), result;
245
- if (hasNativeReflectConstruct) {
246
- var NewTarget = _getPrototypeOf(this).constructor;
247
- result = Reflect.construct(Super, arguments, NewTarget);
248
- } else {
249
- result = Super.apply(this, arguments);
250
- }
251
- return _possibleConstructorReturn(this, result);
252
- };
253
- }
254
- var NonError = /*#__PURE__*/ function(Error1) {
255
- "use strict";
256
- _inherits(NonError, Error1);
257
- var _super = _createSuper(NonError);
258
- function NonError(message) {
259
- _classCallCheck(this, NonError);
260
- var _this;
261
- _this = _super.call(this, NonError._prepareSuperMessage(message));
262
- _defineProperty(_assertThisInitialized(_this), "name", "NonError");
263
- return _this;
264
- }
265
- _createClass(NonError, null, [
266
- {
267
- key: "_prepareSuperMessage",
268
- value: function _prepareSuperMessage(message) {
269
- try {
270
- return JSON.stringify(message);
271
- } catch (e) {
272
- return String(message);
273
- }
274
- }
275
- }
276
- ]);
277
- return NonError;
278
- }(_wrapNativeSuper(Error));
279
- var commonProperties = [
46
+ var errorProperties = [
280
47
  {
281
48
  property: "name",
282
49
  enumerable: false
@@ -296,6 +63,10 @@ var commonProperties = [
296
63
  {
297
64
  property: "cause",
298
65
  enumerable: false
66
+ },
67
+ {
68
+ property: "errors",
69
+ enumerable: false
299
70
  },
300
71
  ];
301
72
  var toJsonWasCalled = new WeakSet();
@@ -305,56 +76,70 @@ var toJSON = function(from) {
305
76
  toJsonWasCalled.delete(from);
306
77
  return json;
307
78
  };
308
- var ref;
309
- var getErrorConstructor = function(name) {
310
- return (ref = _errorConstructorsJs.default.get(name)) !== null && ref !== void 0 ? ref : Error;
79
+ var newError = function(name) {
80
+ if (name === "NonError") {
81
+ return new _nonError.default();
82
+ }
83
+ var factory = _errorConstructorsJs.errorFactories.get(name);
84
+ if (factory) {
85
+ return factory();
86
+ }
87
+ var ref;
88
+ var ErrorConstructor = (ref = _errorConstructorsJs.errorConstructors.get(name)) !== null && ref !== void 0 ? ref : Error;
89
+ return ErrorConstructor === AggregateError ? new ErrorConstructor([]) : new ErrorConstructor();
311
90
  };
312
- // eslint-disable-next-line complexity
313
91
  var destroyCircular = function(param) {
314
92
  var from = param.from, seen = param.seen, to = param.to, forceEnumerable = param.forceEnumerable, maxDepth = param.maxDepth, depth = param.depth, useToJSON = param.useToJSON, serialize = param.serialize;
315
93
  if (!to) {
316
94
  if (Array.isArray(from)) {
317
95
  to = [];
318
96
  } else if (!serialize && isErrorLike(from)) {
319
- var _$Error = getErrorConstructor(from.name);
320
- to = new _$Error();
97
+ to = newError(from.name);
321
98
  } else {
322
99
  to = {};
323
100
  }
324
101
  }
325
- seen.push(from);
102
+ seen.add(from);
326
103
  if (depth >= maxDepth) {
104
+ seen.delete(from);
327
105
  return to;
328
106
  }
329
107
  if (useToJSON && typeof from.toJSON === "function" && !toJsonWasCalled.has(from)) {
108
+ seen.delete(from);
330
109
  return toJSON(from);
331
110
  }
332
111
  var continueDestroyCircular = function(value) {
333
112
  return destroyCircular({
334
113
  from: value,
335
- seen: _toConsumableArray(seen),
114
+ seen: seen,
336
115
  forceEnumerable: forceEnumerable,
337
116
  maxDepth: maxDepth,
338
- depth: depth,
117
+ depth: depth + 1,
339
118
  useToJSON: useToJSON,
340
119
  serialize: serialize
341
120
  });
342
121
  };
343
122
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
344
123
  try {
345
- for(var _iterator = Object.entries(from)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
346
- var _value = _slicedToArray(_step.value, 2), key = _value[0], value = _value[1];
347
- // eslint-disable-next-line node/prefer-global/buffer
348
- if (typeof Buffer === "function" && Buffer.isBuffer(value)) {
349
- to[key] = "[object Buffer]";
124
+ for(var _iterator = Object.keys(from)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
125
+ var key = _step.value;
126
+ var value = from[key];
127
+ if (value && _instanceof(value, Uint8Array) && value.constructor.name === "Buffer") {
128
+ to[key] = serialize ? "[object Buffer]" : value;
350
129
  continue;
351
130
  }
352
- // TODO: Use `stream.isReadable()` when targeting Node.js 18.
353
131
  if (value !== null && typeof value === "object" && typeof value.pipe === "function") {
354
- to[key] = "[object Stream]";
132
+ to[key] = serialize ? "[object Stream]" : value;
355
133
  continue;
356
134
  }
357
135
  if (typeof value === "function") {
136
+ if (!serialize) {
137
+ to[key] = value;
138
+ }
139
+ continue;
140
+ }
141
+ if (serialize && (typeof value === "undefined" ? "undefined" : _typeof(value)) === "bigint") {
142
+ to[key] = "".concat(value, "n");
358
143
  continue;
359
144
  }
360
145
  if (!value || typeof value !== "object") {
@@ -364,9 +149,8 @@ var destroyCircular = function(param) {
364
149
  } catch (e) {}
365
150
  continue;
366
151
  }
367
- if (!seen.includes(from[key])) {
368
- depth++;
369
- to[key] = continueDestroyCircular(from[key]);
152
+ if (!seen.has(value)) {
153
+ to[key] = continueDestroyCircular(value);
370
154
  continue;
371
155
  }
372
156
  to[key] = "[Circular]";
@@ -385,33 +169,46 @@ var destroyCircular = function(param) {
385
169
  }
386
170
  }
387
171
  }
388
- var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
389
- try {
390
- for(var _iterator1 = commonProperties[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
391
- var _value1 = _step1.value, property = _value1.property, enumerable = _value1.enumerable;
392
- if (typeof from[property] !== "undefined" && from[property] !== null) {
172
+ if (serialize || _instanceof(to, Error)) {
173
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
174
+ try {
175
+ for(var _iterator1 = errorProperties[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
176
+ var _value = _step1.value, property = _value.property, enumerable = _value.enumerable;
177
+ var value1 = from[property];
178
+ if (value1 === undefined || value1 === null) {
179
+ continue;
180
+ }
181
+ var descriptor = Object.getOwnPropertyDescriptor(to, property);
182
+ if ((descriptor === null || descriptor === void 0 ? void 0 : descriptor.configurable) === false) {
183
+ continue;
184
+ }
185
+ var processedValue = value1;
186
+ if (typeof value1 === "object") {
187
+ processedValue = seen.has(value1) ? "[Circular]" : continueDestroyCircular(value1);
188
+ }
393
189
  Object.defineProperty(to, property, {
394
- value: isErrorLike(from[property]) ? continueDestroyCircular(from[property]) : from[property],
395
- enumerable: forceEnumerable ? true : enumerable,
190
+ value: processedValue,
191
+ enumerable: forceEnumerable || enumerable,
396
192
  configurable: true,
397
193
  writable: true
398
194
  });
399
195
  }
400
- }
401
- } catch (err) {
402
- _didIteratorError1 = true;
403
- _iteratorError1 = err;
404
- } finally{
405
- try {
406
- if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
407
- _iterator1.return();
408
- }
196
+ } catch (err) {
197
+ _didIteratorError1 = true;
198
+ _iteratorError1 = err;
409
199
  } finally{
410
- if (_didIteratorError1) {
411
- throw _iteratorError1;
200
+ try {
201
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
202
+ _iterator1.return();
203
+ }
204
+ } finally{
205
+ if (_didIteratorError1) {
206
+ throw _iteratorError1;
207
+ }
412
208
  }
413
209
  }
414
210
  }
211
+ seen.delete(from);
415
212
  return to;
416
213
  };
417
214
  function serializeError(value) {
@@ -420,7 +217,7 @@ function serializeError(value) {
420
217
  if (typeof value === "object" && value !== null) {
421
218
  return destroyCircular({
422
219
  from: value,
423
- seen: [],
220
+ seen: new Set(),
424
221
  forceEnumerable: true,
425
222
  maxDepth: maxDepth,
426
223
  depth: 0,
@@ -430,11 +227,17 @@ function serializeError(value) {
430
227
  }
431
228
  // People sometimes throw things besides Error objects…
432
229
  if (typeof value === "function") {
433
- // `JSON.stringify()` discards functions. We do too, unless a function is thrown directly.
434
- // We intentionally use `||` because `.name` is an empty string for anonymous functions.
435
- return "[Function: ".concat(value.name || "anonymous", "]");
230
+ value = "<Function>";
436
231
  }
437
- return value;
232
+ return destroyCircular({
233
+ from: new _nonError.default(value),
234
+ seen: new Set(),
235
+ forceEnumerable: true,
236
+ maxDepth: maxDepth,
237
+ depth: 0,
238
+ useToJSON: useToJSON,
239
+ serialize: true
240
+ });
438
241
  }
439
242
  function deserializeError(value) {
440
243
  var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
@@ -443,21 +246,21 @@ function deserializeError(value) {
443
246
  return value;
444
247
  }
445
248
  if (isMinimumViableSerializedError(value)) {
446
- var _$Error = getErrorConstructor(value.name);
447
249
  return destroyCircular({
448
250
  from: value,
449
- seen: [],
450
- to: new _$Error(),
251
+ seen: new Set(),
252
+ to: newError(value.name),
451
253
  maxDepth: maxDepth,
452
254
  depth: 0,
453
255
  serialize: false
454
256
  });
455
257
  }
456
- return new NonError(value);
258
+ return new _nonError.default(value);
457
259
  }
458
260
  function isErrorLike(value) {
459
- return Boolean(value) && typeof value === "object" && "name" in value && "message" in value && "stack" in value;
261
+ return Boolean(value) && typeof value === "object" && typeof value.name === "string" && typeof value.message === "string" && typeof value.stack === "string";
460
262
  }
263
+ // Used as a weak check for immediately-passed objects, whereas `isErrorLike` is used for nested values to avoid bad detection
461
264
  function isMinimumViableSerializedError(value) {
462
- return Boolean(value) && typeof value === "object" && "message" in value && !Array.isArray(value);
265
+ return Boolean(value) && typeof value === "object" && typeof value.message === "string" && !Array.isArray(value);
463
266
  }
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@common.js/serialize-error",
3
- "version": "11.0.2",
3
+ "version": "13.0.1",
4
4
  "description": "serialize-error package exported as CommonJS modules",
5
5
  "license": "MIT",
6
6
  "repository": "etienne-martin/common.js",
7
7
  "funding": "https://github.com/sponsors/sindresorhus",
8
8
  "type": "commonjs",
9
+ "sideEffects": false,
9
10
  "engines": {
10
- "node": ">=14.16"
11
+ "node": ">=20"
11
12
  },
12
13
  "scripts": {
13
- "//test": "xo && ava && tsd",
14
- "test": "ava && tsd"
14
+ "test": "xo && ava && tsd"
15
15
  },
16
16
  "files": [
17
17
  "index.js",
@@ -20,13 +20,16 @@
20
20
  "error-constructors.d.ts"
21
21
  ],
22
22
  "dependencies": {
23
- "type-fest": "^2.12.2"
23
+ "@common.js/non-error": "^0.1.0",
24
+ "@common.js/type-fest": "^5.4.1"
24
25
  },
25
26
  "devDependencies": {
26
- "ava": "^4.2.0",
27
- "tsd": "^0.20.0",
28
- "xo": "^0.48.0"
27
+ "ava": "^6.4.1",
28
+ "expect-type": "^1.3.0",
29
+ "tsd": "^0.33.0",
30
+ "xo": "^1.2.3"
29
31
  },
30
32
  "homepage": "https://github.com/etienne-martin/common.js#readme",
31
- "main": "./index.js"
33
+ "main": "./index.js",
34
+ "types": "./index.d.ts"
32
35
  }