mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Merge branch 'master' into dev
This commit is contained in:
@@ -99,6 +99,9 @@ var api = module.exports = {
|
||||
safeSettings.markdownEditor = runtime.settings.editorTheme.markdownEditor || {};
|
||||
safeSettings.markdownEditor.mermaid = safeSettings.markdownEditor.mermaid || { enabled: true };
|
||||
}
|
||||
if (runtime.settings.editorTheme.mermaid) {
|
||||
safeSettings.mermaid = runtime.settings.editorTheme.mermaid
|
||||
}
|
||||
}
|
||||
safeSettings.libraries = runtime.library.getLibraries();
|
||||
if (util.isArray(runtime.settings.paletteCategories)) {
|
||||
|
@@ -161,7 +161,8 @@ class Flow {
|
||||
for (let i = 0; i < configNodes.length; i++) {
|
||||
const node = this.flow.configs[configNodes[i]]
|
||||
if (node.type === 'global-config' && node.env) {
|
||||
const nodeEnv = await flowUtil.evaluateEnvProperties(this, node.env, credentials.get(node.id))
|
||||
const globalCreds = credentials.get(node.id)?.map || {}
|
||||
const nodeEnv = await flowUtil.evaluateEnvProperties(this, node.env, globalCreds)
|
||||
this._env = { ...this._env, ...nodeEnv }
|
||||
}
|
||||
}
|
||||
|
@@ -73,9 +73,20 @@ class Subflow extends Flow {
|
||||
id: subflowInstance.id,
|
||||
configs: {},
|
||||
nodes: {},
|
||||
groups: {},
|
||||
subflows: {}
|
||||
}
|
||||
|
||||
if (subflowDef.groups) {
|
||||
// Clone all of the subflow group definitions and give them new IDs
|
||||
for (i in subflowDef.groups) {
|
||||
if (subflowDef.groups.hasOwnProperty(i)) {
|
||||
node = createNodeInSubflow(subflowInstance.id,subflowDef.groups[i]);
|
||||
node_map[node._alias] = node;
|
||||
subflowInternalFlowConfig.groups[node.id] = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (subflowDef.configs) {
|
||||
// Clone all of the subflow config node definitions and give them new IDs
|
||||
for (i in subflowDef.configs) {
|
||||
@@ -237,7 +248,7 @@ class Subflow extends Flow {
|
||||
for (j=0;j<wires.length;j++) {
|
||||
if (wires[j].id != self.subflowDef.id) {
|
||||
node = self.node_map[wires[j].id];
|
||||
if (node._originalWires) {
|
||||
if (node && node._originalWires) {
|
||||
node.wires = clone(node._originalWires);
|
||||
}
|
||||
}
|
||||
@@ -254,8 +265,10 @@ class Subflow extends Flow {
|
||||
subflowInstanceModified = true;
|
||||
} else {
|
||||
node = self.node_map[wires[j].id];
|
||||
node.wires[wires[j].port] = node.wires[wires[j].port].concat(newWires[i]);
|
||||
modifiedNodes[node.id] = node;
|
||||
if (node) {
|
||||
node.wires[wires[j].port] = node.wires[wires[j].port].concat(newWires[i]);
|
||||
modifiedNodes[node.id] = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,10 +296,14 @@ class Subflow extends Flow {
|
||||
this.node._updateWires(subflowInstanceConfig.wires);
|
||||
} else {
|
||||
var node = self.node_map[wires[j].id];
|
||||
if (!node._originalWires) {
|
||||
node._originalWires = clone(node.wires);
|
||||
if (node) {
|
||||
if (!node._originalWires) {
|
||||
node._originalWires = clone(node.wires);
|
||||
}
|
||||
node.wires[wires[j].port] = (node.wires[wires[j].port]||[]).concat(this.subflowInstance.wires[i]);
|
||||
} else {
|
||||
this.error("Unknown node referenced inside subflow: " + wires[j].id)
|
||||
}
|
||||
node.wires[wires[j].port] = (node.wires[wires[j].port]||[]).concat(this.subflowInstance.wires[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -302,11 +319,15 @@ class Subflow extends Flow {
|
||||
this.node._updateWires(subflowInstanceConfig.wires);
|
||||
} else {
|
||||
var node = self.node_map[wires[j].id];
|
||||
if (!node._originalWires) {
|
||||
node._originalWires = clone(node.wires);
|
||||
if (node) {
|
||||
if (!node._originalWires) {
|
||||
node._originalWires = clone(node.wires);
|
||||
}
|
||||
node.wires[wires[j].port] = (node.wires[wires[j].port]||[]);
|
||||
node.wires[wires[j].port].push(subflowStatusId);
|
||||
} else {
|
||||
this.error("Unknown node referenced inside subflow: " + wires[j].id)
|
||||
}
|
||||
node.wires[wires[j].port] = (node.wires[wires[j].port]||[]);
|
||||
node.wires[wires[j].port].push(subflowStatusId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -57,18 +57,20 @@ var EnvVarPropertyRE = /^\${(\S+)}$/;
|
||||
|
||||
|
||||
function mapEnvVarProperties(obj,prop,flow,config) {
|
||||
var v = obj[prop];
|
||||
const v = obj[prop];
|
||||
if (Buffer.isBuffer(v)) {
|
||||
return;
|
||||
} else if (Array.isArray(v)) {
|
||||
for (var i=0;i<v.length;i++) {
|
||||
for (let i=0;i<v.length;i++) {
|
||||
mapEnvVarProperties(v,i,flow,config);
|
||||
}
|
||||
} else if (typeof obj[prop] === 'string') {
|
||||
if (obj[prop][0] === "$" && (EnvVarPropertyRE_old.test(v) || EnvVarPropertyRE.test(v)) ) {
|
||||
var envVar = v.substring(2,v.length-1);
|
||||
var r = redUtil.getSetting(config, envVar, flow);
|
||||
obj[prop] = r ? r : obj[prop];
|
||||
const envVar = v.substring(2,v.length-1);
|
||||
const r = redUtil.getSetting(config, envVar, flow);
|
||||
if (r !== undefined && r !== '') {
|
||||
obj[prop] = r
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var p in v) {
|
||||
@@ -80,6 +82,7 @@ function mapEnvVarProperties(obj,prop,flow,config) {
|
||||
}
|
||||
|
||||
async function evaluateEnvProperties(flow, env, credentials) {
|
||||
credentials = credentials || {}
|
||||
const pendingEvaluations = []
|
||||
const evaluatedEnv = {}
|
||||
const envTypes = []
|
||||
@@ -112,6 +115,7 @@ async function evaluateEnvProperties(flow, env, credentials) {
|
||||
if (pendingEvaluations.length > 0) {
|
||||
await Promise.all(pendingEvaluations)
|
||||
}
|
||||
// Now loop over the env types and evaluate them properly
|
||||
for (let i = 0; i < envTypes.length; i++) {
|
||||
let { name, value, type } = envTypes[i]
|
||||
// If an env-var wants to lookup itself, delegate straight to the parent
|
||||
@@ -122,7 +126,17 @@ async function evaluateEnvProperties(flow, env, credentials) {
|
||||
if (evaluatedEnv.hasOwnProperty(value)) {
|
||||
value = evaluatedEnv[value]
|
||||
} else {
|
||||
value = redUtil.evaluateNodeProperty(value, type, {_flow: flow}, null, null);
|
||||
value = redUtil.evaluateNodeProperty(value, type, {_flow: {
|
||||
// Provide a hook so when it tries to look up a flow setting,
|
||||
// we can insert the just-evaluated value which hasn't yet
|
||||
// been set on the flow object - otherwise delegate up to the flow
|
||||
getSetting: function(name) {
|
||||
if (evaluatedEnv.hasOwnProperty(name)){
|
||||
return evaluatedEnv[name]
|
||||
}
|
||||
return flow.getSetting(name)
|
||||
}
|
||||
}}, null, null);
|
||||
}
|
||||
evaluatedEnv[name] = value
|
||||
}
|
||||
|
@@ -42,6 +42,7 @@ function Node(n) {
|
||||
this._closeCallbacks = [];
|
||||
this._inputCallback = null;
|
||||
this._inputCallbacks = null;
|
||||
this._expectedDoneCount = 0;
|
||||
|
||||
if (n.name) {
|
||||
this.name = n.name;
|
||||
@@ -159,6 +160,9 @@ Node.prototype.on = function(event, callback) {
|
||||
if (event == "close") {
|
||||
this._closeCallbacks.push(callback);
|
||||
} else if (event === "input") {
|
||||
if (callback.length === 3) {
|
||||
this._expectedDoneCount++
|
||||
}
|
||||
if (this._inputCallback) {
|
||||
this._inputCallbacks = [this._inputCallback, callback];
|
||||
this._inputCallback = null;
|
||||
@@ -218,19 +222,17 @@ Node.prototype._emitInput = function(arg) {
|
||||
} else if (node._inputCallbacks) {
|
||||
// Multiple callbacks registered. Call each one, tracking eventual completion
|
||||
var c = node._inputCallbacks.length;
|
||||
let doneCount = 0
|
||||
for (var i=0;i<c;i++) {
|
||||
var cb = node._inputCallbacks[i];
|
||||
if (cb.length === 2) {
|
||||
c++;
|
||||
}
|
||||
try {
|
||||
cb.call(
|
||||
node,
|
||||
arg,
|
||||
function() { node.send.apply(node,arguments) },
|
||||
function(err) {
|
||||
c--;
|
||||
if (c === 0) {
|
||||
doneCount++;
|
||||
if (doneCount === node._expectedDoneCount) {
|
||||
node._complete(arg,err);
|
||||
}
|
||||
}
|
||||
@@ -257,6 +259,9 @@ Node.prototype._removeListener = Node.prototype.removeListener;
|
||||
Node.prototype.removeListener = function(name, listener) {
|
||||
var index;
|
||||
if (name === "input") {
|
||||
if (listener.length === 3) {
|
||||
this._expectedDoneCount--
|
||||
}
|
||||
if (this._inputCallback && this._inputCallback === listener) {
|
||||
// Removing the only callback
|
||||
this._inputCallback = null;
|
||||
|
@@ -48,7 +48,7 @@
|
||||
"port-in-use": "Erreur : port utilisé",
|
||||
"uncaught-exception": "Exception non reconnue :",
|
||||
"admin-ui-disabled": "Interface d'administration désactivée",
|
||||
"now-running": "Le serveur tourne maintenant sur __listenpath__",
|
||||
"now-running": "Le serveur est disponible à l'adresse __listenpath__",
|
||||
"failed-to-start": "Échec lors du démarrage du serveur :",
|
||||
"headless-mode": "Fonctionne en mode sans interface graphique (headless)",
|
||||
"httpadminauth-deprecated": "L'utilisation de httpAdminAuth est DÉCONSEILLÉE. Utiliser adminAuth à la place",
|
||||
@@ -100,7 +100,7 @@
|
||||
"error": "Erreur lors du chargement des identifiants : __message__",
|
||||
"error-saving": "Erreur lors de l'enregistrement des identifiants : __message__",
|
||||
"not-registered": "Le type d'identifiant '__type__' n'a pas été enregistré",
|
||||
"system-key-warning": "\n\n---------------------------------------------------------------------\nVotre fichier contenant les identifiants de flux est chiffré à l'aide d'une clé générée par le système.\n\nSi la clé générée par le système est perdue pour une raison quelconque, votre fichier contenant\nles identifiants ne sera pas récupérable, vous devrez le supprimer et ressaisir vos identifiants.\n\nVous pouvez définir votre propre clé en utilisant l'option 'credentialSecret' dans\nvotre fichier de paramètres. Node-RED rechiffrera alors votre fichier contenant les identifiants\nà l'aide de la clé que vous avez choisie la prochaine fois que vous déploierez une modification.\n---------------------------------------------------------------------\n",
|
||||
"system-key-warning": "\n\n--------------------------------------------------------------------------------------------------------\nVotre fichier contenant les identifiants de flux est chiffré à l'aide d'une clé générée par le système.\n\nSi la clé générée par le système est perdue pour une raison quelconque, votre fichier contenant\nles identifiants ne sera pas récupérable, vous devrez le supprimer et ressaisir vos identifiants.\n\nVous pouvez définir votre propre clé en utilisant l'option 'credentialSecret' dans\nvotre fichier de paramètres. Node-RED rechiffrera alors votre fichier contenant les identifiants\nà l'aide de la clé que vous avez choisie la prochaine fois que vous déploierez une modification.\n--------------------------------------------------------------------------------------------------------\n",
|
||||
"unencrypted": "Utilisation d'identifiants non chiffrés",
|
||||
"encryptedNotFound": "Identifiants chiffrés introuvables"
|
||||
},
|
||||
|
Reference in New Issue
Block a user