From 68957ee1351db3d1ee57f28a1524639efcd312d0 Mon Sep 17 00:00:00 2001 From: Anshuman Date: Mon, 22 Apr 2024 09:13:18 +0000 Subject: [PATCH] use rfdc to clone json objects only --- .../@node-red/runtime/lib/flows/Flow.js | 15 ++++++-- .../@node-red/runtime/lib/flows/index.js | 34 ++++++++++++------- .../@node-red/runtime/lib/flows/util.js | 10 +++--- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js index c320f3c72..af5e90a5d 100644 --- a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js +++ b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js @@ -14,13 +14,15 @@ * limitations under the License. **/ -const clone = require("rfdc")({proto:true, circles: true}); +const clone = require("clone"); +const rfdcClone = require("rfdc")({proto:true, circles: true}); const redUtil = require("@node-red/util").util; const events = require("@node-red/util").events; const flowUtil = require("./util"); const context = require('../nodes/context'); const hooks = require("@node-red/util").hooks; const credentials = require("../nodes/credentials"); +const { isJSONType } = require("ajv/dist/compile/rules"); let Subflow; let Log; @@ -562,8 +564,15 @@ class Flow { }) candidateNodes.forEach(candidate => { const targetStatusNode = candidate.n - var message = { - status: clone(statusMessage) + var message; + if (isJSONType(statusMessage)) { + message = { + status: rfdcClone(statusMessage) + } + } else { + message = { + status: clone(statusMessage) + } } if (statusMessage.hasOwnProperty("text")) { message.status.text = statusMessage.text.toString(); diff --git a/packages/node_modules/@node-red/runtime/lib/flows/index.js b/packages/node_modules/@node-red/runtime/lib/flows/index.js index 70041538f..5197614eb 100644 --- a/packages/node_modules/@node-red/runtime/lib/flows/index.js +++ b/packages/node_modules/@node-red/runtime/lib/flows/index.js @@ -14,7 +14,8 @@ * limitations under the License. **/ -const clone = require("rfdc")({proto:true, circles: true}); +const clone = require("clone"); +const rfdcClone = require("rfdc")({proto:true, circles: true}); var Flow = require('./Flow'); @@ -24,6 +25,7 @@ var deprecated = typeRegistry.deprecated; var context = require("../nodes/context") var credentials = require("../nodes/credentials"); var flowUtil = require("./util"); +const { isJSONType } = require("ajv/dist/compile/rules"); var log; const events = require("@node-red/util").events; var redUtil = require("@node-red/util").util; @@ -137,19 +139,20 @@ function setFlows(_config,_credentials,type,muteLog,forceStart,user) { var diff; var newFlowConfig; var isLoad = false; + var dup = isJSONType(_config) ? rfdcClone : clone; if (type === "load") { isLoad = true; configSavePromise = loadFlows().then(function(_config) { - config = clone(_config.flows); - newFlowConfig = flowUtil.parseConfig(clone(config)); + config = dup(_config.flows); + newFlowConfig = flowUtil.parseConfig(dup(config)); type = "full"; return _config.rev; }); } else { // Clone the provided config so it can be manipulated - config = clone(_config); + config = dup(_config); // Parse the configuration - newFlowConfig = flowUtil.parseConfig(clone(config)); + newFlowConfig = flowUtil.parseConfig(dup(config)); // Generate a diff to identify what has changed diff = flowUtil.diffConfigs(activeFlowConfig,newFlowConfig); @@ -609,7 +612,7 @@ async function addFlow(flow, user) { nodes.push(node); } } - var newConfig = clone(activeConfig.flows); + var newConfig = isJSONType(activeConfig.flows) ? rfdcClone(activeConfig.flows) : clone(activeConfig.flows); newConfig = newConfig.concat(nodes); return setFlows(newConfig, null, 'flows', true, null, user).then(function() { @@ -650,7 +653,8 @@ function getFlow(id) { var nodeIds = Object.keys(flow.nodes); if (nodeIds.length > 0) { result.nodes = nodeIds.map(function(nodeId) { - var node = clone(flow.nodes[nodeId]); + var dup = isJSONType(flow.nodes[nodeId]) ? rfdcClone : clone; + var node = dup(flow.nodes[nodeId]); if (node.type === 'link out') { delete node.wires; } @@ -662,7 +666,8 @@ function getFlow(id) { if (flow.configs) { var configIds = Object.keys(flow.configs); result.configs = configIds.map(function(configId) { - const node = clone(flow.configs[configId]); + var dup = isJSONType(flow.configs[configId]) ? rfdcClone : clone; + const node = dup(flow.configs[configId]); delete node.credentials; return node @@ -674,17 +679,20 @@ function getFlow(id) { if (flow.subflows) { var subflowIds = Object.keys(flow.subflows); result.subflows = subflowIds.map(function(subflowId) { - var subflow = clone(flow.subflows[subflowId]); + var dup = isJSONType(flow.subflows[subflowId]) ? rfdcClone : clone; + var subflow = dup(flow.subflows[subflowId]); var nodeIds = Object.keys(subflow.nodes); subflow.nodes = nodeIds.map(function(id) { - const node = clone(subflow.nodes[id]) + var dup = isJSONType(subflow.nodes[id]) ? rfdcClone : clone; + const node = dup(subflow.nodes[id]) delete node.credentials return node }); if (subflow.configs) { var configIds = Object.keys(subflow.configs); subflow.configs = configIds.map(function(id) { - const node = clone(subflow.configs[id]) + var dup = isJSONType(subflow.configs[id]) ? rfdcClone : clone; + const node = dup(subflow.configs[id]) delete node.credentials return node }) @@ -709,7 +717,7 @@ async function updateFlow(id,newFlow, user) { } label = activeFlowConfig.flows[id].label; } - var newConfig = clone(activeConfig.flows); + var newConfig = isJSONType(activeConfig.flows) ? rfdcClone(activeConfig.flows) : clone(activeConfig.flows); var nodes; if (id === 'global') { @@ -779,7 +787,7 @@ async function removeFlow(id, user) { throw e; } - var newConfig = clone(activeConfig.flows); + var newConfig = isJSONType(activeConfig.flows) ? rfdcClone(activeConfig.flows) : clone(activeConfig.flows); newConfig = newConfig.filter(function(node) { return node.z !== id && node.id !== id; }); diff --git a/packages/node_modules/@node-red/runtime/lib/flows/util.js b/packages/node_modules/@node-red/runtime/lib/flows/util.js index fc5ae9b5e..f4c0c4ddf 100644 --- a/packages/node_modules/@node-red/runtime/lib/flows/util.js +++ b/packages/node_modules/@node-red/runtime/lib/flows/util.js @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ -const clone = require("rfdc")({proto:true, circles: true}); +const clone = require("clone"); +const rfdcClone = require("rfdc")({proto:true, circles: true}); const redUtil = require("@node-red/util").util; const Log = require("@node-red/util").log; const typeRegistry = require("@node-red/registry"); +const { isJSONType } = require("ajv/dist/compile/rules"); const subflowInstanceRE = /^subflow:(.+)$/; let _runtime = null; @@ -175,7 +177,7 @@ async function createNode(flow,config) { try { var nodeTypeConstructor = typeRegistry.get(type); if (typeof nodeTypeConstructor === "function") { - var conf = clone(config); + var conf = isJSONType(config) ? rfdcClone(config) : clone(config); delete conf.credentials; try { Object.defineProperty(conf,'_module', {value: typeRegistry.getNodeInfo(type), enumerable: false, writable: true }) @@ -202,7 +204,7 @@ async function createNode(flow,config) { var subflowInstanceConfig = subflowConfig.subflows[nodeTypeConstructor.subflow.id]; delete subflowConfig.subflows[nodeTypeConstructor.subflow.id]; subflowInstanceConfig.subflows = subflowConfig.subflows; - var instanceConfig = clone(config); + var instanceConfig = isJSONType(config) ? rfdcClone(config) : clone(config); instanceConfig.env = clone(nodeTypeConstructor.subflow.env); instanceConfig.env = nodeTypeConstructor.subflow.env.map(nodeProp => { @@ -256,7 +258,7 @@ function parseConfig(config) { flow.missingTypes = []; config.forEach(function (n) { - flow.allNodes[n.id] = clone(n); + flow.allNodes[n.id] = isJSONType(n) ? rfdcClone(n) : clone(n); if (n.type === 'tab') { flow.flows[n.id] = n; flow.flows[n.id].subflows = {};