[d565449] | 1 | 'use strict';
|
---|
| 2 |
|
---|
[79a0317] | 3 | var callBound = require('call-bound');
|
---|
[d565449] | 4 | var hasToStringTag = require('has-tostringtag/shams')();
|
---|
[79a0317] | 5 | var hasOwn = require('hasown');
|
---|
| 6 | var gOPD = require('gopd');
|
---|
| 7 |
|
---|
| 8 | /** @type {import('.')} */
|
---|
| 9 | var fn;
|
---|
[d565449] | 10 |
|
---|
| 11 | if (hasToStringTag) {
|
---|
[79a0317] | 12 | /** @type {(receiver: ThisParameterType<typeof RegExp.prototype.exec>, ...args: Parameters<typeof RegExp.prototype.exec>) => ReturnType<typeof RegExp.prototype.exec>} */
|
---|
| 13 | var $exec = callBound('RegExp.prototype.exec');
|
---|
| 14 | /** @type {object} */
|
---|
| 15 | var isRegexMarker = {};
|
---|
[d565449] | 16 |
|
---|
| 17 | var throwRegexMarker = function () {
|
---|
| 18 | throw isRegexMarker;
|
---|
| 19 | };
|
---|
[79a0317] | 20 | /** @type {{ toString(): never, valueOf(): never, [Symbol.toPrimitive]?(): never }} */
|
---|
| 21 | var badStringifier = {
|
---|
[d565449] | 22 | toString: throwRegexMarker,
|
---|
| 23 | valueOf: throwRegexMarker
|
---|
| 24 | };
|
---|
| 25 |
|
---|
| 26 | if (typeof Symbol.toPrimitive === 'symbol') {
|
---|
| 27 | badStringifier[Symbol.toPrimitive] = throwRegexMarker;
|
---|
| 28 | }
|
---|
| 29 |
|
---|
[79a0317] | 30 | /** @type {import('.')} */
|
---|
| 31 | // @ts-expect-error TS can't figure out that the $exec call always throws
|
---|
[d565449] | 32 | // eslint-disable-next-line consistent-return
|
---|
[79a0317] | 33 | fn = function isRegex(value) {
|
---|
[d565449] | 34 | if (!value || typeof value !== 'object') {
|
---|
| 35 | return false;
|
---|
| 36 | }
|
---|
| 37 |
|
---|
[79a0317] | 38 | // eslint-disable-next-line no-extra-parens
|
---|
| 39 | var descriptor = /** @type {NonNullable<typeof gOPD>} */ (gOPD)(/** @type {{ lastIndex?: unknown }} */ (value), 'lastIndex');
|
---|
| 40 | var hasLastIndexDataProperty = descriptor && hasOwn(descriptor, 'value');
|
---|
[d565449] | 41 | if (!hasLastIndexDataProperty) {
|
---|
| 42 | return false;
|
---|
| 43 | }
|
---|
| 44 |
|
---|
| 45 | try {
|
---|
[79a0317] | 46 | // eslint-disable-next-line no-extra-parens
|
---|
| 47 | $exec(value, /** @type {string} */ (/** @type {unknown} */ (badStringifier)));
|
---|
[d565449] | 48 | } catch (e) {
|
---|
| 49 | return e === isRegexMarker;
|
---|
| 50 | }
|
---|
[79a0317] | 51 | };
|
---|
| 52 | } else {
|
---|
| 53 | /** @type {(receiver: ThisParameterType<typeof Object.prototype.toString>, ...args: Parameters<typeof Object.prototype.toString>) => ReturnType<typeof Object.prototype.toString>} */
|
---|
| 54 | var $toString = callBound('Object.prototype.toString');
|
---|
| 55 | /** @const @type {'[object RegExp]'} */
|
---|
| 56 | var regexClass = '[object RegExp]';
|
---|
| 57 |
|
---|
| 58 | /** @type {import('.')} */
|
---|
| 59 | fn = function isRegex(value) {
|
---|
[d565449] | 60 | // In older browsers, typeof regex incorrectly returns 'function'
|
---|
| 61 | if (!value || (typeof value !== 'object' && typeof value !== 'function')) {
|
---|
| 62 | return false;
|
---|
| 63 | }
|
---|
| 64 |
|
---|
| 65 | return $toString(value) === regexClass;
|
---|
| 66 | };
|
---|
[79a0317] | 67 | }
|
---|
| 68 |
|
---|
| 69 | module.exports = fn;
|
---|