{"version":3,"file":"isConstructor.mjs","names":[],"sources":["../../../src/utils/reflection/isConstructor.ts"],"sourcesContent":["/**\n * A very jank function to determine if an object can be the target of Reflect.construct.\n * Unfortunately, many functions have a constructor in their prototype. These\n * functions are treated like classes due to JavaScript's poor distinction between\n * classes and functions.\\\n * Typescript can enforce \"new\" keyword usage, but overriding the type\n * allows you to `new isConstructor()` despite this function not intended to be\n * used with the `new` keyword.\n * #### NOTE: Only works when targeting ES6/ES2015 or later.\n * > If your project or a dependent project is compiled to < ES6, this function will always return `false`; classes and constructors were introduced in ES6/ES2015.\n * @param object Anything.\n * @returns `true` if the {@link object} is a constructor. Else, `false`.\n * @since 3.0.0\n * @see https://stackoverflow.com/a/49510834\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isConstructor(object: unknown): object is abstract new (...arguments_: any[]) => any {\n  // Method 0 - filter\n  if (typeof object !== 'function')\n    return false;\n\n  // Method 1\n  // statically-defined class\n  if (/^class\\s/.test(object.toString()))\n    return true;\n\n  /* Method 2\n   * > class class_ {}; function func(){}\n   * undefined\n   * > class_.prototype.constructor.name === class_.name\n   * true\n   * > func.prototype?.constructor?.name === func.name\n   * false\n   * typeof String.prototype ==='object'\n   * > true\n   * typeof Function.prototype === 'object';\n   * > false\n   * typeof Function.prototype\n   * > 'function'\n   */\n  const prototype: unknown = object.prototype;\n  if (prototype != undefined\n    && (typeof prototype === 'function' || typeof prototype === 'object')\n    && 'constructor' in prototype\n    && typeof prototype.constructor === 'function') {\n    const _ctor = prototype.constructor as (new (...arguments_: unknown[]) => unknown);\n    const _name = Reflect.getOwnPropertyDescriptor(\n      _ctor,\n      'name',\n    );\n    // short-circuit if `obj.prototype.constructor` is a function, but not a constructor. Return false.\n    return (\n      _ctor === object\n      && _name?.writable === false\n      && _name.enumerable === false\n      && _name.configurable === true\n    );\n  }\n\n  // Short-circuit\n  // Method 3 catches exceptions when !isConstructor. When debugging, that's annoying.\n  return false;\n\n  // Method 3\n  // isConstructable (See https://stackoverflow.com/a/49510834)\n  // try {\n  //   // @ts-expect-error ts(2351): Type 'Function' has no construct signatures.\n  //   new new Proxy(obj, { construct: () => ({}) })()\n  //   return true\n  // }\n  // catch {\n  //   return false\n  // }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,SAAgB,cAAc,QAAuE;CAEnG,IAAI,OAAO,WAAW,YACpB,OAAO;CAIT,IAAI,WAAW,KAAK,OAAO,SAAS,CAAC,GACnC,OAAO;CAgBT,MAAM,YAAqB,OAAO;CAClC,IAAI,aAAa,KAAA,MACX,OAAO,cAAc,cAAc,OAAO,cAAc,aACzD,iBAAiB,aACjB,OAAO,UAAU,gBAAgB,YAAY;EAChD,MAAM,QAAQ,UAAU;EACxB,MAAM,QAAQ,QAAQ,yBACpB,OACA,MACF;EAEA,OACE,UAAU,UACP,OAAO,aAAa,SACpB,MAAM,eAAe,SACrB,MAAM,iBAAiB;CAE9B;CAIA,OAAO;AAYT"}