@node-red/util 5.0.6 → 5.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/jsonata.js +7699 -0
- package/lib/util.js +66 -5
- package/package.json +3 -4
package/lib/util.js
CHANGED
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
const clonedeep = require("lodash.clonedeep");
|
|
23
|
-
const jsonata = require("jsonata");
|
|
24
23
|
const moment = require("moment-timezone");
|
|
25
24
|
const safeJSONStringify = require("json-stringify-safe");
|
|
26
25
|
const util = require("util");
|
|
27
26
|
const log = require("./log")
|
|
27
|
+
const jsonata = require("./jsonata");
|
|
28
28
|
/**
|
|
29
29
|
* Safely returns the object constructor name.
|
|
30
30
|
* @return {String} the name of the object constructor if it exists, empty string otherwise.
|
|
@@ -470,6 +470,10 @@ function setObjectProperty(msg,prop,value,createMissing) {
|
|
|
470
470
|
var obj = msg;
|
|
471
471
|
var key;
|
|
472
472
|
for (var i=0;i<length-1;i++) {
|
|
473
|
+
if (obj === null || (typeof obj !== "object" && typeof obj !== "function")) {
|
|
474
|
+
// Cannot traverse a property beneath a non-object/array
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
473
477
|
key = msgPropParts[i];
|
|
474
478
|
if (typeof key === 'string' || (typeof key === 'number' && !Array.isArray(obj))) {
|
|
475
479
|
if (Object.hasOwn(obj, key)) {
|
|
@@ -507,6 +511,10 @@ function setObjectProperty(msg,prop,value,createMissing) {
|
|
|
507
511
|
}
|
|
508
512
|
}
|
|
509
513
|
}
|
|
514
|
+
if (obj === null || (typeof obj !== "object" && typeof obj !== "function")) {
|
|
515
|
+
// Cannot set or delete a property beneath a non-object/array
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
510
518
|
key = msgPropParts[length-1];
|
|
511
519
|
if (typeof value === "undefined") {
|
|
512
520
|
if (typeof key === 'number' && Array.isArray(obj)) {
|
|
@@ -724,7 +732,9 @@ function prepareJSONataExpression(value,node) {
|
|
|
724
732
|
}
|
|
725
733
|
});
|
|
726
734
|
expr.assign('moment', function(arg1, arg2, arg3, arg4) {
|
|
727
|
-
|
|
735
|
+
const result = moment(arg1, arg2, arg3, arg4);
|
|
736
|
+
return result;
|
|
737
|
+
// return moment(arg1, arg2, arg3, arg4);
|
|
728
738
|
});
|
|
729
739
|
expr.registerFunction('clone', cloneMessage, '<(oa)-:o>');
|
|
730
740
|
expr._legacyMode = /(^|[^a-zA-Z0-9_'".])msg([^a-zA-Z0-9_'"]|$)/.test(value);
|
|
@@ -856,6 +866,56 @@ function normaliseNodeTypeName(name) {
|
|
|
856
866
|
return result;
|
|
857
867
|
}
|
|
858
868
|
|
|
869
|
+
/**
|
|
870
|
+
* Full length of a Buffer whose toJSON data was truncated by
|
|
871
|
+
* stringifyWithTruncatedBuffers
|
|
872
|
+
*/
|
|
873
|
+
const truncatedBufferLength = Symbol("truncatedBufferLength");
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* Stringify an object like safeJSONStringify, but only convert the first
|
|
877
|
+
* `maxLength` bytes of any Buffer that is longer than that.
|
|
878
|
+
*
|
|
879
|
+
* JSON.stringify calls Buffer's toJSON, which copies every byte into an
|
|
880
|
+
* array, before the replacer gets to see the value. For large Buffers that
|
|
881
|
+
* can take a long time or exhaust the heap, so a truncating toJSON is used
|
|
882
|
+
* for the duration of the call.
|
|
883
|
+
* @param {Object} obj - the object to stringify
|
|
884
|
+
* @param {Number} maxLength - the number of bytes to keep of each Buffer
|
|
885
|
+
* @param {Function} replacer - the replacer for safeJSONStringify
|
|
886
|
+
* @return {String} the JSON string
|
|
887
|
+
*/
|
|
888
|
+
function stringifyWithTruncatedBuffers(obj, maxLength, replacer) {
|
|
889
|
+
if (!(maxLength >= 0)) {
|
|
890
|
+
return safeJSONStringify(obj, replacer);
|
|
891
|
+
}
|
|
892
|
+
const bufferToJSON = Buffer.prototype.toJSON;
|
|
893
|
+
const truncatingToJSON = function() {
|
|
894
|
+
if (this.length <= maxLength) {
|
|
895
|
+
return bufferToJSON.call(this);
|
|
896
|
+
}
|
|
897
|
+
const value = {
|
|
898
|
+
type: "Buffer",
|
|
899
|
+
data: Array.from(this.subarray(0,maxLength))
|
|
900
|
+
};
|
|
901
|
+
value[truncatedBufferLength] = this.length;
|
|
902
|
+
return value;
|
|
903
|
+
};
|
|
904
|
+
Buffer.prototype.toJSON = truncatingToJSON;
|
|
905
|
+
// The finally block is skipped if execution is terminated while
|
|
906
|
+
// stringifying, e.g. by the timeout of a Function node calling node.warn
|
|
907
|
+
process.nextTick(function() {
|
|
908
|
+
if (Buffer.prototype.toJSON === truncatingToJSON) {
|
|
909
|
+
Buffer.prototype.toJSON = bufferToJSON;
|
|
910
|
+
}
|
|
911
|
+
});
|
|
912
|
+
try {
|
|
913
|
+
return safeJSONStringify(obj, replacer);
|
|
914
|
+
} finally {
|
|
915
|
+
Buffer.prototype.toJSON = bufferToJSON;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
|
|
859
919
|
/**
|
|
860
920
|
* Encode an object to JSON without losing information about non-JSON types
|
|
861
921
|
* such as Buffer and Function.
|
|
@@ -901,7 +961,8 @@ function encodeObject(msg,opts) {
|
|
|
901
961
|
msg.msg = JSON.stringify(value);
|
|
902
962
|
} else if (msg.msg instanceof Buffer) {
|
|
903
963
|
msg.format = "buffer["+msg.msg.length+"]";
|
|
904
|
-
|
|
964
|
+
// Only hex encode the bytes that will be shown
|
|
965
|
+
msg.msg = msg.msg.toString('hex', 0, debuglength >= 0 ? Math.ceil(debuglength/2) : undefined);
|
|
905
966
|
if (msg.msg.length > debuglength) {
|
|
906
967
|
msg.msg = msg.msg.substring(0,debuglength);
|
|
907
968
|
}
|
|
@@ -960,7 +1021,7 @@ function encodeObject(msg,opts) {
|
|
|
960
1021
|
msg.msg = msg.msg.toString();
|
|
961
1022
|
}
|
|
962
1023
|
if (needsStringify || (msg.format === "Object")) {
|
|
963
|
-
msg.msg =
|
|
1024
|
+
msg.msg = stringifyWithTruncatedBuffers(msg.msg, debuglength, function(key, value) {
|
|
964
1025
|
if (key === '_req' || key === '_res') {
|
|
965
1026
|
value = {
|
|
966
1027
|
__enc__: true,
|
|
@@ -1032,7 +1093,7 @@ function encodeObject(msg,opts) {
|
|
|
1032
1093
|
} else if (value && value.constructor) {
|
|
1033
1094
|
if (value.type === "Buffer") {
|
|
1034
1095
|
value.__enc__ = true;
|
|
1035
|
-
value.length = value.data.length;
|
|
1096
|
+
value.length = value[truncatedBufferLength] ?? value.data.length;
|
|
1036
1097
|
if (value.length > debuglength) {
|
|
1037
1098
|
value.data = value.data.slice(0,debuglength);
|
|
1038
1099
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node-red/util",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.8",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,12 +16,11 @@
|
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"chalk": "^4.1.2",
|
|
19
|
-
"fs-extra": "11.4.
|
|
19
|
+
"fs-extra": "11.4.1",
|
|
20
20
|
"i18next": "25.8.14",
|
|
21
21
|
"json-stringify-safe": "5.0.1",
|
|
22
|
-
"jsonata": "2.2.2",
|
|
23
22
|
"lodash.clonedeep": "^4.5.0",
|
|
24
|
-
"moment": "2.
|
|
23
|
+
"moment": "2.31.0",
|
|
25
24
|
"moment-timezone": "0.5.48"
|
|
26
25
|
}
|
|
27
26
|
}
|