mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
pull out editor-client and editor-api
This commit is contained in:
162
packages/node_modules/@node-red/util/lib/i18n.js
generated
vendored
Normal file
162
packages/node_modules/@node-red/util/lib/i18n.js
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var i18n = require("i18next");
|
||||
|
||||
var when = require("when");
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
|
||||
var defaultLang = "en-US";
|
||||
|
||||
var resourceMap = {};
|
||||
var resourceCache = {};
|
||||
var initPromise;
|
||||
|
||||
function registerMessageCatalogs(catalogs) {
|
||||
var promises = catalogs.map(function(catalog) {
|
||||
return registerMessageCatalog(catalog.namespace,catalog.dir,catalog.file);
|
||||
});
|
||||
return when.settle(promises);
|
||||
}
|
||||
|
||||
function registerMessageCatalog(namespace,dir,file) {
|
||||
return initPromise.then(function() {
|
||||
return new Promise((resolve,reject) => {
|
||||
resourceMap[namespace] = { basedir:dir, file:file};
|
||||
i18n.loadNamespaces(namespace,function() {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function mergeCatalog(fallback,catalog) {
|
||||
for (var k in fallback) {
|
||||
if (fallback.hasOwnProperty(k)) {
|
||||
if (!catalog[k]) {
|
||||
catalog[k] = fallback[k];
|
||||
} else if (typeof fallback[k] === 'object') {
|
||||
mergeCatalog(fallback[k],catalog[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var MessageFileLoader = {
|
||||
type: "backend",
|
||||
init: function(services, backendOptions, i18nextOptions) {},
|
||||
read: function(lng, ns, callback) {
|
||||
if (resourceMap[ns]) {
|
||||
var file = path.join(resourceMap[ns].basedir,lng,resourceMap[ns].file);
|
||||
//console.log(file);
|
||||
fs.readFile(file,"utf8",function(err,content) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
try {
|
||||
resourceCache[ns] = resourceCache[ns]||{};
|
||||
resourceCache[ns][lng] = JSON.parse(content.replace(/^\uFEFF/, ''));
|
||||
//console.log(resourceCache[ns][lng]);
|
||||
if (lng !== defaultLang) {
|
||||
mergeCatalog(resourceCache[ns][defaultLang],resourceCache[ns][lng]);
|
||||
}
|
||||
callback(null, resourceCache[ns][lng]);
|
||||
} catch(e) {
|
||||
callback(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
callback(new Error("Unrecognised namespace"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getCurrentLocale() {
|
||||
var env = process.env;
|
||||
for (var name of ['LC_ALL', 'LC_MESSAGES', 'LANG']) {
|
||||
if (name in env) {
|
||||
var val = env[name];
|
||||
return val.substring(0, 2);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function init() {
|
||||
if (!initPromise) {
|
||||
// Keep this as a 'when' promise as top-level red.js uses 'otherwise'
|
||||
// and embedded users of NR may have copied that.
|
||||
initPromise = when.promise((resolve,reject) => {
|
||||
i18n.use(MessageFileLoader);
|
||||
var opt = {
|
||||
// debug: true,
|
||||
defaultNS: "runtime",
|
||||
ns: [],
|
||||
fallbackLng: defaultLang,
|
||||
interpolation: {
|
||||
unescapeSuffix: 'HTML',
|
||||
escapeValue: false,
|
||||
prefix: '__',
|
||||
suffix: '__'
|
||||
}
|
||||
};
|
||||
var lang = getCurrentLocale();
|
||||
if (lang) {
|
||||
opt.lng = lang;
|
||||
}
|
||||
i18n.init(opt ,function() {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getCatalog(namespace,lang) {
|
||||
var result = null;
|
||||
lang = lang || defaultLang;
|
||||
if (resourceCache.hasOwnProperty(namespace)) {
|
||||
result = resourceCache[namespace][lang];
|
||||
if (!result) {
|
||||
var langParts = lang.split("-");
|
||||
if (langParts.length == 2) {
|
||||
result = resourceCache[namespace][langParts[0]];
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var obj = module.exports = {
|
||||
init: init,
|
||||
registerMessageCatalog: registerMessageCatalog,
|
||||
registerMessageCatalogs: registerMessageCatalogs,
|
||||
catalog: getCatalog,
|
||||
i: i18n,
|
||||
defaultLang: defaultLang
|
||||
}
|
||||
|
||||
obj['_'] = function() {
|
||||
//var opts = {};
|
||||
//if (def) {
|
||||
// opts.defaultValue = def;
|
||||
//}
|
||||
//console.log(arguments);
|
||||
var res = i18n.t.apply(i18n,arguments);
|
||||
return res;
|
||||
}
|
166
packages/node_modules/@node-red/util/lib/log.js
generated
vendored
Normal file
166
packages/node_modules/@node-red/util/lib/log.js
generated
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var util = require("util");
|
||||
var EventEmitter = require("events").EventEmitter;
|
||||
|
||||
var i18n = require("./i18n");
|
||||
|
||||
var levels = {
|
||||
off: 1,
|
||||
fatal: 10,
|
||||
error: 20,
|
||||
warn: 30,
|
||||
info: 40,
|
||||
debug: 50,
|
||||
trace: 60,
|
||||
audit: 98,
|
||||
metric: 99
|
||||
};
|
||||
|
||||
var levelNames = {
|
||||
10: "fatal",
|
||||
20: "error",
|
||||
30: "warn",
|
||||
40: "info",
|
||||
50: "debug",
|
||||
60: "trace",
|
||||
98: "audit",
|
||||
99: "metric"
|
||||
};
|
||||
|
||||
var logHandlers = [];
|
||||
|
||||
var verbose;
|
||||
|
||||
var metricsEnabled = false;
|
||||
|
||||
var LogHandler = function(settings) {
|
||||
this.logLevel = settings ? levels[settings.level]||levels.info : levels.info;
|
||||
this.metricsOn = settings ? settings.metrics||false : false;
|
||||
this.auditOn = settings ? settings.audit||false : false;
|
||||
|
||||
metricsEnabled = metricsEnabled || this.metricsOn;
|
||||
|
||||
this.handler = (settings && settings.handler) ? settings.handler(settings) : consoleLogger;
|
||||
this.on("log",function(msg) {
|
||||
if (this.shouldReportMessage(msg.level)) {
|
||||
this.handler(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
util.inherits(LogHandler, EventEmitter);
|
||||
|
||||
LogHandler.prototype.shouldReportMessage = function(msglevel) {
|
||||
return (msglevel == log.METRIC && this.metricsOn) ||
|
||||
(msglevel == log.AUDIT && this.auditOn) ||
|
||||
msglevel <= this.logLevel;
|
||||
}
|
||||
|
||||
var consoleLogger = function(msg) {
|
||||
if (msg.level == log.METRIC || msg.level == log.AUDIT) {
|
||||
util.log("["+levelNames[msg.level]+"] "+JSON.stringify(msg));
|
||||
} else {
|
||||
if (verbose && msg.msg && msg.msg.stack) {
|
||||
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+msg.msg.stack);
|
||||
} else {
|
||||
var message = msg.msg;
|
||||
if (typeof message === 'object' && message !== null && message.toString() === '[object Object]' && message.message) {
|
||||
message = message.message;
|
||||
}
|
||||
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var log = module.exports = {
|
||||
FATAL: 10,
|
||||
ERROR: 20,
|
||||
WARN: 30,
|
||||
INFO: 40,
|
||||
DEBUG: 50,
|
||||
TRACE: 60,
|
||||
AUDIT: 98,
|
||||
METRIC: 99,
|
||||
|
||||
init: function(settings) {
|
||||
metricsEnabled = false;
|
||||
logHandlers = [];
|
||||
var loggerSettings = {};
|
||||
verbose = settings.verbose;
|
||||
if (settings.logging) {
|
||||
var keys = Object.keys(settings.logging);
|
||||
if (keys.length === 0) {
|
||||
log.addHandler(new LogHandler());
|
||||
} else {
|
||||
for (var i=0, l=keys.length; i<l; i++) {
|
||||
var config = settings.logging[keys[i]];
|
||||
loggerSettings = config || {};
|
||||
if ((keys[i] === "console") || config.handler) {
|
||||
log.addHandler(new LogHandler(loggerSettings));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.addHandler(new LogHandler());
|
||||
}
|
||||
},
|
||||
addHandler: function(func) {
|
||||
logHandlers.push(func);
|
||||
},
|
||||
removeHandler: function(func) {
|
||||
var index = logHandlers.indexOf(func);
|
||||
if (index > -1) {
|
||||
logHandlers.splice(index,1);
|
||||
}
|
||||
},
|
||||
log: function(msg) {
|
||||
msg.timestamp = Date.now();
|
||||
logHandlers.forEach(function(handler) {
|
||||
handler.emit("log",msg);
|
||||
});
|
||||
},
|
||||
info: function(msg) {
|
||||
log.log({level:log.INFO,msg:msg});
|
||||
},
|
||||
warn: function(msg) {
|
||||
log.log({level:log.WARN,msg:msg});
|
||||
},
|
||||
error: function(msg) {
|
||||
log.log({level:log.ERROR,msg:msg});
|
||||
},
|
||||
trace: function(msg) {
|
||||
log.log({level:log.TRACE,msg:msg});
|
||||
},
|
||||
debug: function(msg) {
|
||||
log.log({level:log.DEBUG,msg:msg});
|
||||
},
|
||||
metric: function() {
|
||||
return metricsEnabled;
|
||||
},
|
||||
|
||||
audit: function(msg,req) {
|
||||
msg.level = log.AUDIT;
|
||||
if (req) {
|
||||
msg.user = req.user;
|
||||
msg.path = req.path;
|
||||
msg.ip = (req.headers && req.headers['x-forwarded-for']) || (req.connection && req.connection.remoteAddress) || undefined;
|
||||
}
|
||||
log.log(msg);
|
||||
}
|
||||
}
|
||||
|
||||
log["_"] = i18n._;
|
601
packages/node_modules/@node-red/util/lib/util.js
generated
vendored
Normal file
601
packages/node_modules/@node-red/util/lib/util.js
generated
vendored
Normal file
@@ -0,0 +1,601 @@
|
||||
/**
|
||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var clone = require("clone");
|
||||
var jsonata = require("jsonata");
|
||||
var safeJSONStringify = require("json-stringify-safe");
|
||||
var util = require("util");
|
||||
|
||||
function generateId() {
|
||||
return (1+Math.random()*4294967295).toString(16);
|
||||
}
|
||||
|
||||
function ensureString(o) {
|
||||
if (Buffer.isBuffer(o)) {
|
||||
return o.toString();
|
||||
} else if (typeof o === "object") {
|
||||
return JSON.stringify(o);
|
||||
} else if (typeof o === "string") {
|
||||
return o;
|
||||
}
|
||||
return ""+o;
|
||||
}
|
||||
|
||||
function ensureBuffer(o) {
|
||||
if (Buffer.isBuffer(o)) {
|
||||
return o;
|
||||
} else if (typeof o === "object") {
|
||||
o = JSON.stringify(o);
|
||||
} else if (typeof o !== "string") {
|
||||
o = ""+o;
|
||||
}
|
||||
return new Buffer(o);
|
||||
}
|
||||
|
||||
function cloneMessage(msg) {
|
||||
// Temporary fix for #97
|
||||
// TODO: remove this http-node-specific fix somehow
|
||||
var req = msg.req;
|
||||
var res = msg.res;
|
||||
delete msg.req;
|
||||
delete msg.res;
|
||||
var m = clone(msg);
|
||||
if (req) {
|
||||
m.req = req;
|
||||
msg.req = req;
|
||||
}
|
||||
if (res) {
|
||||
m.res = res;
|
||||
msg.res = res;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
function compareObjects(obj1,obj2) {
|
||||
var i;
|
||||
if (obj1 === obj2) {
|
||||
return true;
|
||||
}
|
||||
if (obj1 == null || obj2 == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var isArray1 = Array.isArray(obj1);
|
||||
var isArray2 = Array.isArray(obj2);
|
||||
if (isArray1 != isArray2) {
|
||||
return false;
|
||||
}
|
||||
if (isArray1 && isArray2) {
|
||||
if (obj1.length !== obj2.length) {
|
||||
return false;
|
||||
}
|
||||
for (i=0;i<obj1.length;i++) {
|
||||
if (!compareObjects(obj1[i],obj2[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
var isBuffer1 = Buffer.isBuffer(obj1);
|
||||
var isBuffer2 = Buffer.isBuffer(obj2);
|
||||
if (isBuffer1 != isBuffer2) {
|
||||
return false;
|
||||
}
|
||||
if (isBuffer1 && isBuffer2) {
|
||||
if (obj1.equals) {
|
||||
// For node 0.12+ - use the native equals
|
||||
return obj1.equals(obj2);
|
||||
} else {
|
||||
if (obj1.length !== obj2.length) {
|
||||
return false;
|
||||
}
|
||||
for (i=0;i<obj1.length;i++) {
|
||||
if (obj1.readUInt8(i) !== obj2.readUInt8(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') {
|
||||
return false;
|
||||
}
|
||||
var keys1 = Object.keys(obj1);
|
||||
var keys2 = Object.keys(obj2);
|
||||
if (keys1.length != keys2.length) {
|
||||
return false;
|
||||
}
|
||||
for (var k in obj1) {
|
||||
/* istanbul ignore else */
|
||||
if (obj1.hasOwnProperty(k)) {
|
||||
if (!compareObjects(obj1[k],obj2[k])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function normalisePropertyExpression(str) {
|
||||
// This must be kept in sync with validatePropertyExpression
|
||||
// in editor/js/ui/utils.js
|
||||
|
||||
var length = str.length;
|
||||
if (length === 0) {
|
||||
throw new Error("Invalid property expression: zero-length");
|
||||
}
|
||||
var parts = [];
|
||||
var start = 0;
|
||||
var inString = false;
|
||||
var inBox = false;
|
||||
var quoteChar;
|
||||
var v;
|
||||
for (var i=0;i<length;i++) {
|
||||
var c = str[i];
|
||||
if (!inString) {
|
||||
if (c === "'" || c === '"') {
|
||||
if (i != start) {
|
||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
||||
}
|
||||
inString = true;
|
||||
quoteChar = c;
|
||||
start = i+1;
|
||||
} else if (c === '.') {
|
||||
if (i===0) {
|
||||
throw new Error("Invalid property expression: unexpected . at position 0");
|
||||
}
|
||||
if (start != i) {
|
||||
v = str.substring(start,i);
|
||||
if (/^\d+$/.test(v)) {
|
||||
parts.push(parseInt(v));
|
||||
} else {
|
||||
parts.push(v);
|
||||
}
|
||||
}
|
||||
if (i===length-1) {
|
||||
throw new Error("Invalid property expression: unterminated expression");
|
||||
}
|
||||
// Next char is first char of an identifier: a-z 0-9 $ _
|
||||
if (!/[a-z0-9\$\_]/i.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||
}
|
||||
start = i+1;
|
||||
} else if (c === '[') {
|
||||
if (i === 0) {
|
||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
||||
}
|
||||
if (start != i) {
|
||||
parts.push(str.substring(start,i));
|
||||
}
|
||||
if (i===length-1) {
|
||||
throw new Error("Invalid property expression: unterminated expression");
|
||||
}
|
||||
// Next char is either a quote or a number
|
||||
if (!/["'\d]/.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1));
|
||||
}
|
||||
start = i+1;
|
||||
inBox = true;
|
||||
} else if (c === ']') {
|
||||
if (!inBox) {
|
||||
throw new Error("Invalid property expression: unexpected "+c+" at position "+i);
|
||||
}
|
||||
if (start != i) {
|
||||
v = str.substring(start,i);
|
||||
if (/^\d+$/.test(v)) {
|
||||
parts.push(parseInt(v));
|
||||
} else {
|
||||
throw new Error("Invalid property expression: unexpected array expression at position "+start);
|
||||
}
|
||||
}
|
||||
start = i+1;
|
||||
inBox = false;
|
||||
} else if (c === ' ') {
|
||||
throw new Error("Invalid property expression: unexpected ' ' at position "+i);
|
||||
}
|
||||
} else {
|
||||
if (c === quoteChar) {
|
||||
if (i-start === 0) {
|
||||
throw new Error("Invalid property expression: zero-length string at position "+start);
|
||||
}
|
||||
parts.push(str.substring(start,i));
|
||||
// If inBox, next char must be a ]. Otherwise it may be [ or .
|
||||
if (inBox && !/\]/.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected array expression at position "+start);
|
||||
} else if (!inBox && i+1!==length && !/[\[\.]/.test(str[i+1])) {
|
||||
throw new Error("Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1));
|
||||
}
|
||||
start = i+1;
|
||||
inString = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (inBox || inString) {
|
||||
throw new Error("Invalid property expression: unterminated expression");
|
||||
}
|
||||
if (start < length) {
|
||||
parts.push(str.substring(start));
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
function getMessageProperty(msg,expr) {
|
||||
if (expr.indexOf('msg.')===0) {
|
||||
expr = expr.substring(4);
|
||||
}
|
||||
return getObjectProperty(msg,expr);
|
||||
}
|
||||
function getObjectProperty(msg,expr) {
|
||||
var result = null;
|
||||
var msgPropParts = normalisePropertyExpression(expr);
|
||||
var m;
|
||||
msgPropParts.reduce(function(obj, key) {
|
||||
result = (typeof obj[key] !== "undefined" ? obj[key] : undefined);
|
||||
return result;
|
||||
}, msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
function setMessageProperty(msg,prop,value,createMissing) {
|
||||
if (prop.indexOf('msg.')===0) {
|
||||
prop = prop.substring(4);
|
||||
}
|
||||
return setObjectProperty(msg,prop,value,createMissing);
|
||||
}
|
||||
function setObjectProperty(msg,prop,value,createMissing) {
|
||||
if (typeof createMissing === 'undefined') {
|
||||
createMissing = (typeof value !== 'undefined');
|
||||
}
|
||||
var msgPropParts = normalisePropertyExpression(prop);
|
||||
var depth = 0;
|
||||
var length = msgPropParts.length;
|
||||
var obj = msg;
|
||||
var key;
|
||||
for (var i=0;i<length-1;i++) {
|
||||
key = msgPropParts[i];
|
||||
if (typeof key === 'string' || (typeof key === 'number' && !Array.isArray(obj))) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
obj = obj[key];
|
||||
} else if (createMissing) {
|
||||
if (typeof msgPropParts[i+1] === 'string') {
|
||||
obj[key] = {};
|
||||
} else {
|
||||
obj[key] = [];
|
||||
}
|
||||
obj = obj[key];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (typeof key === 'number') {
|
||||
// obj is an array
|
||||
if (obj[key] === undefined) {
|
||||
if (createMissing) {
|
||||
if (typeof msgPropParts[i+1] === 'string') {
|
||||
obj[key] = {};
|
||||
} else {
|
||||
obj[key] = [];
|
||||
}
|
||||
obj = obj[key];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
obj = obj[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
key = msgPropParts[length-1];
|
||||
if (typeof value === "undefined") {
|
||||
if (typeof key === 'number' && Array.isArray(obj)) {
|
||||
obj.splice(key,1);
|
||||
} else {
|
||||
delete obj[key]
|
||||
}
|
||||
} else {
|
||||
obj[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
function evaluateEnvProperty(value) {
|
||||
if (/^\${[^}]+}$/.test(value)) {
|
||||
// ${ENV_VAR}
|
||||
value = value.substring(2,value.length-1);
|
||||
value = process.env.hasOwnProperty(value)?process.env[value]:""
|
||||
} else if (!/\${\S+}/.test(value)) {
|
||||
// ENV_VAR
|
||||
value = process.env.hasOwnProperty(value)?process.env[value]:""
|
||||
} else {
|
||||
// FOO${ENV_VAR}BAR
|
||||
value = value.replace(/\${([^}]+)}/g, function(match, v) {
|
||||
return process.env.hasOwnProperty(v)?process.env[v]:""
|
||||
});
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
var parseContextStore = function(key) {
|
||||
var parts = {};
|
||||
var m = /^#:\((\S+?)\)::(.*)$/.exec(key);
|
||||
if (m) {
|
||||
parts.store = m[1];
|
||||
parts.key = m[2];
|
||||
} else {
|
||||
parts.key = key;
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
function evaluateNodeProperty(value, type, node, msg, callback) {
|
||||
var result = value;
|
||||
if (type === 'str') {
|
||||
result = ""+value;
|
||||
} else if (type === 'num') {
|
||||
result = Number(value);
|
||||
} else if (type === 'json') {
|
||||
result = JSON.parse(value);
|
||||
} else if (type === 're') {
|
||||
result = new RegExp(value);
|
||||
} else if (type === 'date') {
|
||||
result = Date.now();
|
||||
} else if (type === 'bin') {
|
||||
var data = JSON.parse(value);
|
||||
result = Buffer.from(data);
|
||||
} else if (type === 'msg' && msg) {
|
||||
try {
|
||||
result = getMessageProperty(msg,value);
|
||||
} catch(err) {
|
||||
if (callback) {
|
||||
callback(err);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if ((type === 'flow' || type === 'global') && node) {
|
||||
var contextKey = parseContextStore(value);
|
||||
result = node.context()[type].get(contextKey.key,contextKey.store,callback);
|
||||
if (callback) {
|
||||
return;
|
||||
}
|
||||
} else if (type === 'bool') {
|
||||
result = /^true$/i.test(value);
|
||||
} else if (type === 'jsonata') {
|
||||
var expr = prepareJSONataExpression(value,node);
|
||||
result = evaluateJSONataExpression(expr,msg);
|
||||
} else if (type === 'env') {
|
||||
result = evaluateEnvProperty(value);
|
||||
}
|
||||
if (callback) {
|
||||
callback(null,result);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
function prepareJSONataExpression(value,node) {
|
||||
var expr = jsonata(value);
|
||||
expr.assign('flowContext',function(val) {
|
||||
return node.context().flow.get(val);
|
||||
});
|
||||
expr.assign('globalContext',function(val) {
|
||||
return node.context().global.get(val);
|
||||
});
|
||||
expr.assign('env', function(val) {
|
||||
return process.env[val];
|
||||
})
|
||||
expr.registerFunction('clone', cloneMessage, '<(oa)-:o>');
|
||||
expr._legacyMode = /(^|[^a-zA-Z0-9_'"])msg([^a-zA-Z0-9_'"]|$)/.test(value);
|
||||
expr._node = node;
|
||||
return expr;
|
||||
}
|
||||
|
||||
function evaluateJSONataExpression(expr,msg,callback) {
|
||||
var context = msg;
|
||||
if (expr._legacyMode) {
|
||||
context = {msg:msg};
|
||||
}
|
||||
var bindings = {};
|
||||
|
||||
if (callback) {
|
||||
// If callback provided, need to override the pre-assigned sync
|
||||
// context functions to be their async variants
|
||||
bindings.flowContext = function(val, store) {
|
||||
return new Promise((resolve,reject) => {
|
||||
expr._node.context().flow.get(val, store, function(err,value) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(value);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
bindings.globalContext = function(val, store) {
|
||||
return new Promise((resolve,reject) => {
|
||||
expr._node.context().global.get(val, store, function(err,value) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(value);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
return expr.evaluate(context, bindings, callback);
|
||||
}
|
||||
|
||||
|
||||
function normaliseNodeTypeName(name) {
|
||||
var result = name.replace(/[^a-zA-Z0-9]/g, " ");
|
||||
result = result.trim();
|
||||
result = result.replace(/ +/g, " ");
|
||||
result = result.replace(/ ./g,
|
||||
function(s) {
|
||||
return s.charAt(1).toUpperCase();
|
||||
}
|
||||
);
|
||||
result = result.charAt(0).toLowerCase() + result.slice(1);
|
||||
return result;
|
||||
}
|
||||
|
||||
function encodeObject(msg,opts) {
|
||||
var debuglength = 1000;
|
||||
if (opts && opts.hasOwnProperty('maxLength')) {
|
||||
debuglength = opts.maxLength;
|
||||
}
|
||||
var msgType = typeof msg.msg;
|
||||
if (msg.msg instanceof Error) {
|
||||
msg.format = "error";
|
||||
var errorMsg = {};
|
||||
if (msg.msg.name) {
|
||||
errorMsg.name = msg.msg.name;
|
||||
}
|
||||
if (msg.msg.hasOwnProperty('message')) {
|
||||
errorMsg.message = msg.msg.message;
|
||||
} else {
|
||||
errorMsg.message = msg.msg.toString();
|
||||
}
|
||||
msg.msg = JSON.stringify(errorMsg);
|
||||
} else if (msg.msg instanceof Buffer) {
|
||||
msg.format = "buffer["+msg.msg.length+"]";
|
||||
msg.msg = msg.msg.toString('hex');
|
||||
if (msg.msg.length > debuglength) {
|
||||
msg.msg = msg.msg.substring(0,debuglength);
|
||||
}
|
||||
} else if (msg.msg && msgType === 'object') {
|
||||
try {
|
||||
msg.format = msg.msg.constructor.name || "Object";
|
||||
// Handle special case of msg.req/res objects from HTTP In node
|
||||
if (msg.format === "IncomingMessage" || msg.format === "ServerResponse") {
|
||||
msg.format = "Object";
|
||||
}
|
||||
} catch(err) {
|
||||
msg.format = "Object";
|
||||
}
|
||||
if (/error/i.test(msg.format)) {
|
||||
msg.msg = JSON.stringify({
|
||||
name: msg.msg.name,
|
||||
message: msg.msg.message
|
||||
});
|
||||
} else {
|
||||
var isArray = util.isArray(msg.msg);
|
||||
if (isArray) {
|
||||
msg.format = "array["+msg.msg.length+"]";
|
||||
if (msg.msg.length > debuglength) {
|
||||
// msg.msg = msg.msg.slice(0,debuglength);
|
||||
msg.msg = {
|
||||
__enc__: true,
|
||||
type: "array",
|
||||
data: msg.msg.slice(0,debuglength),
|
||||
length: msg.msg.length
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isArray || (msg.format === "Object")) {
|
||||
msg.msg = safeJSONStringify(msg.msg, function(key, value) {
|
||||
if (key === '_req' || key === '_res') {
|
||||
value = {
|
||||
__enc__: true,
|
||||
type: "internal"
|
||||
}
|
||||
} else if (value instanceof Error) {
|
||||
value = value.toString()
|
||||
} else if (util.isArray(value) && value.length > debuglength) {
|
||||
value = {
|
||||
__enc__: true,
|
||||
type: "array",
|
||||
data: value.slice(0,debuglength),
|
||||
length: value.length
|
||||
}
|
||||
} else if (typeof value === 'string') {
|
||||
if (value.length > debuglength) {
|
||||
value = value.substring(0,debuglength)+"...";
|
||||
}
|
||||
} else if (typeof value === 'function') {
|
||||
value = {
|
||||
__enc__: true,
|
||||
type: "function"
|
||||
}
|
||||
} else if (typeof value === 'number') {
|
||||
if (isNaN(value) || value === Infinity || value === -Infinity) {
|
||||
value = {
|
||||
__enc__: true,
|
||||
type: "number",
|
||||
data: value.toString()
|
||||
}
|
||||
}
|
||||
} else if (value && value.constructor) {
|
||||
if (value.type === "Buffer") {
|
||||
value.__enc__ = true;
|
||||
value.length = value.data.length;
|
||||
if (value.length > debuglength) {
|
||||
value.data = value.data.slice(0,debuglength);
|
||||
}
|
||||
} else if (value.constructor.name === "ServerResponse") {
|
||||
value = "[internal]"
|
||||
} else if (value.constructor.name === "Socket") {
|
||||
value = "[internal]"
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}," ");
|
||||
} else {
|
||||
try { msg.msg = msg.msg.toString(); }
|
||||
catch(e) { msg.msg = "[Type not printable]"; }
|
||||
}
|
||||
}
|
||||
} else if (msgType === "function") {
|
||||
msg.format = "function";
|
||||
msg.msg = "[function]"
|
||||
} else if (msgType === "boolean") {
|
||||
msg.format = "boolean";
|
||||
msg.msg = msg.msg.toString();
|
||||
} else if (msgType === "number") {
|
||||
msg.format = "number";
|
||||
msg.msg = msg.msg.toString();
|
||||
} else if (msg.msg === null || msgType === "undefined") {
|
||||
msg.format = (msg.msg === null)?"null":"undefined";
|
||||
msg.msg = "(undefined)";
|
||||
} else {
|
||||
msg.format = "string["+msg.msg.length+"]";
|
||||
if (msg.msg.length > debuglength) {
|
||||
msg.msg = msg.msg.substring(0,debuglength)+"...";
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
encodeObject: encodeObject,
|
||||
ensureString: ensureString,
|
||||
ensureBuffer: ensureBuffer,
|
||||
cloneMessage: cloneMessage,
|
||||
compareObjects: compareObjects,
|
||||
generateId: generateId,
|
||||
getMessageProperty: getMessageProperty,
|
||||
setMessageProperty: setMessageProperty,
|
||||
getObjectProperty: getObjectProperty,
|
||||
setObjectProperty: setObjectProperty,
|
||||
evaluateNodeProperty: evaluateNodeProperty,
|
||||
normalisePropertyExpression: normalisePropertyExpression,
|
||||
normaliseNodeTypeName: normaliseNodeTypeName,
|
||||
prepareJSONataExpression: prepareJSONataExpression,
|
||||
evaluateJSONataExpression: evaluateJSONataExpression,
|
||||
parseContextStore: parseContextStore
|
||||
};
|
Reference in New Issue
Block a user