utils.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. export function isIterable(value) {
  2. return (
  3. typeof value === 'object' &&
  4. value !== null &&
  5. (
  6. typeof value[Symbol.iterator] === 'function' ||
  7. typeof value[Symbol.asyncIterator] === 'function'
  8. )
  9. );
  10. }
  11. export function replaceValue(holder, key, value, replacer) {
  12. if (value && typeof value.toJSON === 'function') {
  13. value = value.toJSON();
  14. }
  15. if (replacer !== null) {
  16. value = replacer.call(holder, String(key), value);
  17. }
  18. switch (typeof value) {
  19. case 'function':
  20. case 'symbol':
  21. value = undefined;
  22. break;
  23. case 'object':
  24. if (value !== null) {
  25. const cls = value.constructor;
  26. if (cls === String || cls === Number || cls === Boolean) {
  27. value = value.valueOf();
  28. }
  29. }
  30. break;
  31. }
  32. return value;
  33. }
  34. export function normalizeReplacer(replacer) {
  35. if (typeof replacer === 'function') {
  36. return replacer;
  37. }
  38. if (Array.isArray(replacer)) {
  39. const allowlist = new Set(replacer
  40. .map(item => {
  41. const cls = item && item.constructor;
  42. return cls === String || cls === Number ? String(item) : null;
  43. })
  44. .filter(item => typeof item === 'string')
  45. );
  46. return [...allowlist];
  47. }
  48. return null;
  49. }
  50. export function normalizeSpace(space) {
  51. if (typeof space === 'number') {
  52. if (!Number.isFinite(space) || space < 1) {
  53. return false;
  54. }
  55. return ' '.repeat(Math.min(space, 10));
  56. }
  57. if (typeof space === 'string') {
  58. return space.slice(0, 10) || false;
  59. }
  60. return false;
  61. }
  62. export function normalizeStringifyOptions(optionsOrReplacer, space) {
  63. if (optionsOrReplacer === null || Array.isArray(optionsOrReplacer) || typeof optionsOrReplacer !== 'object') {
  64. optionsOrReplacer = {
  65. replacer: optionsOrReplacer,
  66. space
  67. };
  68. }
  69. let replacer = normalizeReplacer(optionsOrReplacer.replacer);
  70. let getKeys = Object.keys;
  71. if (Array.isArray(replacer)) {
  72. const allowlist = replacer;
  73. getKeys = () => allowlist;
  74. replacer = null;
  75. }
  76. return {
  77. ...optionsOrReplacer,
  78. replacer,
  79. getKeys,
  80. space: normalizeSpace(optionsOrReplacer.space)
  81. };
  82. }