index.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. 'use strict';
  2. var whichBoxedPrimitive = require('which-boxed-primitive');
  3. var whichCollection = require('which-collection');
  4. var whichTypedArray = require('which-typed-array');
  5. var isArray = require('isarray');
  6. var isDate = require('is-date-object');
  7. var isRegex = require('is-regex');
  8. var isWeakRef = require('is-weakref');
  9. var isFinalizationRegistry = require('is-finalizationregistry');
  10. var name = require('function.prototype.name');
  11. var isGeneratorFunction = require('is-generator-function');
  12. var isAsyncFunction = require('is-async-function');
  13. var hasToStringTag = require('has-tostringtag/shams')();
  14. var toStringTag = hasToStringTag && Symbol.toStringTag;
  15. var $Object = Object;
  16. var promiseThen = typeof Promise === 'function' && Promise.prototype.then;
  17. var isPromise = function isPromise(value) {
  18. if (!value || typeof value !== 'object' || !promiseThen) {
  19. return false;
  20. }
  21. try {
  22. promiseThen.call(value, null, function () {});
  23. return true;
  24. } catch (e) {}
  25. return false;
  26. };
  27. var isKnownBuiltin = function isKnownBuiltin(builtinName) {
  28. return builtinName
  29. // primitives
  30. && builtinName !== 'BigInt'
  31. && builtinName !== 'Boolean'
  32. && builtinName !== 'Null'
  33. && builtinName !== 'Number'
  34. && builtinName !== 'String'
  35. && builtinName !== 'Symbol'
  36. && builtinName !== 'Undefined'
  37. // namespaces
  38. && builtinName !== 'Math'
  39. && builtinName !== 'JSON'
  40. && builtinName !== 'Reflect'
  41. && builtinName !== 'Atomics'
  42. // collections
  43. && builtinName !== 'Map'
  44. && builtinName !== 'Set'
  45. && builtinName !== 'WeakMap'
  46. && builtinName !== 'WeakSet'
  47. // typed arrays
  48. && builtinName !== 'BigInt64Array'
  49. && builtinName !== 'BigUint64Array'
  50. && builtinName !== 'Float32Array'
  51. && builtinName !== 'Float64Array'
  52. && builtinName !== 'Int16Array'
  53. && builtinName !== 'Int32Array'
  54. && builtinName !== 'Int8Array'
  55. && builtinName !== 'Uint16Array'
  56. && builtinName !== 'Uint32Array'
  57. && builtinName !== 'Uint8Array'
  58. && builtinName !== 'Uint8ClampedArray'
  59. // checked explicitly
  60. && builtinName !== 'Array'
  61. && builtinName !== 'Date'
  62. && builtinName !== 'FinalizationRegistry'
  63. && builtinName !== 'Promise'
  64. && builtinName !== 'RegExp'
  65. && builtinName !== 'WeakRef'
  66. // functions
  67. && builtinName !== 'Function'
  68. && builtinName !== 'GeneratorFunction'
  69. && builtinName !== 'AsyncFunction';
  70. };
  71. module.exports = function whichBuiltinType(value) {
  72. if (value == null) {
  73. return value;
  74. }
  75. // covers: primitives, {,Weak}Map/Set, typed arrays
  76. var which = whichBoxedPrimitive($Object(value)) || whichCollection(value) || whichTypedArray(value);
  77. if (which) {
  78. return which;
  79. }
  80. if (isArray(value)) {
  81. return 'Array';
  82. }
  83. if (isDate(value)) {
  84. return 'Date';
  85. }
  86. if (isRegex(value)) {
  87. return 'RegExp';
  88. }
  89. if (isWeakRef(value)) {
  90. return 'WeakRef';
  91. }
  92. if (isFinalizationRegistry(value)) {
  93. return 'FinalizationRegistry';
  94. }
  95. if (typeof value === 'function') {
  96. if (isGeneratorFunction(value)) {
  97. return 'GeneratorFunction';
  98. }
  99. if (isAsyncFunction(value)) {
  100. return 'AsyncFunction';
  101. }
  102. return 'Function';
  103. }
  104. if (isPromise(value)) {
  105. return 'Promise';
  106. }
  107. if (toStringTag && toStringTag in value) {
  108. var tag = value[toStringTag];
  109. if (isKnownBuiltin(tag)) {
  110. return tag;
  111. }
  112. }
  113. if (typeof value.constructor === 'function') {
  114. var constructorName = name(value.constructor);
  115. if (isKnownBuiltin(constructorName)) {
  116. return constructorName;
  117. }
  118. }
  119. return 'Object';
  120. };