'use strict'; var callBound = require('call-bound'); var hasToStringTag = require('has-tostringtag/shams')(); var hasOwn = require('hasown'); var gOPD = require('gopd'); /** @type {import('.')} */ var fn; if (hasToStringTag) { /** @type {(receiver: ThisParameterType, ...args: Parameters) => ReturnType} */ var $exec = callBound('RegExp.prototype.exec'); /** @type {object} */ var isRegexMarker = {}; var throwRegexMarker = function () { throw isRegexMarker; }; /** @type {{ toString(): never, valueOf(): never, [Symbol.toPrimitive]?(): never }} */ var badStringifier = { toString: throwRegexMarker, valueOf: throwRegexMarker }; if (typeof Symbol.toPrimitive === 'symbol') { badStringifier[Symbol.toPrimitive] = throwRegexMarker; } /** @type {import('.')} */ // @ts-expect-error TS can't figure out that the $exec call always throws // eslint-disable-next-line consistent-return fn = function isRegex(value) { if (!value || typeof value !== 'object') { return false; } // eslint-disable-next-line no-extra-parens var descriptor = /** @type {NonNullable} */ (gOPD)(/** @type {{ lastIndex?: unknown }} */ (value), 'lastIndex'); var hasLastIndexDataProperty = descriptor && hasOwn(descriptor, 'value'); if (!hasLastIndexDataProperty) { return false; } try { // eslint-disable-next-line no-extra-parens $exec(value, /** @type {string} */ (/** @type {unknown} */ (badStringifier))); } catch (e) { return e === isRegexMarker; } }; } else { /** @type {(receiver: ThisParameterType, ...args: Parameters) => ReturnType} */ var $toString = callBound('Object.prototype.toString'); /** @const @type {'[object RegExp]'} */ var regexClass = '[object RegExp]'; /** @type {import('.')} */ fn = function isRegex(value) { // In older browsers, typeof regex incorrectly returns 'function' if (!value || (typeof value !== 'object' && typeof value !== 'function')) { return false; } return $toString(value) === regexClass; }; } module.exports = fn;