diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
index 6ccad2d0e..d67a5d93d 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
@@ -58,6 +58,10 @@ RED.utils = (function() {
result = $('').text('buffer['+value.length+']');
} else if (value.hasOwnProperty('type') && value.type === 'array' && value.hasOwnProperty('data')) {
result = $('').text('array['+value.length+']');
+ } else if (value.hasOwnProperty('type') && value.type === 'set' && value.hasOwnProperty('data')) {
+ result = $('').text('set['+value.length+']');
+ } else if (value.hasOwnProperty('type') && value.type === 'map' && value.hasOwnProperty('data')) {
+ result = $('').text('map');
} else if (value.hasOwnProperty('type') && value.type === 'function') {
result = $('').text('function');
} else if (value.hasOwnProperty('type') && (value.type === 'number' || value.type === 'bigint')) {
@@ -350,7 +354,7 @@ RED.utils = (function() {
var isArray = Array.isArray(obj);
var isArrayObject = false;
- if (obj && typeof obj === 'object' && obj.hasOwnProperty('type') && obj.hasOwnProperty('data') && ((obj.__enc__ && obj.type === 'array') || obj.type === 'Buffer')) {
+ if (obj && typeof obj === 'object' && obj.hasOwnProperty('type') && obj.hasOwnProperty('data') && ((obj.__enc__ && obj.type === 'set') || (obj.__enc__ && obj.type === 'array') || obj.type === 'Buffer')) {
isArray = true;
isArrayObject = true;
}
@@ -417,7 +421,7 @@ RED.utils = (function() {
}
var fullLength = data.length;
- if (originalLength > 0) {
+ if (originalLength > 0) {
$(' ').prependTo(header);
var arrayRows = $('
').appendTo(element);
element.addClass('red-ui-debug-msg-buffer-raw');
@@ -532,12 +536,18 @@ RED.utils = (function() {
}
} else if (typeof obj === 'object') {
element.addClass('collapsed');
- var keys = Object.keys(obj);
+ var data = obj;
+ var type = "object";
+ if (data.__enc__) {
+ data = data.data;
+ type = obj.type.toLowerCase();
+ }
+ var keys = Object.keys(data);
if (key || keys.length > 0) {
$(' ').prependTo(header);
makeExpandable(header, function() {
if (!key) {
- $('').text('object').appendTo(header);
+ $('').text(type).appendTo(header);
}
for (i=0;i').appendTo(element);
@@ -550,7 +560,7 @@ RED.utils = (function() {
}
}
subElements[newPath] = buildMessageElement(
- obj[keys[i]],
+ data[keys[i]],
{
key: keys[i],
typeHint: false,
@@ -573,7 +583,7 @@ RED.utils = (function() {
checkExpanded(strippedKey,expandPaths));
}
if (key) {
- $('').text('object').appendTo(entryObj);
+ $('').text(type).appendTo(entryObj);
} else {
headerHead = $('').appendTo(entryObj);
$('{ ').appendTo(headerHead);
@@ -581,7 +591,7 @@ RED.utils = (function() {
for (i=0;i').text(keys[i]).appendTo(headerHead);
$(': ').appendTo(headerHead);
- buildMessageSummaryValue(obj[keys[i]]).appendTo(headerHead);
+ buildMessageSummaryValue(data[keys[i]]).appendTo(headerHead);
if (i < keysLength-1) {
$(', ').appendTo(headerHead);
}
@@ -1062,7 +1072,7 @@ RED.utils = (function() {
payload = Infinity;
} else if ((format === 'number') && (payload === "-Infinity")) {
payload = -Infinity;
- } else if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) {
+ } else if (format === 'Object' || /^(array|set|map)/.test(format) || format === 'boolean' || format === 'number' ) {
payload = JSON.parse(payload);
} else if (/error/i.test(format)) {
payload = JSON.parse(payload);
@@ -1268,13 +1278,13 @@ RED.utils = (function() {
r.os = /Windows NT 10/.test(ua) ? "win10" : /Windows NT 6\.0/.test(ua) ? "winvista" : /Windows NT 6\.1/.test(ua) ? "win7" : /Windows NT 6\.\d/.test(ua) ? "win8" : /Windows NT 5\.1/.test(ua) ? "winxp" : /Windows NT [1-5]\./.test(ua) ? "winnt" : /Mac/.test(ua) ? "mac" : /Linux/.test(ua) ? "linux" : /X11/.test(ua) ? "nix" : "";
r.touch = 'ontouchstart' in document.documentElement;
r.mobile = /IEMobile|Windows Phone|Lumia/i.test(ua) ? 'w' : /iPhone|iP[oa]d/.test(ua) ? 'i' : /Android/.test(ua) ? 'a' : /BlackBerry|PlayBook|BB10/.test(ua) ? 'b' : /Mobile Safari/.test(ua) ? 's' : /webOS|Mobile|Tablet|Opera Mini|\bCrMo\/|Opera Mobi/i.test(ua) ? 1 : 0;
- r.tablet = /Tablet|iPad/i.test(ua);
+ r.tablet = /Tablet|iPad/i.test(ua);
r.ie = /MSIE \d|Trident.*rv:/.test(navigator.userAgent);
r.android = /android/i.test(navigator.userAgent);
} catch (error) { }
return r;
}
-
+
return {
createObjectElement: buildMessageElement,
getMessageProperty: getMessageProperty,
diff --git a/packages/node_modules/@node-red/util/lib/util.js b/packages/node_modules/@node-red/util/lib/util.js
index 5d164af76..0a1ba5d5c 100644
--- a/packages/node_modules/@node-red/util/lib/util.js
+++ b/packages/node_modules/@node-red/util/lib/util.js
@@ -806,6 +806,7 @@ function encodeObject(msg,opts) {
});
} else {
var isArray = util.isArray(msg.msg);
+ var needsStringify = isArray;
if (isArray) {
msg.format = "array["+msg.msg.length+"]";
if (msg.msg.length > debuglength) {
@@ -817,8 +818,26 @@ function encodeObject(msg,opts) {
length: msg.msg.length
}
}
+ } else if (msg.msg && msg.msg.constructor.name === "Set") {
+ msg.format = "set["+msg.msg.size+"]";
+ msg.msg = {
+ __enc__: true,
+ type: "set",
+ data: Array.from(msg.msg).slice(0,debuglength),
+ length: msg.msg.size
+ }
+ needsStringify = true;
+ } else if (msg.msg && msg.msg.constructor.name === "Map") {
+ msg.format = "map";
+ msg.msg = {
+ __enc__: true,
+ type: "map",
+ data: Object.fromEntries(Array.from(msg.msg.entries()).slice(0,debuglength)),
+ length: msg.msg.size
+ }
+ needsStringify = true;
}
- if (isArray || (msg.format === "Object")) {
+ if (needsStringify || (msg.format === "Object")) {
msg.msg = safeJSONStringify(msg.msg, function(key, value) {
if (key === '_req' || key === '_res') {
value = {
@@ -868,6 +887,20 @@ function encodeObject(msg,opts) {
value = "[internal]"
} else if (value.constructor.name === "Socket") {
value = "[internal]"
+ } else if (value.constructor.name === "Set") {
+ value = {
+ __enc__: true,
+ type: "set",
+ data: Array.from(value).slice(0,debuglength),
+ length: value.size
+ }
+ } else if (value.constructor.name === "Map") {
+ value = {
+ __enc__: true,
+ type: "map",
+ data: Object.fromEntries(Array.from(value.entries()).slice(0,debuglength)),
+ length: value.size
+ }
}
} else if (value === undefined) {
value = {
diff --git a/test/unit/@node-red/util/lib/util_spec.js b/test/unit/@node-red/util/lib/util_spec.js
index 6db93f311..5007fe5c5 100644
--- a/test/unit/@node-red/util/lib/util_spec.js
+++ b/test/unit/@node-red/util/lib/util_spec.js
@@ -768,6 +768,36 @@ describe("@node-red/util/util", function() {
result.format.should.eql("string[10]");
result.msg.should.eql('123456...');
});
+
+ it('encodes Map', function() {
+ const m = new Map();
+ m.set("a",1);
+ m.set("b",2);
+ var msg = {msg:m};
+ var result = util.encodeObject(msg);
+ result.format.should.eql("map");
+ var resultJson = JSON.parse(result.msg);
+ resultJson.should.have.property("__enc__",true);
+ resultJson.should.have.property("type","map");
+ resultJson.should.have.property("data",{"a":1,"b":2});
+ resultJson.should.have.property("length",2)
+ });
+
+ it('encodes Set', function() {
+ const m = new Set();
+ m.add("a");
+ m.add("b");
+ var msg = {msg:m};
+ var result = util.encodeObject(msg);
+ result.format.should.eql("set[2]");
+ var resultJson = JSON.parse(result.msg);
+ resultJson.should.have.property("__enc__",true);
+ resultJson.should.have.property("type","set");
+ resultJson.should.have.property("data",["a","b"]);
+ resultJson.should.have.property("length",2)
+ });
+
+
describe('encode object', function() {
it('object', function() {
var msg = { msg:{"foo":"bar"} };
@@ -800,7 +830,34 @@ describe("@node-red/util/util", function() {
resultJson.b.should.have.property("__enc__", true);
resultJson.b.should.have.property("type", "undefined");
});
-
+ it('object with Map property', function() {
+ const m = new Map();
+ m.set("a",1);
+ m.set("b",2);
+ var msg = {msg:{"aMap":m}};
+ var result = util.encodeObject(msg);
+ result.format.should.eql("Object");
+ var resultJson = JSON.parse(result.msg);
+ resultJson.should.have.property("aMap");
+ resultJson.aMap.should.have.property("__enc__",true);
+ resultJson.aMap.should.have.property("type","map");
+ resultJson.aMap.should.have.property("data",{"a":1,"b":2});
+ resultJson.aMap.should.have.property("length",2)
+ });
+ it('object with Set property', function() {
+ const m = new Set();
+ m.add("a");
+ m.add("b");
+ var msg = {msg:{"aSet":m}};
+ var result = util.encodeObject(msg);
+ result.format.should.eql("Object");
+ var resultJson = JSON.parse(result.msg);
+ resultJson.should.have.property("aSet");
+ resultJson.aSet.should.have.property("__enc__",true);
+ resultJson.aSet.should.have.property("type","set");
+ resultJson.aSet.should.have.property("data",["a","b"]);
+ resultJson.aSet.should.have.property("length",2)
+ });
it('constructor of IncomingMessage', function() {
function IncomingMessage(){};
var msg = { msg:new IncomingMessage() };