@node-red/util 4.0.9 → 4.1.0-beta.1
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/i18n.js +21 -1
- package/lib/log.js +22 -6
- package/lib/util.js +67 -24
- package/package.json +6 -5
package/lib/i18n.js
CHANGED
|
@@ -80,6 +80,21 @@ function mergeCatalog(fallback,catalog) {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
function migrateMessageCatalogV3toV4(catalog) {
|
|
84
|
+
const keys = Object.keys(catalog)
|
|
85
|
+
keys.forEach(key => {
|
|
86
|
+
if (typeof catalog[key] === 'object') {
|
|
87
|
+
catalog[key] = migrateMessageCatalogV3toV4(catalog[key])
|
|
88
|
+
} else if (key.endsWith('_plural')) {
|
|
89
|
+
const otherKey = key.replace('_plural', '_other')
|
|
90
|
+
if (!catalog[otherKey]) {
|
|
91
|
+
catalog[otherKey] = catalog[key]
|
|
92
|
+
}
|
|
93
|
+
delete catalog[key]
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
return catalog
|
|
97
|
+
}
|
|
83
98
|
|
|
84
99
|
async function readFile(lng, ns) {
|
|
85
100
|
if (/[^a-z\-]/i.test(lng)) {
|
|
@@ -92,6 +107,12 @@ async function readFile(lng, ns) {
|
|
|
92
107
|
const content = await fs.promises.readFile(file, "utf8");
|
|
93
108
|
resourceCache[ns] = resourceCache[ns] || {};
|
|
94
109
|
resourceCache[ns][lng] = JSON.parse(content.replace(/^\uFEFF/, ''));
|
|
110
|
+
|
|
111
|
+
// Message catalogues are in i18next v3 format. That is no longer supported
|
|
112
|
+
// by i18next so we need to migrate any catalog to the v4 format.
|
|
113
|
+
// This primarily means mapping `FOO_plural` to `FOO_other`
|
|
114
|
+
resourceCache[ns][lng] = migrateMessageCatalogV3toV4(resourceCache[ns][lng])
|
|
115
|
+
|
|
95
116
|
var baseLng = lng.split('-')[0];
|
|
96
117
|
if (baseLng !== lng && resourceCache[ns][baseLng]) {
|
|
97
118
|
mergeCatalog(resourceCache[ns][baseLng], resourceCache[ns][lng]);
|
|
@@ -139,7 +160,6 @@ function init(settings) {
|
|
|
139
160
|
initPromise = new Promise((resolve,reject) => {
|
|
140
161
|
i18n.use(MessageFileLoader);
|
|
141
162
|
var opt = {
|
|
142
|
-
compatibilityJSON: 'v3',
|
|
143
163
|
// debug: true,
|
|
144
164
|
defaultNS: "runtime",
|
|
145
165
|
ns: [],
|
package/lib/log.js
CHANGED
|
@@ -23,6 +23,7 @@ var util = require("util");
|
|
|
23
23
|
var EventEmitter = require("events").EventEmitter;
|
|
24
24
|
|
|
25
25
|
var i18n = require("./i18n");
|
|
26
|
+
const chalk = require("chalk");
|
|
26
27
|
|
|
27
28
|
var levels = {
|
|
28
29
|
off: 1,
|
|
@@ -47,6 +48,17 @@ var levelNames = {
|
|
|
47
48
|
99: "metric"
|
|
48
49
|
};
|
|
49
50
|
|
|
51
|
+
var levelColours = {
|
|
52
|
+
10: 'red',
|
|
53
|
+
20: 'red',
|
|
54
|
+
30: 'yellow',
|
|
55
|
+
40: '',
|
|
56
|
+
50: 'cyan',
|
|
57
|
+
60: 'gray',
|
|
58
|
+
98: '',
|
|
59
|
+
99: ''
|
|
60
|
+
};
|
|
61
|
+
|
|
50
62
|
var logHandlers = [];
|
|
51
63
|
|
|
52
64
|
var verbose;
|
|
@@ -75,28 +87,32 @@ LogHandler.prototype.shouldReportMessage = function(msglevel) {
|
|
|
75
87
|
msglevel <= this.logLevel;
|
|
76
88
|
}
|
|
77
89
|
|
|
78
|
-
|
|
79
90
|
// Older versions of Node-RED used the deprecated util.log function.
|
|
80
91
|
// With Node.js 22, use of that function causes warnings. So here we
|
|
81
92
|
// are replicating the same format output to ensure we don't break any
|
|
82
93
|
// log parsing that happens in the real world.
|
|
83
94
|
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
84
|
-
const utilLog = function (msg) {
|
|
95
|
+
const utilLog = function (msg, level) {
|
|
85
96
|
const d = new Date();
|
|
86
97
|
const time = [
|
|
87
98
|
d.getHours().toString().padStart(2, '0'),
|
|
88
99
|
d.getMinutes().toString().padStart(2, '0'),
|
|
89
100
|
d.getSeconds().toString().padStart(2, '0')
|
|
90
101
|
].join(':');
|
|
91
|
-
|
|
102
|
+
const logLine = `${d.getDate()} ${months[d.getMonth()]} ${time} - ${msg}`
|
|
103
|
+
if (levelColours[level]) {
|
|
104
|
+
console.log(chalk[levelColours[level]](logLine))
|
|
105
|
+
} else {
|
|
106
|
+
console.log(logLine)
|
|
107
|
+
}
|
|
92
108
|
}
|
|
93
109
|
|
|
94
110
|
var consoleLogger = function(msg) {
|
|
95
111
|
if (msg.level == log.METRIC || msg.level == log.AUDIT) {
|
|
96
|
-
utilLog("["+levelNames[msg.level]+"] "+JSON.stringify(msg));
|
|
112
|
+
utilLog("["+levelNames[msg.level]+"] "+JSON.stringify(msg), msg.level);
|
|
97
113
|
} else {
|
|
98
114
|
if (verbose && msg.msg && msg.msg.stack) {
|
|
99
|
-
utilLog("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+msg.msg.stack);
|
|
115
|
+
utilLog("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+msg.msg.stack, msg.level);
|
|
100
116
|
} else {
|
|
101
117
|
var message = msg.msg;
|
|
102
118
|
try {
|
|
@@ -107,7 +123,7 @@ var consoleLogger = function(msg) {
|
|
|
107
123
|
message = 'Exception trying to log: '+util.inspect(message);
|
|
108
124
|
}
|
|
109
125
|
|
|
110
|
-
utilLog("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+message);
|
|
126
|
+
utilLog("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+message, msg.level);
|
|
111
127
|
}
|
|
112
128
|
}
|
|
113
129
|
}
|
package/lib/util.js
CHANGED
|
@@ -828,18 +828,31 @@ function encodeObject(msg,opts) {
|
|
|
828
828
|
debuglength = opts.maxLength;
|
|
829
829
|
}
|
|
830
830
|
var msgType = typeof msg.msg;
|
|
831
|
-
if (msg.msg instanceof Error) {
|
|
831
|
+
if (msg.msg instanceof Error || /Error/.test(msg.msg?.__proto__?.name)) {
|
|
832
832
|
msg.format = "error";
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
833
|
+
|
|
834
|
+
const cause = msg.msg.cause
|
|
835
|
+
const value = {
|
|
836
|
+
__enc__: true,
|
|
837
|
+
type: 'error',
|
|
838
|
+
data: {
|
|
839
|
+
name: msg.msg.name,
|
|
840
|
+
message: hasOwnProperty.call(msg.msg, 'message') ? msg.msg.message : msg.msg.toString(),
|
|
841
|
+
code: msg.msg.code,
|
|
842
|
+
cause: cause + "",
|
|
843
|
+
stack: msg.msg.stack,
|
|
844
|
+
}
|
|
836
845
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
846
|
+
// We optimistically added these properties to the object
|
|
847
|
+
// to ensure they are shown above 'stack'. But we don't want
|
|
848
|
+
// to include them if they are undefined
|
|
849
|
+
if (cause === undefined) {
|
|
850
|
+
delete value.data.cause
|
|
841
851
|
}
|
|
842
|
-
msg.msg
|
|
852
|
+
if (msg.msg.code === undefined) {
|
|
853
|
+
delete value.data.code
|
|
854
|
+
}
|
|
855
|
+
msg.msg = JSON.stringify(value);
|
|
843
856
|
} else if (msg.msg instanceof Buffer) {
|
|
844
857
|
msg.format = "buffer["+msg.msg.length+"]";
|
|
845
858
|
msg.msg = msg.msg.toString('hex');
|
|
@@ -857,6 +870,7 @@ function encodeObject(msg,opts) {
|
|
|
857
870
|
msg.format = "Object";
|
|
858
871
|
}
|
|
859
872
|
if (/error/i.test(msg.format)) {
|
|
873
|
+
// TODO: check if this is needed
|
|
860
874
|
msg.msg = JSON.stringify({
|
|
861
875
|
name: msg.msg.name,
|
|
862
876
|
message: msg.msg.message
|
|
@@ -904,8 +918,29 @@ function encodeObject(msg,opts) {
|
|
|
904
918
|
__enc__: true,
|
|
905
919
|
type: "internal"
|
|
906
920
|
}
|
|
907
|
-
} else if (value instanceof Error) {
|
|
908
|
-
|
|
921
|
+
} else if (value instanceof Error || /Error/.test(value?.__proto__?.name)) {
|
|
922
|
+
const cause = value.cause
|
|
923
|
+
const code = value.code
|
|
924
|
+
value = {
|
|
925
|
+
__enc__: true,
|
|
926
|
+
type: 'error',
|
|
927
|
+
data: {
|
|
928
|
+
name: value.name,
|
|
929
|
+
message: hasOwnProperty.call(value, 'message') ? value.message : value.toString(),
|
|
930
|
+
code,
|
|
931
|
+
cause: cause + "",
|
|
932
|
+
stack: value.stack,
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
// We optimistically added these properties to the object
|
|
936
|
+
// to ensure they are shown above 'stack'. But we don't want
|
|
937
|
+
// to include them if they are undefined
|
|
938
|
+
if (cause === undefined) {
|
|
939
|
+
delete value.data.cause
|
|
940
|
+
}
|
|
941
|
+
if (code === undefined) {
|
|
942
|
+
delete value.data.code
|
|
943
|
+
}
|
|
909
944
|
} else if (Array.isArray(value) && value.length > debuglength) {
|
|
910
945
|
value = {
|
|
911
946
|
__enc__: true,
|
|
@@ -977,8 +1012,19 @@ function encodeObject(msg,opts) {
|
|
|
977
1012
|
return value;
|
|
978
1013
|
});
|
|
979
1014
|
} else {
|
|
980
|
-
try {
|
|
981
|
-
|
|
1015
|
+
try {
|
|
1016
|
+
msg.msg = msg.msg.toString();
|
|
1017
|
+
} catch(e) {
|
|
1018
|
+
msg.msg.format = 'error'
|
|
1019
|
+
msg.msg = JSON.stringify({
|
|
1020
|
+
__enc__: true,
|
|
1021
|
+
type: 'error',
|
|
1022
|
+
data: {
|
|
1023
|
+
message: "[Type not serializable]",
|
|
1024
|
+
stack: e.stack
|
|
1025
|
+
}
|
|
1026
|
+
})
|
|
1027
|
+
}
|
|
982
1028
|
}
|
|
983
1029
|
}
|
|
984
1030
|
} else if (msgType === "function") {
|
|
@@ -1009,17 +1055,14 @@ function encodeObject(msg,opts) {
|
|
|
1009
1055
|
return msg;
|
|
1010
1056
|
} catch(e) {
|
|
1011
1057
|
msg.format = "error";
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
}
|
|
1021
|
-
if (errorMsg.message.length > debuglength) {
|
|
1022
|
-
errorMsg.message = errorMsg.message.substring(0,debuglength);
|
|
1058
|
+
const errorMsg = {
|
|
1059
|
+
__enc__: true,
|
|
1060
|
+
type: 'error',
|
|
1061
|
+
data: {
|
|
1062
|
+
name: e.name,
|
|
1063
|
+
message: 'encodeObject Error: ' + (hasOwnProperty.call(e, 'message') ? e.message : e.toString()),
|
|
1064
|
+
stack: e.stack,
|
|
1065
|
+
}
|
|
1023
1066
|
}
|
|
1024
1067
|
msg.msg = JSON.stringify(errorMsg);
|
|
1025
1068
|
return msg;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node-red/util",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.1.0-beta.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -15,12 +15,13 @@
|
|
|
15
15
|
}
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
18
|
+
"chalk": "^4.1.2",
|
|
19
|
+
"fs-extra": "11.3.0",
|
|
20
|
+
"i18next": "24.2.3",
|
|
20
21
|
"json-stringify-safe": "5.0.1",
|
|
21
|
-
"jsonata": "2.0.
|
|
22
|
+
"jsonata": "2.0.6",
|
|
22
23
|
"lodash.clonedeep": "^4.5.0",
|
|
23
24
|
"moment": "2.30.1",
|
|
24
|
-
"moment-timezone": "0.5.
|
|
25
|
+
"moment-timezone": "0.5.48"
|
|
25
26
|
}
|
|
26
27
|
}
|