to-json.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. const nonJsonTypes = ["function", "symbol", "undefined"];
  2. const protectedProps = ["constructor", "prototype", "__proto__"];
  3. const objectPrototype = Object.getPrototypeOf({});
  4. /**
  5. * Custom JSON serializer for Error objects.
  6. * Returns all built-in error properties, as well as extended properties.
  7. */
  8. export function toJSON() {
  9. // HACK: We have to cast the objects to `any` so we can use symbol indexers.
  10. // see https://github.com/Microsoft/TypeScript/issues/1863
  11. let pojo = {};
  12. let error = this;
  13. for (let key of getDeepKeys(error)) {
  14. if (typeof key === "string") {
  15. let value = error[key];
  16. let type = typeof value;
  17. if (!nonJsonTypes.includes(type)) {
  18. pojo[key] = value;
  19. }
  20. }
  21. }
  22. return pojo;
  23. }
  24. /**
  25. * Returns own, inherited, enumerable, non-enumerable, string, and symbol keys of `obj`.
  26. * Does NOT return members of the base Object prototype, or the specified omitted keys.
  27. */
  28. export function getDeepKeys(obj, omit = []) {
  29. let keys = [];
  30. // Crawl the prototype chain, finding all the string and symbol keys
  31. while (obj && obj !== objectPrototype) {
  32. keys = keys.concat(Object.getOwnPropertyNames(obj), Object.getOwnPropertySymbols(obj));
  33. obj = Object.getPrototypeOf(obj);
  34. }
  35. // De-duplicate the list of keys
  36. let uniqueKeys = new Set(keys);
  37. // Remove any omitted keys
  38. for (let key of omit.concat(protectedProps)) {
  39. uniqueKeys.delete(key);
  40. }
  41. return uniqueKeys;
  42. }
  43. //# sourceMappingURL=to-json.js.map