UNPKG

webgme-engine

Version:

WebGME server and Client API without a GUI

1,230 lines (1,086 loc) 117 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: client/gmeNodeSetter.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: client/gmeNodeSetter.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/*globals define*/ /*eslint-env browser*/ /** * @author kecso / https://github.com/kecso * @author pmeijer / https://github.com/pmeijer */ define([], function () { 'use strict'; function gmeNodeSetter(logger, state, saveRoot, storeNode, printCoreError) { function _logDeprecated(oldFn, newFn, isGetter, comment) { var typeToUse = isGetter ? 'gmeNode.' : 'gmeClient.', commentStr = comment ? comment : ''; //eslint-disable-next-line no-console console.warn('"gmeClient.' + oldFn + '" is deprecated and will eventually be removed, use "' + typeToUse + newFn + '" instead.' + commentStr); } function _getNode(path) { if (state.core &amp;&amp; state.nodes[path] &amp;&amp; typeof state.nodes[path].node === 'object') { return state.nodes[path].node; } } function _setAttrAndRegistry(node, desc) { var name; desc = desc || {}; if (desc.attributes) { for (name in desc.attributes) { if (Object.hasOwn(desc.attributes, name)) { state.core.setAttribute(node, name, desc.attributes[name]); } } } if (desc.registry) { for (name in desc.registry) { if (Object.hasOwn(desc.registry, name)) { state.core.setRegistry(node, name, desc.registry[name]); } } } } function _copyMultipleNodes(paths, parentNode, resultAsArray) { var copiedNodes, result = {}, resultArray = [], i, originalNodes = [], checkPaths = function () { var i, result = true; for (i = 0; i &lt; paths.length; i += 1) { result = result &amp;&amp; (state.nodes[paths[i]] &amp;&amp; typeof state.nodes[paths[i]].node === 'object'); } return result; }; if (parentNode &amp;&amp; checkPaths()) { for (i = 0; i &lt; paths.length; i += 1) { originalNodes.push(state.nodes[paths[i]].node); } copiedNodes = state.core.copyNodes(originalNodes, parentNode); if (copiedNodes instanceof Error) { return copiedNodes; } for (i = 0; i &lt; paths.length; i += 1) { result[paths[i]] = copiedNodes[i]; resultArray.push(storeNode(copiedNodes[i])); } } return resultAsArray ? resultArray : result; } /** * @description Method to set an attribute of a given node. * @memberOf Client * @instance * @param {string} path - The path of the node in question. * @param {string} name - The name of the attribute. * @param {any} value - The value of the attribute to be set. * @param {string} msg - The message that should be attached to the commit that covers this update. */ function setAttribute(path, name, value, msg) { var error, node = _getNode(path); if (node) { error = state.core.setAttribute(node, name, value); if (error instanceof Error) { printCoreError(error); return; } saveRoot(typeof msg === 'string' ? msg : 'setAttribute(' + path + ',' + name + ',' + JSON.stringify(value) + ')'); } } /** * @description Method to remove an attribute from a given node. * @memberOf Client * @instance * @param {string} path - The path of the node in question. * @param {string} name - The name of the attribute. * @param {string} msg - The message that should be attached to the commit that covers this update. */ function delAttribute(path, name, msg) { var error, node = _getNode(path); if (node) { error = state.core.delAttribute(node, name); if (error instanceof Error) { printCoreError(error); return; } saveRoot(typeof msg === 'string' ? msg : 'delAttribute(' + path + ',' + name + ')'); } } /** * @description Method to set a registry entry of a given node. * @memberOf Client * @instance * @param {string} path - The path of the node in question. * @param {string} name - The name of the registry. * @param {any} value - The value of the registry to be set. * @param {string} msg - The message that should be attached to the commit that covers this update. */ function setRegistry(path, name, value, msg) { var error, node = _getNode(path); if (node) { error = state.core.setRegistry(node, name, value); if (error instanceof Error) { printCoreError(error); return; } saveRoot(typeof msg === 'string' ? msg : 'setRegistry(' + path + ',' + name + ',' + JSON.stringify(value) + ')'); } } /** * @description Method to remove a registry entry of a given node. * @memberOf Client * @instance * @param {string} path - The path of the node in question. * @param {string} name - The name of the registry. * @param {string} msg - The message that should be attached to the commit that covers this update. */ function delRegistry(path, name, msg) { var error, node = _getNode(path); if (node) { error = state.core.delRegistry(node, name); if (error instanceof Error) { printCoreError(error); return; } saveRoot(typeof msg === 'string' ? msg : 'delRegistry(' + path + ',' + name + ')'); } } /** * @example * * var nodeCopy1 = client.copyNode('/4', ''); * var nodeCopy2 = client.copyNode('/4', '', { * attributes: { * name: 'CopiedNode' * }, * registry: { * position: {x: 100, y: 100} * } * }, 'Created node with specific name and position.'); * * @description Copies the given node into parent * (does not enforce meta-rules and requires all participating nodes to be loaded in the client) * @function copyNode * @memberOf Client * @param {string} path - the id/path of the node to copy * @param {string} parentId - the id/path of the parent where the new copy should be created * @param {object} [desc={}] - named attributes and/or registries to set for the new node (see example) * @param {object} [desc.attributes={}] - named attributes to set for the new node * @param {object} [desc.registry={}] - named registries to set for the new node * @param {string} [msg] - optional commit message, if not supplied a default one * with the function name and input parameters will be used * @returns {GMENode|undefined} - the newly created node if it could be copied * @instance */ function copyNode(path, parentPath, desc, msg) { var node = _getNode(path), parentNode = _getNode(parentPath), newNode, newPath; if (node &amp;&amp; parentNode) { newNode = state.core.copyNode(node, parentNode); if (newNode instanceof Error) { printCoreError(newNode); return; } _setAttrAndRegistry(newNode, desc); newPath = storeNode(newNode); saveRoot(typeof msg === 'string' ? msg : 'copyNode(' + path + ', ' + parentPath + ', ' + JSON.stringify(desc) + ')'); return newPath; } } /** * @example * * client.copyMoreNodes({ * parentId: '', * '/4': {}, * '/5': { * attributes: { * name: 'MyNamedCopy' * }, * registry: { * position: {x: 100, y:100} * } * } * }, 'Copied two nodes with some additional init data.'); * * @description Copies the given nodes into the parent (does not enforce meta-rules * and requires all participating nodes to be loaded in the client) * @function copyMoreNodes * @memberOf Client * @param {object} parameters - the parameters holding parentId and nodes to be copied * indexed by their ids/paths (see example) * @param {string} parameters.parentId - the id/path of the parent where the new copies should be created * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function copyMoreNodes(parameters, msg) { var pathsToCopy = [], parentNode = _getNode(parameters.parentId), nodePath, newNodes; if (parentNode) { for (nodePath in parameters) { if (Object.hasOwn(parameters, nodePath) &amp;&amp; nodePath !== 'parentId') { pathsToCopy.push(nodePath); } } msg = typeof msg === 'string' ? msg : 'copyMoreNodes(' + JSON.stringify(pathsToCopy) + ',' + parameters.parentId + ')'; if (pathsToCopy.length &lt; 1) { // empty on purpose } else if (pathsToCopy.length === 1) { copyNode(pathsToCopy[0], parameters.parentId, parameters[pathsToCopy[0]], msg); } else { newNodes = _copyMultipleNodes(pathsToCopy, parentNode); if (newNodes instanceof Error) { printCoreError(newNodes); return; } for (nodePath in newNodes) { if (Object.hasOwn(newNodes, nodePath) &amp;&amp; parameters[nodePath]) { _setAttrAndRegistry(newNodes[nodePath], parameters[nodePath]); } } saveRoot(msg); } } else { state.logger.error('wrong parameters for copy operation - denied -'); } } /** * @example * * client.moveMoreNodes({ * parentId: '', * '/4': {}, * '/5': { * attributes: { * name: 'MyNamedCopy' * }, * registry: { * position: {x: 100, y:100} * } * } * }, 'Copied two nodes with some additional init data.'); * * @description Moves the given nodes into the parent (does not enforce meta-rules * and requires all participating nodes to be loaded in the client) * @function moveMoreNodes * @memberOf Client * @param {object} parameters - the parameters holding parentId and nodes to be copied * indexed by their ids/paths (see example) * @param {string} parameters.parentId - the id/path of the parent where the new copies should be created * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function moveMoreNodes(parameters, msg) { var pathsToMove = [], returnParams = {}, i, newNode; for (i in parameters) { if (Object.hasOwn(parameters, i)) { if (i !== 'parentId') { pathsToMove.push(i); } } } if (pathsToMove.length > 0 &amp;&amp; typeof parameters.parentId === 'string' &amp;&amp; state.nodes[parameters.parentId] &amp;&amp; typeof state.nodes[parameters.parentId].node === 'object') { for (i = 0; i &lt; pathsToMove.length; i += 1) { if (state.nodes[pathsToMove[i]] &amp;&amp; typeof state.nodes[pathsToMove[i]].node === 'object') { newNode = state.core.moveNode(state.nodes[pathsToMove[i]].node, state.nodes[parameters.parentId].node); returnParams[pathsToMove[i]] = state.core.getPath(newNode); _setAttrAndRegistry(newNode, parameters[pathsToMove[i]]); delete state.nodes[pathsToMove[i]]; storeNode(newNode, true); } } } saveRoot(typeof msg === 'string' ? msg : 'moveMoreNodes(' + JSON.stringify(returnParams) + ')'); return returnParams; } /** * @example * * client.createChildren({ * parentId: '', * '/4': {}, * '/5': { * attributes: { * name: 'MyVeryOwnName' * }, * registry: { * position: {x: 100, y:100} * } * } * }, 'Created new children of the root based on the list of existing nodes.'); * * @description Creates instances as children of the parent node based on the list * of nodes among the parameters (does not enforce meta-rules * and requires all participating nodes to be loaded in the client). * @function createChildren * @memberOf Client * @param {object} parameters - the parameters holding parentId and nodes to be instantiated * indexed by their ids/paths (see example) * @param {string} parameters.parentId - the id/path of the parent where the new nodes should be created * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function createChildren(parameters, msg) { //TODO we also have to check out what is happening with the sets!!! var result = {}, paths = [], nodes = [], node, parent = state.nodes[parameters.parentId].node, names, i, j, index, pointer, newChildren = [], relations = []; //to allow 'meaningfull' instantiation of multiple objects // we have to recreate the internal relations - except the base paths = Object.keys(parameters); paths.splice(paths.indexOf('parentId'), 1); for (i = 0; i &lt; paths.length; i++) { node = state.nodes[paths[i]].node; nodes.push(node); pointer = {}; names = state.core.getPointerNames(node); index = names.indexOf('base'); if (index !== -1) { names.splice(index, 1); } for (j = 0; j &lt; names.length; j++) { index = paths.indexOf(state.core.getPointerPath(node, names[j])); if (index !== -1) { pointer[names[j]] = index; } } relations.push(pointer); } //now the instantiation for (i = 0; i &lt; nodes.length; i++) { newChildren.push(state.core.createNode({parent: parent, base: nodes[i]})); } //now for the storage and relation setting for (i = 0; i &lt; paths.length; i++) { _setAttrAndRegistry(newChildren[i], parameters[paths[i]]); //relations names = Object.keys(relations[i]); for (j = 0; j &lt; names.length; j++) { state.core.setPointer(newChildren[i], names[j], newChildren[relations[i][names[j]]]); } //store result[paths[i]] = storeNode(newChildren[i]); } msg = typeof msg === 'string' ? msg : 'createChildren(' + JSON.stringify(result) + ')'; saveRoot(msg); return result; } /** * @description Delete the given node. * @function deleteNode * @memberOf Client * @param {string} path - the path/id of the node to be deleted from the model. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function deleteNode(path, msg) { var node = _getNode(path); if (node) { state.core.deleteNode(node); saveRoot(typeof msg === 'string' ? msg : 'deleteNode(' + path + ')'); } } /** * @description Delete the given node. * @function deleteNodes * @memberOf Client * @param {string[]} paths - the path/id list of the nodes to be deleted from the model. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function deleteNodes(paths, msg) { var didDelete = false, i, node; for (i = 0; i &lt; paths.length; i++) { node = _getNode(paths[i]); if (node) { state.core.deleteNode(node); didDelete = true; } } if (didDelete) { saveRoot(typeof msg === 'string' ? msg : 'deleteNodes(' + paths + ')'); } } /** * @example * * client.createNode({ * parentId: '', * baseId:'/1', * guid:, * relid:'/aaa' * }, * { * attributes: { * name: 'MyVeryOwnName' * }, * registry: { * position: {x: 100, y:100} * } * }, * 'Created new node as the child of the root and instance of the FCO.'); * * @description Creates a new node based on the given parameters. * @function createNode * @memberOf Client * @param {object} parameters - the parameters holding necessary information for the creation. * @param {string} parameters.parentId - the path/id of the container of the new node. * @param {string} parameters.baseId - the path/id of the prototype of the new node. * @param {string} parameters.parentId - the id/path of the parent where the new nodes should be created * @param {string} [parameters.guid] - the unique identifier of the node we will create. * @param {string} [parameters.relid] - the relative id of the node we will create. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function createNode(parameters, desc, msg) { var parentNode = _getNode(parameters.parentId), baseNode = _getNode(parameters.baseId), newNode, newID; if (parentNode) { newNode = state.core.createNode({ parent: parentNode, base: baseNode, guid: parameters.guid, relid: parameters.relid }); if (newNode instanceof Error) { printCoreError(newNode); return; } // By default the position will be {100, 100} desc = desc || {}; desc.registry = desc.registry || {}; desc.registry.position = desc.registry.position || {}; desc.registry.position.x = (typeof desc.registry.position.x === 'number' || Number(desc.registry.position.x) + '' === desc.registry.position.x) ? Number(desc.registry.position.x) : 100; desc.registry.position.y = (typeof desc.registry.position.y === 'number' || Number(desc.registry.position.y) + '' === desc.registry.position.y) ? Number(desc.registry.position.y) : 100; _setAttrAndRegistry(newNode, desc); storeNode(newNode); newID = state.core.getPath(newNode); saveRoot(typeof msg === 'string' ? msg : 'createNode(' + parameters.parentId + ',' + parameters.baseId + ',' + newID + ')'); } return newID; } /** * @description Sets the value of the pointer of the given node. * @function setPointer * @memberOf Client * @param {string} path - the path/id of the node that we will modify. * @param {string} name - the name of the pointer to set. * @param {string|null} target - the id/path of the target node of the pointer. If * the value is null, there will be no target for the pointer. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function setPointer(path, name, target, msg) { var node = _getNode(path), targetNode; if (node) { if (target === null) { state.core.setPointer(node, name, target); } else { targetNode = _getNode(target); state.core.setPointer(node, name, targetNode); } saveRoot(typeof msg === 'string' ? msg : 'setPointer(' + path + ',' + name + ',' + target + ')'); } } /** * @description Removes the pointer of the given node. * Setting a pointer to null and deleting it is different! * (one is a value, the other means the absence of value) * @function delPointer * @memberOf Client * @param {string} path - the path/id of the node that we will modify. * @param {string} name - the name of the pointer to set. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function delPointer(path, name, msg) { var node = _getNode(path); if (node) { state.core.delPointer(node, name); saveRoot(typeof msg === 'string' ? msg : 'delPointer(' + path + ',' + name + ')'); } } // Mixed argument methods - START /** * @description Add a new member node to the given set of the * specified node. * @function addMember * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} memberPath - the path/id of the member node. * @param {string} setId - the name of the set to expand. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function addMember(path, memberPath, setId, msg) { // FIXME: This will have to break due to switched arguments var node = _getNode(path), memberNode = _getNode(memberPath); if (node &amp;&amp; memberNode) { state.core.addMember(node, setId, memberNode); saveRoot(typeof msg === 'string' ? msg : 'addMember(' + path + ',' + memberPath + ',' + setId + ')'); } } /** * @description Removes a member node from the given set of the * specified node. * @function removeMember * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} memberPath - the path/id of the member node. * @param {string} setId - the name of the set to expand. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function removeMember(path, memberPath, setId, msg) { // FIXME: This will have to break due to switched arguments (sort of) var node = _getNode(path); if (node) { state.core.delMember(node, setId, memberPath); saveRoot(typeof msg === 'string' ? msg : 'removeMember(' + path + ',' + memberPath + ',' + setId + ')'); } } /** * @description Set the given attribute value that is connected to the membership * (not the member node, so it only has a meaning in the context of the membership). * @function setMemberAttribute * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} memberPath - the path/id of the member node. * @param {string} setId - the name of the set where the member exists. * @param {string} name - the name of the attribute. * @param {object|string|null} value - the value of the attribute. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function setMemberAttribute(path, memberPath, setId, name, value, msg) { // FIXME: This will have to break due to switched arguments var node = _getNode(path); if (node) { state.core.setMemberAttribute(node, setId, memberPath, name, value); saveRoot(typeof msg === 'string' ? msg : 'setMemberAttribute(' + [path, memberPath, setId, name, value].join(',') + ')'); } } /** * @description Removes the given attribute that is connected to the membership * from the node. * @function delMemberAttribute * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} memberPath - the path/id of the member node. * @param {string} setId - the name of the set to expand. * @param {string} name - the name of the attribute. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function delMemberAttribute(path, memberPath, setId, name, msg) { // FIXME: This will have to break due to switched arguments var node = _getNode(path); if (node) { state.core.delMemberAttribute(node, setId, memberPath, name); saveRoot(typeof msg === 'string' ? msg : 'delMemberAttribute(' + [path, memberPath, setId, name].join(',') + ')'); } } /** * @description Set the given registry value that is connected to the membership * (not the member node, so it only has a meaning in the context of the membership). * @function setMemberRegistry * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} memberPath - the path/id of the member node. * @param {string} setId - the name of the set to expand. * @param {string} name - the name of the registry. * @param {object|string|null} value - the value of the registry. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function setMemberRegistry(path, memberPath, setId, name, value, msg) { // FIXME: This will have to break due to switched arguments var node = _getNode(path); if (node) { state.core.setMemberRegistry(node, setId, memberPath, name, value); saveRoot(typeof msg === 'string' ? msg : 'setMemberRegistry(' + path + ',' + memberPath + ',' + setId + ',' + name + ',' + JSON.stringify(value) + ')'); } } /** * @description Removes the given registry that is connected to the membership * from the node. * @function delMemberRegistry * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} memberPath - the path/id of the member node. * @param {string} setId - the name of the set to expand. * @param {string} name - the name of the registry. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function delMemberRegistry(path, memberPath, setId, name, msg) { // FIXME: This will have to break due to switched arguments var node = _getNode(path); if (node) { state.core.delMemberRegistry(node, setId, memberPath, name); saveRoot(typeof msg === 'string' ? msg : 'delMemberRegistry(' + path + ',' + memberPath + ',' + setId + ',' + name + ')'); } } // Mixed argument methods - END /** * @description Set the given attribute value of the set of the node * (the value is connected to the node, but only in the context of the set). * @function setSetAttribute * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} setName - the name of the set where the member exists. * @param {string} attrName - the name of the attribute. * @param {object|string|null} attrValue - the value of the attribute. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function setSetAttribute(path, setName, attrName, attrValue, msg) { var node = _getNode(path); if (node) { state.core.setSetAttribute(node, setName, attrName, attrValue); saveRoot(typeof msg === 'string' ? msg : 'setSetAttribute(' + path + ',' + setName + ',' + attrName + ',' + JSON.stringify(attrValue) + ')'); } } /** * @description Removes the given attribute that is connected to set of the node. * @function delSetAttribute * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} setName - the name of the set to change. * @param {string} attrName - the name of the attribute. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function delSetAttribute(path, setName, attrName, msg) { var node = _getNode(path); if (node) { state.core.delSetAttribute(node, setName, attrName); saveRoot(typeof msg === 'string' ? msg : 'delSetAttribute(' + path + ',' + setName + ',' + attrName + ')'); } } /** * @description Set the given registry value of the set of the node * (the value is connected to the node, but only in the context of the set). * @function setSetRegistry * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} setName - the name of the set where the member exists. * @param {string} regName - the name of the registry. * @param {object|string|null} regValue - the value of the registry. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function setSetRegistry(path, setName, regName, regValue, msg) { var node = _getNode(path); if (node) { state.core.setSetRegistry(node, setName, regName, regValue); saveRoot(typeof msg === 'string' ? msg : 'setSetRegistry(' + [path, setName, regName, JSON.stringify(regValue)].join(',') + ')'); } } /** * @description Removes the given registry that is connected to set of the node. * @function delSetRegistry * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} setName - the name of the set to change. * @param {string} attrName - the name of the registry. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function delSetRegistry(path, setName, regName, msg) { var node = _getNode(path); if (node) { state.core.delSetRegistry(node, setName, regName); saveRoot(typeof msg === 'string' ? msg : 'delSetRegistry(' + path + ',' + setName + ',' + regName + ')'); } } /** * @description Creates a set that belongs to the node. * @function createSet * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} setId - the name of the set. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function createSet(path, setId, msg) { var node = _getNode(path); if (node) { state.core.createSet(node, setId); saveRoot(typeof msg === 'string' ? msg : 'createSet(' + path + ',' + setId + ')'); } } /** * @description Removes a set that belongs to the node. * @function delSet * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} setId - the name of the set. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function delSet(path, setId, msg) { var node = _getNode(path), error; if (node) { error = state.core.delSet(node, setId); if (error instanceof Error) { printCoreError(error); return; } saveRoot(typeof msg === 'string' ? msg : 'delSet(' + path + ',' + setId + ')'); } } /** * @description Changes the prototype node of the node. * This function should only be used with care! * @function setBase * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} basePath - the path/id of the new prototype node. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function setBase(path, basePath, msg) { var node = _getNode(path), baseNode = _getNode(basePath), error; if (node &amp;&amp; baseNode) { error = state.core.setBase(node, baseNode); if (error instanceof Error) { printCoreError(error); return; } saveRoot(typeof msg === 'string' ? msg : 'setBase(' + path + ',' + basePath + ')'); } } /** * @description Moves a node into a new container. * @function moveNode * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} parentPath - the path/id of the new container node. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function moveNode(path, parentPath, msg) { var node = _getNode(path), parentNode = _getNode(parentPath), movedPath; if (node &amp;&amp; parentNode) { movedPath = storeNode(state.core.moveNode(node, parentNode)); saveRoot(typeof msg === 'string' ? msg : 'moveNode(' + path + ',' + parentPath + ')'); } return movedPath; } /** * @description Removes teh prototype ofd the node. Do not use this function * as it is very dangerous! * @function delBase * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function delBase(path, msg) { var node = _getNode(path), error; if (node) { error = state.core.setBase(node, null); if (error instanceof Error) { printCoreError(error); return; } saveRoot(typeof msg === 'string' ? msg : 'delBase(' + path + ')'); } } // META functions /** * @description Returns the JSON based meta description of the node. * @function getMeta * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function getMeta(path) { var node = _getNode(path), meta = {children: {}, attributes: {}, pointers: {}, aspects: {}}; if (!node) { return null; } meta = state.core.getJsonMeta(node); return meta; } /** * @description Set all the meta rules of a node based on a JSON. * It has no effect on the inherited rules! * @function setMeta * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {object} meta - the directory of rules to be set. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function setMeta(path, meta, msg) { var node = _getNode(path), otherNode, name, i, error; if (node) { state.core.clearMetaRules(node); //children if (meta.children &amp;&amp; meta.children.items &amp;&amp; meta.children.items.length > 0) { error = state.core.setChildrenMetaLimits(node, meta.children.min, meta.children.max); if (error instanceof Error) { printCoreError(error); return; } for (i = 0; i &lt; meta.children.items.length; i += 1) { otherNode = _getNode(meta.children.items[i]); if (otherNode) { error = state.core.setChildMeta(node, otherNode, meta.children.minItems[i], meta.children.maxItems[i]); if (error instanceof Error) { printCoreError(error); return; } } } } //attributes if (meta.attributes) { for (i in meta.attributes) { error = state.core.setAttributeMeta(node, i, meta.attributes[i]); if (error instanceof Error) { printCoreError(error); return; } } } //pointers and sets if (meta.pointers) { for (name in meta.pointers) { if (meta.pointers[name].items &amp;&amp; meta.pointers[name].items.length > 0) { error = state.core.setPointerMetaLimits(node, name, meta.pointers[name].min, meta.pointers[name].max); if (error instanceof Error) { printCoreError(error); return; } for (i = 0; i &lt; meta.pointers[name].items.length; i += 1) { otherNode = _getNode(meta.pointers[name].items[i]); if (otherNode) { error = state.core.setPointerMetaTarget(node, name, otherNode, meta.pointers[name].minItems[i], meta.pointers[name].maxItems[i]); if (error instanceof Error) { printCoreError(error); return; } } } } } } //aspects if (meta.aspects) { for (name in meta.aspects) { for (i = 0; i &lt; meta.aspects[name].length; i += 1) { otherNode = _getNode(meta.aspects[name][i]); if (otherNode) { error = state.core.setAspectMetaTarget(node, name, otherNode); if (error instanceof Error) { printCoreError(error); return; } } } } } //constraints if (meta.constraints) { for (name in meta.constraints) { if (typeof meta.constraints[name] === 'object') { error = state.core.setConstraint(node, name, meta.constraints[name]); if (error instanceof Error) { printCoreError(error); return; } } } } saveRoot(typeof msg === 'string' ? msg : 'setMeta(' + path + ')'); } } /** * @description Removes all Meta rules from the node (does not have effect on the inherited rules). * @function clearMetaRules * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function clearMetaRules(path, msg) { var node = _getNode(path); if (node) { state.core.clearMetaRules(node); saveRoot(typeof msg === 'string' ? msg : 'clearMetaRules(' + path + ')'); } } /** * @description Creates a mixin connection to the node. * @function addMixin * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} addMixin - the path/id of the mixin node. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function addMixin(path, mixinPath, msg) { var error, node = _getNode(path); if (node) { error = state.core.addMixin(node, mixinPath); if (error instanceof Error) { printCoreError(error); return; } saveRoot(typeof msg === 'string' ? msg : 'addMixin(' + path + ',' + mixinPath + ')'); } } /** * @description Removes a mixin connection from the node. * @function delMixin * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} addMixin - the path/id of the mixin node. * @param {string} [msg] - optional commit message, if not supplied a default one with the * function name and input parameters will be used * @instance */ function delMixin(path, mixinPath, msg) { var error, node = _getNode(path); if (node) { error = state.core.delMixin(node, mixinPath); if (error instanceof Error) { printCoreError(error); return; } saveRoot(typeof msg === 'string' ? msg : 'delMixin(' + path + ',' + mixinPath + ')'); } } //TODO add function description function setChildrenMetaAttribute(path, attrName, value, msg) { if (attrName !== 'items') { var rawMeta = getMeta(path); rawMeta.children[attrName] = value; setMeta(path, rawMeta, msg); } } /** * @description Creates a containment rule for the node. * @function setChildMeta * @memberOf Client * @param {string} path - the path/id of the node that will be modified. * @param {string} childPath - the path/id of the child node. * @param {number} min - the minimum allowed number of children of this type. * -1 means that there is no lower limit. * @param {number} max - the maximum allowed number of children of this type. * -1 ,eams there is no upper limit.