mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
allow $parent access of flow context
This commit is contained in:
parent
30aebc4ee3
commit
596fbfb517
@ -18,6 +18,7 @@ var clone = require("clone");
|
||||
var log = require("@node-red/util").log;
|
||||
var util = require("@node-red/util").util;
|
||||
var memory = require("./memory");
|
||||
var flows;
|
||||
|
||||
var settings;
|
||||
|
||||
@ -47,6 +48,7 @@ function logUnknownStore(name) {
|
||||
}
|
||||
|
||||
function init(_settings) {
|
||||
flows = require("../flows");
|
||||
settings = _settings;
|
||||
contexts = {};
|
||||
stores = {};
|
||||
@ -198,8 +200,24 @@ function getContextStorage(storage) {
|
||||
}
|
||||
}
|
||||
|
||||
function followParentContext(parent, key) {
|
||||
if (key === "$parent") {
|
||||
return [parent, ""];
|
||||
}
|
||||
else if (key.startsWith("$parent.")) {
|
||||
var len = "$parent.".length;
|
||||
var new_key = key.substring(len);
|
||||
var ctx = parent;
|
||||
while (ctx && new_key.startsWith("$parent.")) {
|
||||
ctx = ctx.$parent;
|
||||
new_key = new_key.substring(len);
|
||||
}
|
||||
return [ctx, new_key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function createContext(id,seed) {
|
||||
function createContext(id,seed,parent) {
|
||||
// Seed is only set for global context - sourced from functionGlobalContext
|
||||
var scope = id;
|
||||
var obj = seed || {};
|
||||
@ -254,6 +272,29 @@ function createContext(id,seed) {
|
||||
if (!storage) {
|
||||
storage = keyParts.store || "_";
|
||||
}
|
||||
var result = followParentContext(parent, key);
|
||||
if (result) {
|
||||
var [ctx, new_key] = result;
|
||||
if (ctx) {
|
||||
if (new_key === "") {
|
||||
if (callback) {
|
||||
return callback(ctx);
|
||||
}
|
||||
else {
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
return ctx.get(new_key, storage, callback);
|
||||
}
|
||||
else {
|
||||
if (callback) {
|
||||
return callback(undefined);
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!storage) {
|
||||
storage = "_";
|
||||
@ -321,6 +362,19 @@ function createContext(id,seed) {
|
||||
if (!storage) {
|
||||
storage = keyParts.store || "_";
|
||||
}
|
||||
var result = followParentContext(parent, key);
|
||||
if (result) {
|
||||
var [ctx, new_key] = result;
|
||||
if (ctx) {
|
||||
return ctx.set(new_key, value, storage, callback);
|
||||
}
|
||||
else {
|
||||
if (callback) {
|
||||
return callback();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!storage) {
|
||||
storage = "_";
|
||||
@ -361,10 +415,36 @@ function createContext(id,seed) {
|
||||
}
|
||||
}
|
||||
});
|
||||
if (parent) {
|
||||
Object.defineProperty(obj, "$parent", {
|
||||
value: parent
|
||||
});
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function getContext(localId,flowId) {
|
||||
function createRootContext() {
|
||||
var obj = {};
|
||||
Object.defineProperties(obj, {
|
||||
get: {
|
||||
value: function(key, storage, callback) {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
set: {
|
||||
value: function(key, value, storage, callback) {
|
||||
}
|
||||
},
|
||||
keys: {
|
||||
value: function(storage, callback) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
|
||||
function getContext(localId,flowId,parent) {
|
||||
var contextId = localId;
|
||||
if (flowId) {
|
||||
contextId = localId+":"+flowId;
|
||||
@ -372,10 +452,19 @@ function getContext(localId,flowId) {
|
||||
if (contexts.hasOwnProperty(contextId)) {
|
||||
return contexts[contextId];
|
||||
}
|
||||
var newContext = createContext(contextId);
|
||||
var newContext = createContext(contextId,undefined,parent);
|
||||
if (flowId) {
|
||||
var node = flows.get(flowId);
|
||||
var parent = undefined;
|
||||
if (node && node.type.startsWith("subflow:")) {
|
||||
parent = node.context().flow;
|
||||
}
|
||||
else {
|
||||
parent = createRootContext();
|
||||
}
|
||||
var flowContext = getContext(flowId,undefined,parent);
|
||||
Object.defineProperty(newContext, 'flow', {
|
||||
value: getContext(flowId)
|
||||
value: flowContext
|
||||
});
|
||||
}
|
||||
Object.defineProperty(newContext, 'global', {
|
||||
|
@ -225,6 +225,50 @@ describe('context', function() {
|
||||
});
|
||||
})
|
||||
|
||||
describe("$parent", function() {
|
||||
it('should access $parent', function() {
|
||||
var context0 = Context.get("0","flowA");
|
||||
var context1 = Context.get("1","flowB", context0);
|
||||
var parent = context1.get("$parent");
|
||||
parent.should.equal(context0);
|
||||
});
|
||||
|
||||
it('should get undefined for $parent of root', function() {
|
||||
var context0 = Context.get("0","flowA");
|
||||
var context1 = Context.get("1","flowB", context0);
|
||||
var parent = context1.get("$parent.$parent");
|
||||
should.equal(parent, undefined);
|
||||
});
|
||||
|
||||
it('should get $parent', function() {
|
||||
var context0 = Context.get("0","flowA");
|
||||
var context1 = Context.get("1","flowB", context0);
|
||||
var parent = context1.get("$parent");
|
||||
context0.set("K", "v");
|
||||
var v = context1.get("$parent.K");
|
||||
should.equal(v, "v");
|
||||
});
|
||||
|
||||
it('should set $parent', function() {
|
||||
var context0 = Context.get("0","flowA");
|
||||
var context1 = Context.get("1","flowB", context0);
|
||||
var parent = context1.get("$parent");
|
||||
context1.set("$parent.K", "v");
|
||||
var v = context0.get("K");
|
||||
should.equal(v, "v");
|
||||
});
|
||||
|
||||
it('should not contain $parent in keys', function() {
|
||||
var context0 = Context.get("0","flowA");
|
||||
var context1 = Context.get("1","flowB", context0);
|
||||
var parent = context1.get("$parent");
|
||||
context0.set("K0", "v0");
|
||||
context1.set("K1", "v1");
|
||||
var keys = context1.keys();
|
||||
keys.should.have.length(1);
|
||||
keys[0].should.equal("K1");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user