UNPKG

ts-comply

Version:

TypeTools is a Typescript library for providing extensible tooling runtime validations and type helpers.

262 lines 11.1 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.ClassLineage = exports.ClassLineageExtensionData = exports.ClassLineageSettings = void 0; var context_1 = require("./context"); var type_tools_1 = require("./type-tools"); var common_iface_1 = require("./upstream/common.iface"); var lcaCache = {}; var lineageCache = {}; var ClassLineageSettings = exports.ClassLineageSettings = (function (_super) { __extends(ClassLineageSettings, _super); function ClassLineageSettings(init) { var _this = _super.call(this, init) || this; _this.extensionEphemerals = ClassLineageSettings.extensionClassLineage; if (init) { Object.assign(_this, init); } return _this; } ClassLineageSettings.extensionClassLineage = 'ClassLineage'; return ClassLineageSettings; }(type_tools_1.TypeToolsSettings)); var ClassLineageExtensionData = (function () { function ClassLineageExtensionData() { this.lineage = []; } return ClassLineageExtensionData; }()); exports.ClassLineageExtensionData = ClassLineageExtensionData; var ClassLineage = exports.ClassLineage = (function () { function ClassLineage(settings) { this.settings = (0, type_tools_1.settingsInitialize)(ClassLineageSettings, settings); } ClassLineage.getExtensionData = function (target, settings) { if (settings === void 0) { settings = ClassLineageSettings; } return type_tools_1.TypeToolsBase.getExtension(target, settings.extensionClassLineage, settings); }; ClassLineage.typeCheck = function (target, settings) { if (settings === void 0) { settings = ClassLineageSettings; } return target && !!ClassLineage.getExtensionData(target, settings); }; ClassLineage.implementOn = function (target, settings) { if (settings === void 0) { settings = ClassLineageSettings; } if (!type_tools_1.TypeToolsBase.checkContext(ClassLineage)) { return false; } if (!ClassLineage.getExtensionData(target, settings)) { var extension = new ClassLineageExtensionData(); type_tools_1.TypeToolsBase.addExtension(target, ClassLineageSettings.extensionClassLineage, extension); } return true; }; ClassLineage.mapOut = function (target, settings) { if (settings === void 0) { settings = ClassLineageSettings; } if (!ClassLineage.implementOn(target, settings)) { return; } var lineage = ClassLineage.of(target); ClassLineage.getExtensionData(target, settings).lineage = lineage; return lineage; }; ClassLineage.mapOf = function (target) { return ClassLineage.of(target, null, null, true); }; ClassLineage.of = function (target, topDown, getAsNames, getAsMap) { if (topDown === void 0) { topDown = true; } if (getAsNames === void 0) { getAsNames = false; } if (getAsMap === void 0) { getAsMap = false; } var useCache = !ClassLineage.noCache; var lineage = []; var targetIsClass = !!target.prototype && !!target.constructor.name; if (targetIsClass) { if (useCache) { var cached = lineageCache[(0, common_iface_1.typeLocalName)(target)]; if (cached) { if (getAsMap) { return cached.mapped; } if (getAsNames) { return topDown ? cached.topDownNames : cached.bottomUpNames; } else { return topDown ? cached.topDown : cached.bottomUp; } } } target = type_tools_1.TypeToolsBase.getSampleInstance(target); } var node = Object.getPrototypeOf(target); var topType = node.constructor; if (useCache) { var cached2 = lineageCache[(0, common_iface_1.typeLocalName)(topType)]; if (cached2) { if (getAsMap) { return cached2.mapped; } if (getAsNames) { return topDown ? cached2.topDownNames : cached2.bottomUpNames; } else { return topDown ? cached2.topDown : cached2.bottomUp; } } } while (node && node.constructor.name !== 'Object') { lineage.push(node.constructor); node = Object.getPrototypeOf(node); } var mapped = {}; for (var _i = 0, lineage_1 = lineage; _i < lineage_1.length; _i++) { var cls = lineage_1[_i]; mapped[(0, common_iface_1.typeLocalName)(cls)] = cls; } var result = { topDown: lineage.reverse(), bottomUp: lineage, topDownNames: lineage.reverse().map(function (a) { return (0, common_iface_1.typeLocalName)(a); }), bottomUpNames: lineage.map(function (a) { return (0, common_iface_1.typeLocalName)(a); }), mapped: mapped }; if (useCache) { lineageCache[(0, common_iface_1.typeLocalName)(topType)] = result; } if (getAsMap) { return result.mapped; } if (getAsNames) { return topDown ? result.topDownNames : result.bottomUpNames; } else { return topDown ? result.topDown : result.bottomUp; } }; ClassLineage.typeOf = function (target) { return ClassLineage.of(target, false)[0]; }; ClassLineage.parentOf = function (target) { var parentClass = ClassLineage.of(target, false)[1]; return parentClass ? parentClass : null; }; ClassLineage.parentNameOf = function (target) { var parentClass = ClassLineage.of(target, false)[1]; return parentClass ? parentClass.name : null; }; ClassLineage.namesOf = function (target, topDown) { if (topDown === void 0) { topDown = true; } return ClassLineage.of(target, topDown, true); }; ClassLineage.commonAncestorsInfo = function (target1, target2) { var lineage1 = ClassLineage.of(target1, true); var lineage2 = ClassLineage.of(target2, true); var key = (0, common_iface_1.typeLocalName)(lineage1[0]) + ':' + (0, common_iface_1.typeLocalName)(lineage2[0]); if (!ClassLineage.noCache) { var cache = lcaCache[key]; if (cache) { return cache; } } var travel = 0; var closestMatch; for (var i = 0; i < lineage1.length; ++i) { var parent1 = lineage1[i]; for (var j = 0; j < lineage2.length; ++j) { var parent2 = lineage2[j]; if (parent1 === parent2) { var commonAncestors = lineage2.slice(j); var levelCompare = j - i; var levelDifference = Math.abs(levelCompare); var distance = i + j; var senior = (levelDifference === 0) ? null : (i > j) ? target2 : target1; var junior = (levelDifference === 0) ? null : (i < j) ? target2 : target1; if (!closestMatch || closestMatch.travel > travel) { closestMatch = { commonAncestors: commonAncestors, lastCommonAncestor: parent1, senior: senior, junior: junior, distance: distance, travel: travel, levelCompare: levelCompare, levelDifference: levelDifference, }; } } } ++travel; } if (!closestMatch) { closestMatch = { commonAncestors: [], lastCommonAncestor: null, senior: null, junior: null, distance: Infinity, travel: Infinity, levelCompare: NaN, levelDifference: NaN, }; } if (!ClassLineage.noCache) { lcaCache[key] = closestMatch; } return closestMatch; }; ClassLineage.lastCommonAncestor = function (target1, target2) { return ClassLineage.commonAncestorsInfo(target1, target2).lastCommonAncestor; }; ClassLineage.areRelated = function (target1, target2) { return ClassLineage.commonAncestorsInfo(target1, target2).lastCommonAncestor !== null; }; ClassLineage.recentConstructorName = function () { try { return new Error().stack.split('\n') .filter(function (line) { return line.indexOf('at new ') >= 0; })[0] .trim().split(' ')[2]; } catch (e) { return null; } }; ClassLineage.getContextSlow = function (target) { var name = ClassLineage.recentConstructorName(); var lineage = ClassLineage.of(target); for (var _i = 0, lineage_2 = lineage; _i < lineage_2.length; _i++) { var parent_1 = lineage_2[_i]; if (name === parent_1.name) { return parent_1; } } return null; }; ClassLineage.prototype.getExtensionData = function (target) { return ClassLineage.getExtensionData(target, this.settings); }; ClassLineage.prototype.typeCheck = function (target) { return ClassLineage.typeCheck(target, this.settings); }; ClassLineage.prototype.implementOn = function (target) { return ClassLineage.implementOn(target, this.settings); }; ClassLineage.prototype.mapOut = function (target) { return ClassLineage.mapOut(target, this.settings); }; ClassLineage.noCache = false; return ClassLineage; }()); context_1.Context.lineageMap = function (a) { return ClassLineage.of(a, null, null, true); }; context_1.Context.lineageHas = function (a, type) { var map = ClassLineage.of(a, null, null, true); return (map && map[(0, common_iface_1.typeLocalName)(type)]) ? true : false; }; //# sourceMappingURL=class-lineage.js.map