UNPKG

@sapphire/type

Version:

A type detection utility for JavaScript

162 lines (156 loc) 5.19 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var nodePreGyp = require('@discordjs/node-pre-gyp'); var path = require('path'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var nodePreGyp__default = /*#__PURE__*/_interopDefault(nodePreGyp); var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw Error('Dynamic require of "' + x + '" is not supported'); }); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); var bindingPath = nodePreGyp__default.default.find(path.resolve(path.join(__dirname, "..", "..", "./package.json"))); var { getPromiseDetails, getProxyDetails } = __require(bindingPath); var _Type = class _Type { /** * @param value The value to generate a deep Type of * @param parent The parent value used in recursion */ constructor(value, parent = null) { /** * The value to generate a deep Type of */ __publicField(this, "value"); /** * The shallow type of this */ __publicField(this, "is"); /** * The parent of this Type */ __publicField(this, "parent"); /** * The child keys of this Type */ __publicField(this, "childKeys", /* @__PURE__ */ new Map()); /** * The child values of this Type */ __publicField(this, "childValues", /* @__PURE__ */ new Map()); this.value = value; this.is = _Type.resolve(value); this.parent = parent; } /** * The type string for the children of this Type */ get childTypes() { if (!this.childValues.size) return ""; return `<${(this.childKeys.size ? `${_Type.list(this.childKeys)}, ` : "") + _Type.list(this.childValues)}>`; } /** * The full type string generated. */ toString() { this.check(); return `${this.is}${this.childTypes}`; } /** * Walks the linked list backwards, for checking circulars. */ *parents() { let current = this; while (current = current.parent) yield current; } /** * Checks if the value of this Type is a circular reference to any parent. */ isCircular() { for (const parent of this.parents()) if (parent.value === this.value) return true; return false; } /** * The subtype to create based on this.value's sub value. * @param value The sub value */ addValue(value) { const child = new _Type(value, this); this.childValues.set(child.is, child); } /** * The subtype to create based on this.value's entries. * @param entry The entry */ addEntry([key, value]) { const child = new _Type(key, this); this.childKeys.set(child.is, child); this.addValue(value); } /** * Get the deep type name that defines the input. */ check() { if (Object.isFrozen(this)) return; const promise = getPromiseDetails(this.value); const proxy = getProxyDetails(this.value); if (typeof this.value === "object" && this.isCircular()) { this.is = `[Circular:${this.is}]`; } else if (promise && promise[0]) { this.addValue(promise[1]); } else if (proxy && proxy[0]) { this.is = "Proxy"; this.addValue(proxy[0]); } else if (this.value instanceof Map) { for (const entry of this.value) this.addEntry(entry); } else if (Array.isArray(this.value) || this.value instanceof Set) { for (const value of this.value) this.addValue(value); } else if (this.is === "Object") { this.is = "Record"; for (const entry of Object.entries(this.value)) this.addEntry(entry); } Object.freeze(this); } /** * Resolves the type name that defines the input. * @param value The value to get the type name of */ static resolve(value) { const type = typeof value; switch (type) { case "object": { if (value === null) return "null"; if (!value.constructor?.name) return "Object"; return value.constructor.name; } case "function": { if (!value.constructor?.name) return "Function"; return `${value.constructor.name}(${value.length}-arity)`; } case "undefined": return "void"; default: return type; } } /** * Joins the list of child types. * @param values The values to list */ static list(values) { return [...values.values()].sort().join(" | "); } }; __name(_Type, "Type"); var Type = _Type; var lib_default = Type; exports.Type = Type; exports.default = lib_default; exports.getPromiseDetails = getPromiseDetails; exports.getProxyDetails = getProxyDetails; //# sourceMappingURL=index.cjs.map //# sourceMappingURL=index.cjs.map