@sapphire/type
Version:
A type detection utility for JavaScript
162 lines (156 loc) • 5.19 kB
JavaScript
'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