-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
132 lines (127 loc) · 3.87 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
'use strict';
var whichBoxedPrimitive = require('which-boxed-primitive');
var whichCollection = require('which-collection');
var whichTypedArray = require('which-typed-array');
var isArray = require('isarray');
var isDate = require('is-date-object');
var isRegex = require('is-regex');
var isWeakRef = require('is-weakref');
var isFinalizationRegistry = require('is-finalizationregistry');
var name = require('function.prototype.name');
var isGeneratorFunction = require('is-generator-function');
var isAsyncFunction = require('is-async-function');
var callBound = require('call-bind/callBound');
var hasToStringTag = require('has-tostringtag/shams')();
var toStringTag = hasToStringTag && Symbol.toStringTag;
var $Object = Object;
/** @type {undefined | ((value: ThisParameterType<typeof Promise.prototype.then>, ...args: Parameters<typeof Promise.prototype.then>) => ReturnType<typeof Promise.prototype.then>)} */
var promiseThen = callBound('Promise.prototype.then', true);
/** @type {<T = unknown>(value: unknown) => value is Promise<T>} */
var isPromise = function isPromise(value) {
if (!value || typeof value !== 'object' || !promiseThen) {
return false;
}
try {
promiseThen(value, null, function () {});
return true;
} catch (e) {}
return false;
};
/** @type {(builtinName: unknown) => boolean} */
var isKnownBuiltin = function isKnownBuiltin(builtinName) {
return !!builtinName
// primitives
&& builtinName !== 'BigInt'
&& builtinName !== 'Boolean'
&& builtinName !== 'Null'
&& builtinName !== 'Number'
&& builtinName !== 'String'
&& builtinName !== 'Symbol'
&& builtinName !== 'Undefined'
// namespaces
&& builtinName !== 'Math'
&& builtinName !== 'JSON'
&& builtinName !== 'Reflect'
&& builtinName !== 'Atomics'
// collections
&& builtinName !== 'Map'
&& builtinName !== 'Set'
&& builtinName !== 'WeakMap'
&& builtinName !== 'WeakSet'
// typed arrays
&& builtinName !== 'BigInt64Array'
&& builtinName !== 'BigUint64Array'
&& builtinName !== 'Float32Array'
&& builtinName !== 'Float64Array'
&& builtinName !== 'Int16Array'
&& builtinName !== 'Int32Array'
&& builtinName !== 'Int8Array'
&& builtinName !== 'Uint16Array'
&& builtinName !== 'Uint32Array'
&& builtinName !== 'Uint8Array'
&& builtinName !== 'Uint8ClampedArray'
// checked explicitly
&& builtinName !== 'Array'
&& builtinName !== 'Date'
&& builtinName !== 'FinalizationRegistry'
&& builtinName !== 'Promise'
&& builtinName !== 'RegExp'
&& builtinName !== 'WeakRef'
// functions
&& builtinName !== 'Function'
&& builtinName !== 'GeneratorFunction'
&& builtinName !== 'AsyncFunction';
};
/** @type {import('.')} */
module.exports = function whichBuiltinType(value) {
if (value == null) {
return value;
}
// covers: primitives, {,Weak}Map/Set, typed arrays
var which = whichBoxedPrimitive($Object(value)) || whichCollection(value) || whichTypedArray(value);
if (which) {
return which;
}
if (isArray(value)) {
return 'Array';
}
if (isDate(value)) {
return 'Date';
}
if (isRegex(value)) {
return 'RegExp';
}
if (isWeakRef(value)) {
return 'WeakRef';
}
if (isFinalizationRegistry(value)) {
return 'FinalizationRegistry';
}
if (typeof value === 'function') {
if (isGeneratorFunction(value)) {
return 'GeneratorFunction';
}
if (isAsyncFunction(value)) {
return 'AsyncFunction';
}
return 'Function';
}
if (isPromise(value)) {
return 'Promise';
}
// @ts-expect-error TS can't figure out that `value` is an `object` after the `which` check above
if (toStringTag && toStringTag in value) {
var tag = value[toStringTag];
if (isKnownBuiltin(tag)) {
return tag;
}
}
if (typeof value.constructor === 'function') {
// eslint-disable-next-line no-extra-parens
var constructorName = name(/** @type {Parameters<name>[0]} */ (value.constructor));
if (isKnownBuiltin(constructorName)) {
return constructorName;
}
}
return 'Object';
};