mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Add add/update/delete flow apis
This commit is contained in:
parent
fd2e47ed73
commit
c4b1795396
@ -26,7 +26,64 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
get: function(req,res) {
|
get: function(req,res) {
|
||||||
var id = req.params.id;
|
var id = req.params.id;
|
||||||
log.audit({event: "flow.get"},req);
|
var flow = redNodes.getFlow(id);
|
||||||
res.json(redNodes.getFlow(id));
|
if (flow) {
|
||||||
|
log.audit({event: "flow.get",id:id},req);
|
||||||
|
res.json(flow);
|
||||||
|
} else {
|
||||||
|
log.audit({event: "flow.get",id:id,error:"not_found"},req);
|
||||||
|
res.status(404).end();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
post: function(req,res) {
|
||||||
|
var flow = req.body;
|
||||||
|
redNodes.addFlow(flow).then(function(id) {
|
||||||
|
log.audit({event: "flow.add",id:id},req);
|
||||||
|
res.json({id:id});
|
||||||
|
}).otherwise(function(err) {
|
||||||
|
log.audit({event: "flow.add",error:err.code||"unexpected_error",message:err.toString()},req);
|
||||||
|
res.status(400).json({error:err.code||"unexpected_error", message:err.toString()});
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
put: function(req,res) {
|
||||||
|
var id = req.params.id;
|
||||||
|
var flow = req.body;
|
||||||
|
try {
|
||||||
|
redNodes.updateFlow(id,flow).then(function() {
|
||||||
|
log.audit({event: "flow.update",id:id},req);
|
||||||
|
res.json({id:id});
|
||||||
|
}).otherwise(function(err) {
|
||||||
|
console.log(err.stack);
|
||||||
|
log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()},req);
|
||||||
|
res.status(400).json({error:err.code||"unexpected_error", message:err.toString()});
|
||||||
|
})
|
||||||
|
} catch(err) {
|
||||||
|
if (err.code === 404) {
|
||||||
|
log.audit({event: "flow.update",id:id,error:"not_found"},req);
|
||||||
|
res.status(404).end();
|
||||||
|
} else {
|
||||||
|
console.log(err.stack);
|
||||||
|
log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()},req);
|
||||||
|
res.status(400).json({error:err.code||"unexpected_error", message:err.toString()});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
delete: function(req,res) {
|
||||||
|
var id = req.params.id;
|
||||||
|
try {
|
||||||
|
redNodes.removeFlow(id).then(function() {
|
||||||
|
log.audit({event: "flow.remove",id:id},req);
|
||||||
|
res.status(204).end();
|
||||||
|
})
|
||||||
|
} catch(err) {
|
||||||
|
if (err.code === 404) {
|
||||||
|
log.audit({event: "flow.remove",id:id,error:"not_found"},req);
|
||||||
|
res.status(404).end();
|
||||||
|
} else {
|
||||||
|
log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()},req);
|
||||||
|
res.status(400).json({error:err.code||"unexpected_error", message:err.toString()});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,9 @@ function init(_server,runtime) {
|
|||||||
adminApp.post("/flows",needsPermission("flows.write"),flows.post);
|
adminApp.post("/flows",needsPermission("flows.write"),flows.post);
|
||||||
|
|
||||||
adminApp.get("/flow/:id",needsPermission("flows.read"),flow.get);
|
adminApp.get("/flow/:id",needsPermission("flows.read"),flow.get);
|
||||||
|
adminApp.post("/flow",needsPermission("flows.write"),flow.post);
|
||||||
|
adminApp.delete("/flow/:id",needsPermission("flows.write"),flow.delete);
|
||||||
|
adminApp.put("/flow/:id",needsPermission("flows.write"),flow.put);
|
||||||
|
|
||||||
// Nodes
|
// Nodes
|
||||||
adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll);
|
adminApp.get("/nodes",needsPermission("nodes.read"),nodes.getAll);
|
||||||
|
@ -121,6 +121,7 @@ module.exports = {
|
|||||||
var nodeType = node.type;
|
var nodeType = node.type;
|
||||||
var newCreds = node.credentials;
|
var newCreds = node.credentials;
|
||||||
if (newCreds) {
|
if (newCreds) {
|
||||||
|
delete node.credentials;
|
||||||
var savedCredentials = credentialCache[nodeID] || {};
|
var savedCredentials = credentialCache[nodeID] || {};
|
||||||
var dashedType = nodeType.replace(/\s+/g, '-');
|
var dashedType = nodeType.replace(/\s+/g, '-');
|
||||||
var definition = credentialsDef[dashedType];
|
var definition = credentialsDef[dashedType];
|
||||||
@ -145,7 +146,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
credentialCache[nodeID] = savedCredentials;
|
credentialCache[nodeID] = savedCredentials;
|
||||||
delete node.credentials;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ function Flow(global,flow) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (diff) {
|
if (diff && diff.rewired) {
|
||||||
for (var j=0;j<diff.rewired.length;j++) {
|
for (var j=0;j<diff.rewired.length;j++) {
|
||||||
var rewireNode = activeNodes[diff.rewired[j]];
|
var rewireNode = activeNodes[diff.rewired[j]];
|
||||||
if (rewireNode) {
|
if (rewireNode) {
|
||||||
@ -262,7 +262,6 @@ function mapEnvVarProperties(obj,prop) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createNode(type,config) {
|
function createNode(type,config) {
|
||||||
// console.log("CREATE",type,config.id);
|
|
||||||
var nn = null;
|
var nn = null;
|
||||||
var nt = typeRegistry.get(type);
|
var nt = typeRegistry.get(type);
|
||||||
if (nt) {
|
if (nt) {
|
||||||
|
@ -200,6 +200,7 @@ function handleStatus(node,statusMessage) {
|
|||||||
|
|
||||||
|
|
||||||
function start(type,diff) {
|
function start(type,diff) {
|
||||||
|
//dumpActiveNodes();
|
||||||
type = type||"full";
|
type = type||"full";
|
||||||
started = true;
|
started = true;
|
||||||
var i;
|
var i;
|
||||||
@ -231,14 +232,18 @@ function start(type,diff) {
|
|||||||
}
|
}
|
||||||
var id;
|
var id;
|
||||||
if (!diff) {
|
if (!diff) {
|
||||||
activeFlows['_GLOBAL_'] = Flow.create(activeFlowConfig);
|
if (!activeFlows['global']) {
|
||||||
|
activeFlows['global'] = Flow.create(activeFlowConfig);
|
||||||
|
}
|
||||||
for (id in activeFlowConfig.flows) {
|
for (id in activeFlowConfig.flows) {
|
||||||
if (activeFlowConfig.flows.hasOwnProperty(id)) {
|
if (activeFlowConfig.flows.hasOwnProperty(id)) {
|
||||||
|
if (!activeFlows[id]) {
|
||||||
activeFlows[id] = Flow.create(activeFlowConfig,activeFlowConfig.flows[id]);
|
activeFlows[id] = Flow.create(activeFlowConfig,activeFlowConfig.flows[id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
activeFlows['_GLOBAL_'].update(activeFlowConfig,activeFlowConfig);
|
activeFlows['global'].update(activeFlowConfig,activeFlowConfig);
|
||||||
for (id in activeFlowConfig.flows) {
|
for (id in activeFlowConfig.flows) {
|
||||||
if (activeFlowConfig.flows.hasOwnProperty(id)) {
|
if (activeFlowConfig.flows.hasOwnProperty(id)) {
|
||||||
if (activeFlows[id]) {
|
if (activeFlows[id]) {
|
||||||
@ -352,7 +357,34 @@ function checkTypeInUse(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateMissingTypes() {
|
||||||
|
var subflowInstanceRE = /^subflow:(.+)$/;
|
||||||
|
activeFlowConfig.missingTypes = [];
|
||||||
|
|
||||||
|
for (var id in activeFlowConfig.allNodes) {
|
||||||
|
if (activeFlowConfig.allNodes.hasOwnProperty(id)) {
|
||||||
|
var node = activeFlowConfig.allNodes[id];
|
||||||
|
if (node.type !== 'tab' && node.type !== 'subflow') {
|
||||||
|
var subflowDetails = subflowInstanceRE.exec(node.type);
|
||||||
|
if ( (subflowDetails && !activeFlowConfig.subflows[subflowDetails[1]]) || (!subflowDetails && !typeRegistry.get(node.type)) ) {
|
||||||
|
if (activeFlowConfig.missingTypes.indexOf(node.type) === -1) {
|
||||||
|
activeFlowConfig.missingTypes.push(node.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// function dumpActiveNodes() {
|
||||||
|
// console.log("--------")
|
||||||
|
// for (var i in activeFlowConfig.allNodes) {
|
||||||
|
// console.log(i,activeFlowConfig.allNodes[i].type,activeFlowConfig.allNodes[i].z)
|
||||||
|
// }
|
||||||
|
// console.log("--------")
|
||||||
|
// }
|
||||||
function addFlow(flow) {
|
function addFlow(flow) {
|
||||||
|
//dumpActiveNodes();
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
id:'',
|
id:'',
|
||||||
@ -364,12 +396,10 @@ function addFlow(flow) {
|
|||||||
|
|
||||||
// flow.id should not exist - it will be assigned by the runtime
|
// flow.id should not exist - it will be assigned by the runtime
|
||||||
// all flow.{subflows|configs|nodes}.z will be set to flow.id
|
// all flow.{subflows|configs|nodes}.z will be set to flow.id
|
||||||
// all nodes will have new ids assigned if there is a clash
|
|
||||||
// check all known types - fail if otherwise?
|
// check all known types - fail if otherwise?
|
||||||
//
|
//
|
||||||
// resolves with generated flow id
|
// resolves with generated flow id
|
||||||
|
|
||||||
return when.promise(function(resolve,reject) {
|
|
||||||
var i,id,node;
|
var i,id,node;
|
||||||
|
|
||||||
flow.id = redUtil.generateId();
|
flow.id = redUtil.generateId();
|
||||||
@ -378,55 +408,202 @@ function addFlow(flow) {
|
|||||||
node = flow.nodes[i];
|
node = flow.nodes[i];
|
||||||
if (activeFlowConfig.allNodes[node.id]) {
|
if (activeFlowConfig.allNodes[node.id]) {
|
||||||
// TODO nls
|
// TODO nls
|
||||||
return reject(new Error('duplicate id'));
|
return when.reject(new Error('duplicate id'));
|
||||||
}
|
}
|
||||||
node.z = flow.id;
|
node.z = flow.id;
|
||||||
}
|
}
|
||||||
|
if (flow.configs) {
|
||||||
|
for (i=0;i<flow.configs.length;i++) {
|
||||||
|
node = flow.configs[i];
|
||||||
|
if (activeFlowConfig.allNodes[node.id]) {
|
||||||
|
// TODO nls
|
||||||
|
return when.reject(new Error('duplicate id'));
|
||||||
|
}
|
||||||
|
node.z = flow.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
var tabNode = {
|
var tabNode = {
|
||||||
type:'tab',
|
type:'tab',
|
||||||
label:flow.label,
|
label:flow.label,
|
||||||
id:flow.id
|
id:flow.id
|
||||||
}
|
}
|
||||||
var nodes = [tabNode].concat(flow.nodes);
|
var nodes = [tabNode].concat(flow.nodes||[]).concat(flow.configs||[]);
|
||||||
|
var credentialSavePromise;
|
||||||
|
var credentialsChanged = false;
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
if (node.credentials) {
|
||||||
|
credentials.extract(node);
|
||||||
|
credentialsChanged = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (credentialsChanged) {
|
||||||
|
credentialSavePromise = credentials.save();
|
||||||
|
} else {
|
||||||
|
credentialSavePromise = when.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
var parsedConfig = flowUtil.parseConfig(clone(nodes));
|
var parsedConfig = flowUtil.parseConfig(clone(nodes));
|
||||||
// TODO: handle unknown type
|
parsedConfig.missingTypes.forEach(function(type) {
|
||||||
for (id in parsedConfig.flows[flow.id]) {
|
if (activeFlowConfig.missingTypes.indexOf(type) == -1) {
|
||||||
if (parsedConfig.flows[flow.id].hasOwnProperty(id)) {
|
activeFlowConfig.missingTypes.push(type);
|
||||||
activeFlowConfig.allNodes[id] = parsedConfig.flows[flow.id][id];
|
}
|
||||||
|
})
|
||||||
|
activeFlowConfig.allNodes[tabNode.id] = tabNode;
|
||||||
|
for (id in parsedConfig.flows[flow.id].nodes) {
|
||||||
|
if (parsedConfig.flows[flow.id].nodes.hasOwnProperty(id)) {
|
||||||
|
activeFlowConfig.allNodes[id] = parsedConfig.flows[flow.id].nodes[id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (parsedConfig.flows[flow.id].configs) {
|
||||||
|
for (id in parsedConfig.flows[flow.id].configs) {
|
||||||
|
if (parsedConfig.flows[flow.id].configs.hasOwnProperty(id)) {
|
||||||
|
activeFlowConfig.allNodes[id] = parsedConfig.flows[flow.id].configs[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
activeFlowConfig.flows[flow.id] = parsedConfig.flows[flow.id];
|
activeFlowConfig.flows[flow.id] = parsedConfig.flows[flow.id];
|
||||||
|
|
||||||
activeConfig = activeConfig.concat(nodes);
|
activeConfig = activeConfig.concat(nodes);
|
||||||
// TODO: extract creds
|
// TODO: extract creds
|
||||||
// TODO: save config
|
return credentialSavePromise.then(function() {
|
||||||
|
return storage.saveFlows(activeConfig).then(function() {
|
||||||
start("flows",{added:flow.nodes.map(function(n) { return n.id})}).then(function() {
|
return start("flows",{added:flow.nodes.map(function(n) { return n.id})}).then(function() {
|
||||||
|
//dumpActiveNodes();
|
||||||
// console.log(activeFlowConfig);
|
// console.log(activeFlowConfig);
|
||||||
resolve(flow.id);
|
return flow.id;
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFlow(id) {
|
function getFlow(id) {
|
||||||
var flow = activeFlowConfig.flows[id];
|
var flow;
|
||||||
|
if (id === 'global') {
|
||||||
|
flow = activeFlowConfig;
|
||||||
|
} else {
|
||||||
|
flow = activeFlowConfig.flows[id];
|
||||||
|
}
|
||||||
if (!flow) {
|
if (!flow) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var result = {
|
var result = {
|
||||||
id: id,
|
id: id
|
||||||
label: flow.label,
|
|
||||||
nodes: []
|
|
||||||
};
|
};
|
||||||
|
if (flow.label) {
|
||||||
for (var i=0;i<activeConfig.length;i++) {
|
result.label = flow.label;
|
||||||
if (activeConfig[i].z === id && activeConfig[i].type != 'tab') {
|
|
||||||
result.nodes.push(activeConfig[i]);
|
|
||||||
}
|
}
|
||||||
|
if (flow.nodes) {
|
||||||
|
var nodeIds = Object.keys(flow.nodes);
|
||||||
|
if (nodeIds.length > 0) {
|
||||||
|
result.nodes = nodeIds.map(function(nodeId) {
|
||||||
|
return clone(flow.nodes[nodeId]);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flow.configs) {
|
||||||
|
var configIds = Object.keys(flow.configs);
|
||||||
|
result.configs = configIds.map(function(configId) {
|
||||||
|
return clone(flow.configs[configId]);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (flow.subflows) {
|
||||||
|
var subflowIds = Object.keys(flow.subflows);
|
||||||
|
result.subflows = subflowIds.map(function(subflowId) {
|
||||||
|
var subflow = clone(flow.subflows[subflowId]);
|
||||||
|
var nodeIds = Object.keys(subflow.nodes);
|
||||||
|
subflow.nodes = nodeIds.map(function(id) {
|
||||||
|
return subflow.nodes[id];
|
||||||
|
});
|
||||||
|
if (subflow.configs) {
|
||||||
|
var configIds = Object.keys(subflow.configs);
|
||||||
|
subflow.configs = configIds.map(function(id) {
|
||||||
|
return subflow.configs[id];
|
||||||
|
})
|
||||||
|
}
|
||||||
|
delete subflow.instances;
|
||||||
|
return subflow;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
function updateFlow(id,newFlow) {
|
||||||
|
if (id === 'global') {
|
||||||
|
// TODO: handle global update
|
||||||
|
throw new Error('not allowed to update global');
|
||||||
|
}
|
||||||
|
|
||||||
|
var flow = activeFlowConfig.flows[id];
|
||||||
|
if (!flow) {
|
||||||
|
var e = new Error();
|
||||||
|
e.code = 404;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
var newConfig = clone(activeConfig);
|
||||||
|
newConfig = newConfig.filter(function(node) {
|
||||||
|
return node.z !== id && node.id !== id;
|
||||||
|
});
|
||||||
|
|
||||||
|
var tabNode = {
|
||||||
|
type:'tab',
|
||||||
|
label:newFlow.label,
|
||||||
|
id:id
|
||||||
|
}
|
||||||
|
var nodes = [tabNode].concat(newFlow.nodes||[]).concat(newFlow.configs||[]);
|
||||||
|
nodes.forEach(function(n) {
|
||||||
|
n.z = id;
|
||||||
|
});
|
||||||
|
newConfig = newConfig.concat(nodes);
|
||||||
|
|
||||||
|
return setConfig(newConfig,'flows');
|
||||||
|
|
||||||
|
// filter activeConfig to remove nodes
|
||||||
|
|
||||||
|
}
|
||||||
|
function removeFlow(id) {
|
||||||
|
if (id === 'global') {
|
||||||
|
// TODO: nls + error code
|
||||||
|
throw new Error('not allowed to remove global');
|
||||||
|
}
|
||||||
|
var flow = activeFlowConfig.flows[id];
|
||||||
|
if (!flow) {
|
||||||
|
var e = new Error();
|
||||||
|
e.code = 404;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
var diff = {
|
||||||
|
removed: [id].concat(Object.keys(flow.nodes)).concat(Object.keys(flow.configs)),
|
||||||
|
linked:[],
|
||||||
|
changed:[]
|
||||||
|
}
|
||||||
|
|
||||||
|
delete activeFlowConfig.flows[id];
|
||||||
|
|
||||||
|
diff.removed.forEach(function(id) {
|
||||||
|
delete activeFlowConfig.allNodes[id];
|
||||||
|
});
|
||||||
|
|
||||||
|
activeConfig = activeConfig.filter(function(node) {
|
||||||
|
return node.z !== id && node.id !== id;
|
||||||
|
});
|
||||||
|
|
||||||
|
var missingTypeCount = activeFlowConfig.missingTypes.length;
|
||||||
|
updateMissingTypes();
|
||||||
|
|
||||||
|
return credentials.clean(activeConfig).then(function() {
|
||||||
|
storage.saveFlows(activeConfig).then(function() {
|
||||||
|
stop("flows",diff).then(function() {
|
||||||
|
if (missingTypeCount > 0 && activeFlowConfig.missingTypes.length === 0) {
|
||||||
|
return start();
|
||||||
|
}
|
||||||
|
//dumpActiveNodes();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: init,
|
init: init,
|
||||||
|
|
||||||
@ -470,11 +647,10 @@ module.exports = {
|
|||||||
|
|
||||||
checkTypeInUse: checkTypeInUse,
|
checkTypeInUse: checkTypeInUse,
|
||||||
|
|
||||||
|
|
||||||
addFlow: addFlow,
|
addFlow: addFlow,
|
||||||
getFlow: getFlow,
|
getFlow: getFlow,
|
||||||
updateFlow:null,
|
updateFlow: updateFlow,
|
||||||
removeFlow:null,
|
removeFlow: removeFlow,
|
||||||
disableFlow:null,
|
disableFlow:null,
|
||||||
enableFlow:null
|
enableFlow:null
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ module.exports = {
|
|||||||
if (flow.missingTypes.indexOf(n.type) === -1) {
|
if (flow.missingTypes.indexOf(n.type) === -1) {
|
||||||
flow.missingTypes.push(n.type);
|
flow.missingTypes.push(n.type);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
var container = null;
|
var container = null;
|
||||||
if (flow.flows[n.z]) {
|
if (flow.flows[n.z]) {
|
||||||
container = flow.flows[n.z];
|
container = flow.flows[n.z];
|
||||||
@ -101,7 +101,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
config.forEach(function(n) {
|
config.forEach(function(n) {
|
||||||
if (n.type !== 'subflow' && n.type !== 'tab') {
|
if (n.type !== 'subflow' && n.type !== 'tab') {
|
||||||
|
@ -531,6 +531,9 @@ describe('flows/index', function() {
|
|||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve(originalConfig);
|
||||||
}
|
}
|
||||||
|
storage.setFlows = function() {
|
||||||
|
return when.resolve();
|
||||||
|
}
|
||||||
flows.init({},storage);
|
flows.init({},storage);
|
||||||
flows.load().then(function() {
|
flows.load().then(function() {
|
||||||
return flows.startFlows();
|
return flows.startFlows();
|
||||||
@ -539,7 +542,8 @@ describe('flows/index', function() {
|
|||||||
label:'new flow',
|
label:'new flow',
|
||||||
nodes:[
|
nodes:[
|
||||||
{id:"t2-1",x:10,y:10,z:"t1",type:"test",wires:[]},
|
{id:"t2-1",x:10,y:10,z:"t1",type:"test",wires:[]},
|
||||||
{id:"t2-2",x:10,y:10,z:"t1",type:"test",wires:[]},
|
{id:"t2-2",x:10,y:10,z:"t1",type:"test",wires:[]}
|
||||||
|
,
|
||||||
{id:"t2-3",z:"t1",type:"test"}
|
{id:"t2-3",z:"t1",type:"test"}
|
||||||
]
|
]
|
||||||
}).then(function(id) {
|
}).then(function(id) {
|
||||||
|
@ -137,8 +137,7 @@ describe('flows/util', function() {
|
|||||||
];
|
];
|
||||||
var parsedConfig = flowUtil.parseConfig(originalConfig);
|
var parsedConfig = flowUtil.parseConfig(originalConfig);
|
||||||
parsedConfig.missingTypes.should.eql(['missing']);
|
parsedConfig.missingTypes.should.eql(['missing']);
|
||||||
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},"t1-2":{"id":"t1-2","x":10,"y":10,"z":"t1","type":"missing","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]}}}},"missingTypes":["missing"]};
|
var expectedConfig = {"allNodes":{"t1":{"id":"t1","type":"tab"},"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},"t1-2":{"id":"t1-2","x":10,"y":10,"z":"t1","type":"missing","wires":[]}},"subflows":{},"configs":{},"flows":{"t1":{"id":"t1","type":"tab","subflows":{},"configs":{},"nodes":{"t1-1":{"id":"t1-1","x":10,"y":10,"z":"t1","type":"sf1","wires":[]},'t1-2': { id: 't1-2', x: 10, y: 10, z: 't1', type: 'missing', wires: [] }}}},"missingTypes":["missing"]};
|
||||||
|
|
||||||
redUtil.compareObjects(parsedConfig,expectedConfig).should.be.true;
|
redUtil.compareObjects(parsedConfig,expectedConfig).should.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user