UNPKG

inheritance-diagram

Version:

Build an inheritance diagram for a class

145 lines (123 loc) 2.97 kB
/* * Copyright (c) 2016-2020 Valerii Zinchenko * Licensed under MIT (https://gitlab.com/valerii-zinchenko/inheritance-diagram/blob/master/LICENSE.txt) * All source files are available at: https://gitlab.com/valerii-zinchenko/inheritance-diagram */ const {Class} = require('class-wrapper/dest/class-wrapper.amd'); /** * Node is valid if is as non-zero length string name or is already an instance of a GraphNode class. * * @param {*} item - Thing to check. * @return {boolean} */ function isNodeValid(item) { // eslint-disable-next-line no-use-before-define return (typeof item === 'string' && item.length > 0) || item instanceof GraphNode; } /** * Graph node. * * @class GraphNode * * @param {string} name - Node name. * @param {Objcet} data - Raw node data. * @param {Object} data.parent - Parent node. * @param {Object[]} data.children - Children nodes. * @param {Object[]} data.implements - Nodes of implemented interfaces. * @param {Object[]} data.mixes - Mixed in nodes. * @param {Object} [properties] - Properties for a graph node. * @param {string} [properties.type] - Node type. * @param {Object[]} [properties.parentStack] - Stack of parents. */ const GraphNode = Class(function(name, data, properties) { if (typeof name !== 'string' || name.length === 0) { throw new TypeError('Invalid node name. It is expected a string with a length > 0'); } this.name = name; if (data) { this.data = data; const {parent, children, mixes} = data; const impls = data.implements; // set references to some raw data properties for easier access // -------------------------------------------------- if (isNodeValid(parent)) { this.parent = parent; } if (children) { this.children = children.filter(isNodeValid); } if (impls) { this.implements = impls.filter(isNodeValid); } if (mixes) { this.mixes = mixes.filter(isNodeValid); } // -------------------------------------------------- } if (properties) { const {type, parentStack} = properties; if (type) { this.type = type; } if (parentStack) { this.parentStack = parentStack.filter(isNodeValid); } } }, /** @lends GraphNode.prototype */{ __name: 'GraphNode ', /** * Node data. * * @type {Object} */ data: {}, /** * Node name. * * @type {String} */ name: '', /** * Name of parent node. * * @type {String} */ parent: '', /** * An array of children node names. * * @type {String[]} */ children: [], /** * An array of mixin node names. * * @type {String[]} */ mixes: [], /** * An array of interface node names. * * @type {String[]} */ implements: [], /** * Type of a node. * * Supported types: * * noi - node of interest * * parent - parent node * * child - child node * * mixin - mixed in node * * @type {String} */ type: '', /** * Stack of parent nodes. * * @type {GraphNode} */ parentStack: [] }); module.exports = GraphNode;