Compare commits

...

31 Commits
3.1.4 ... 3.1.7

Author SHA1 Message Date
Nick O'Leary
179032cd4d Merge pull request #4608 from node-red/rel317
Bump for 3.1.7 release
2024-03-12 17:43:32 +00:00
Nick O'Leary
6a6f0d04d6 Bump for 3.1.7 release 2024-03-12 14:25:41 +00:00
Nick O'Leary
add4d9758c Merge pull request #4603 from kazuhitoyokoi/master-addjpn
Add Japanese translation for v3.1.6
2024-03-11 16:07:28 +00:00
Kazuhito Yokoi
a0d3ea62b2 Add Japanese translation for v3.1.6 2024-03-10 23:36:20 +09:00
Nick O'Leary
7447e88a50 Merge pull request #4593 from hardillb/hardillb-patch-1
Update jsonata version
2024-03-07 14:26:02 +00:00
Ben Hardill
a193b79d3d Bump jsonata to match utils 2024-03-05 10:31:03 +00:00
Ben Hardill
da380f7464 Update jsonata version
Pulls in fix for CVE-2024-27307
2024-03-05 10:22:49 +00:00
Nick O'Leary
269cf02c0b Merge pull request #4586 from node-red/rel316
Bump for 3.1.6 release
2024-03-01 11:47:57 +00:00
Nick O'Leary
fb50e2772a Bump for 3.1.6 release 2024-03-01 10:50:06 +00:00
Nick O'Leary
058c97138a Merge pull request #4582 from node-red/3795-allow-env-var-in-num-field-validation
Do not flag env var in num typedInput as error
2024-02-26 17:01:45 +00:00
Nick O'Leary
828ae29aed Merge pull request #4581 from node-red/4579-fix-undef-env-vars
Handle undefined env vars
2024-02-26 17:01:27 +00:00
Nick O'Leary
6a0f45140c Merge pull request #4568 from JaysonHurst/fips
fix: Removed offending MD5 crypto hash and replaced with SHA1 and SHA256 …
2024-02-26 17:00:26 +00:00
Nick O'Leary
50a267528d Merge pull request #4580 from giscafer/remove-never-use-code
chore: remove never use import code
2024-02-26 16:58:20 +00:00
Nick O'Leary
220786be60 Do not flag env var in num typedInput as error 2024-02-26 16:55:01 +00:00
Nick O'Leary
fa78bb3d78 Handle undefined env vars
Fixes #4579
2024-02-26 16:17:09 +00:00
Nick O'Leary
9a32ebd0c0 Merge pull request #4578 from kazuhitoyokoi/master-fiximportdialog
Fix example flow name in import dialog
2024-02-26 16:09:10 +00:00
giscafer
4643f5e8cc chore: remove never use import code 2024-02-25 22:44:01 +08:00
Kazuhito Yokoi
7de0984d6d Update test case for example flow name 2024-02-25 17:38:46 +09:00
Kazuhito Yokoi
635334f096 Fix example flow name in import dialog 2024-02-25 17:04:42 +09:00
Nick O'Leary
f0d0990b5a Merge pull request #4575 from giscafer/master
fix: template node zh-CN translation
2024-02-22 13:03:24 +00:00
giscafer
43b3589451 fix: template node zh-CN translation 2024-02-22 13:02:06 +08:00
Nick O'Leary
016a19ba7c Merge pull request #4570 from node-red/fix-icon-scaling
Fix missing node icons in workspace
2024-02-20 10:37:33 +00:00
Nick O'Leary
aeb79bce2a Fix missing node icons in workspace 2024-02-19 16:07:22 +00:00
Jayson Hurst
0ab9b9a5fd Merge branch 'master' into fips 2024-02-16 17:53:30 -07:00
Jayson Hurst
56e58521bd Removed offending MD5 crypto hash and replaced with SHA1 and SHA256 crypto hashes to work with the FIPS crypto policy. 2024-02-17 00:35:03 +00:00
Nick O'Leary
b10ef4c98c Merge pull request #4564 from node-red/rel315
Bump for 3.1.5 release
2024-02-08 15:37:48 +00:00
Nick O'Leary
3ff038fb98 Bump for 3.1.5 release 2024-02-08 15:32:53 +00:00
Nick O'Leary
adb498af24 Merge pull request #4562 from node-red/fix-require
Fix require of dns module
2024-02-07 15:24:10 +00:00
Nick O'Leary
fc67a2efc2 Merge pull request #4561 from node-red/4560-fix-global-env-cred
Ensure global creds object is initialised when adding first cred
2024-02-07 14:52:17 +00:00
Nick O'Leary
55771c7241 Fix require of dns module 2024-02-07 14:50:46 +00:00
Nick O'Leary
109fa5f04e Ensure global creds object is initialised when adding first cred 2024-02-07 10:02:22 +00:00
33 changed files with 102 additions and 63 deletions

View File

@@ -1,3 +1,33 @@
#### 3.1.7: Maintenance Release
- Add Japanese translation for v3.1.6 (#4603) @kazuhitoyokoi
- Update jsonata version (#4593) @hardillb
#### 3.1.6: Maintenance Release
Editor
- Do not flag env var in num typedInput as error (#4582) @knolleary
- Fix example flow name in import dialog (#4578) @kazuhitoyokoi
- Fix missing node icons in workspace (#4570) @knolleary
Runtime
- Handle undefined env vars (#4581) @knolleary
- fix: Removed offending MD5 crypto hash and replaced with SHA1 and SHA256 … (#4568) @JaysonHurst
- chore: remove never use import code (#4580) @giscafer
Nodes
- fix: template node zh-CN translation (#4575) @giscafer
#### 3.1.5: Maintenance Release
Runtime
- Fix require of dns module (#4562) @knolleary
- Ensure global creds object is initialised when adding first cred (#4561) @knolleary
#### 3.1.4: Maintenance Release #### 3.1.4: Maintenance Release
Editor Editor

View File

@@ -1,6 +1,6 @@
{ {
"name": "node-red", "name": "node-red",
"version": "3.1.4", "version": "3.1.7",
"description": "Low-code programming for event-driven applications", "description": "Low-code programming for event-driven applications",
"homepage": "https://nodered.org", "homepage": "https://nodered.org",
"license": "Apache-2.0", "license": "Apache-2.0",
@@ -54,7 +54,7 @@
"is-utf8": "0.2.1", "is-utf8": "0.2.1",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"json-stringify-safe": "5.0.1", "json-stringify-safe": "5.0.1",
"jsonata": "1.8.6", "jsonata": "1.8.7",
"lodash.clonedeep": "^4.5.0", "lodash.clonedeep": "^4.5.0",
"media-typer": "1.1.0", "media-typer": "1.1.0",
"memorystore": "1.6.7", "memorystore": "1.6.7",

View File

@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
var apiUtils = require("../util");
var runtimeAPI; var runtimeAPI;
var settings; var settings;
var theme = require("../editor/theme"); var theme = require("../editor/theme");

View File

@@ -18,7 +18,6 @@ var BearerStrategy = require('passport-http-bearer').Strategy;
var ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy; var ClientPasswordStrategy = require('passport-oauth2-client-password').Strategy;
var passport = require("passport"); var passport = require("passport");
var crypto = require("crypto");
var util = require("util"); var util = require("util");
var Tokens = require("./tokens"); var Tokens = require("./tokens");

View File

@@ -14,11 +14,9 @@
* limitations under the License. * limitations under the License.
**/ **/
var express = require("express");
var path = require('path'); var path = require('path');
var comms = require("./comms"); var comms = require("./comms");
var library = require("./library");
var info = require("./settings"); var info = require("./settings");
var auth = require("../auth"); var auth = require("../auth");

View File

@@ -15,8 +15,6 @@
**/ **/
var apiUtils = require("../util"); var apiUtils = require("../util");
var fs = require('fs');
var fspath = require('path');
var runtimeAPI; var runtimeAPI;

View File

@@ -13,9 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
var fs = require('fs');
var path = require('path');
// var apiUtil = require('../util');
var i18n = require("@node-red/util").i18n; // TODO: separate module var i18n = require("@node-red/util").i18n; // TODO: separate module

View File

@@ -15,7 +15,6 @@
**/ **/
var apiUtils = require("../util"); var apiUtils = require("../util");
var express = require("express");
var runtimeAPI; var runtimeAPI;
var settings; var settings;

View File

@@ -14,7 +14,6 @@
* limitations under the License. * limitations under the License.
**/ **/
var express = require("express");
var util = require("util"); var util = require("util");
var path = require("path"); var path = require("path");
var fs = require("fs"); var fs = require("fs");

View File

@@ -99,7 +99,7 @@ module.exports = {
// settings.instanceId is set asynchronously to the editor-api // settings.instanceId is set asynchronously to the editor-api
// being initiaised. So we defer calculating the cacheBuster hash // being initiaised. So we defer calculating the cacheBuster hash
// until the first load of the editor // until the first load of the editor
cacheBuster = crypto.createHash('md5').update(`${settings.version || 'version'}-${settings.instanceId || 'instanceId'}`).digest("hex").substring(0,12) cacheBuster = crypto.createHash('sha1').update(`${settings.version || 'version'}-${settings.instanceId || 'instanceId'}`).digest("hex").substring(0,12)
} }
let sessionMessages; let sessionMessages;

View File

@@ -24,11 +24,8 @@
* @namespace @node-red/editor-api * @namespace @node-red/editor-api
*/ */
var express = require("express");
var bodyParser = require("body-parser"); var bodyParser = require("body-parser");
var util = require('util');
var passport = require('passport'); var passport = require('passport');
var cors = require('cors');
var auth = require("./auth"); var auth = require("./auth");
var apiUtil = require("./util"); var apiUtil = require("./util");

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/editor-api", "name": "@node-red/editor-api",
"version": "3.1.4", "version": "3.1.7",
"license": "Apache-2.0", "license": "Apache-2.0",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {
@@ -16,8 +16,8 @@
} }
], ],
"dependencies": { "dependencies": {
"@node-red/util": "3.1.4", "@node-red/util": "3.1.7",
"@node-red/editor-client": "3.1.4", "@node-red/editor-client": "3.1.7",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"body-parser": "1.20.2", "body-parser": "1.20.2",
"clone": "2.1.2", "clone": "2.1.2",

View File

@@ -303,7 +303,8 @@
"missingType": "不正なフロー - __index__ 番目の要素に'type'プロパティがありません" "missingType": "不正なフロー - __index__ 番目の要素に'type'プロパティがありません"
}, },
"conflictNotification1": "読み込もうとしているノードのいくつかは、既にワークスペース内に存在しています。", "conflictNotification1": "読み込もうとしているノードのいくつかは、既にワークスペース内に存在しています。",
"conflictNotification2": "読み込むノードを選択し、また既存のノードを置き換えるか、もしくはそれらのコピーを読み込むかも選択してください。" "conflictNotification2": "読み込むノードを選択し、また既存のノードを置き換えるか、もしくはそれらのコピーを読み込むかも選択してください。",
"alreadyExists": "本ノードは既に存在"
}, },
"copyMessagePath": "パスをコピーしました", "copyMessagePath": "パスをコピーしました",
"copyMessageValue": "値をコピーしました", "copyMessageValue": "値をコピーしました",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/editor-client", "name": "@node-red/editor-client",
"version": "3.1.4", "version": "3.1.7",
"license": "Apache-2.0", "license": "Apache-2.0",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@@ -906,7 +906,10 @@ RED.utils = (function() {
* @returns true if valid, String if invalid * @returns true if valid, String if invalid
*/ */
function validateTypedProperty(propertyValue, propertyType, opt) { function validateTypedProperty(propertyValue, propertyType, opt) {
if (propertyValue && /^\${[^}]+}$/.test(propertyValue)) {
// Allow ${ENV_VAR} value
return true
}
let error let error
if (propertyType === 'json') { if (propertyType === 'json') {
try { try {

View File

@@ -4156,7 +4156,7 @@ RED.view = (function() {
} }
var width = img.width * scaleFactor; var width = img.width * scaleFactor;
if (width > 20) { if (width > 20) {
scalefactor *= 20/width; scaleFactor *= 20/width;
width = 20; width = 20;
} }
var height = img.height * scaleFactor; var height = img.height * scaleFactor;

View File

@@ -16,8 +16,20 @@
RED.validators = { RED.validators = {
number: function(blankAllowed,mopt){ number: function(blankAllowed,mopt){
return function(v, opt) { return function(v, opt) {
if ((blankAllowed&&(v===''||v===undefined)) || (v!=='' && !isNaN(v))) { if (blankAllowed && (v === '' || v === undefined)) {
return true; return true
}
if (v !== '') {
if (/^NaN$|^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$|^[+-]?(0b|0B)[01]+$|^[+-]?(0o|0O)[0-7]+$|^[+-]?(0x|0X)[0-9a-fA-F]+$/.test(v)) {
return true
}
if (/^\${[^}]+}$/.test(v)) {
// Allow ${ENV_VAR} value
return true
}
}
if (!isNaN(v)) {
return true
} }
if (opt && opt.label) { if (opt && opt.label) {
return RED._("validator.errors.invalid-num-prop", { return RED._("validator.errors.invalid-num-prop", {

View File

@@ -227,34 +227,42 @@
name: {value:""}, name: {value:""},
props:{value:[{p:"payload"},{p:"topic",vt:"str"}], validate:function(v, opt) { props:{value:[{p:"payload"},{p:"topic",vt:"str"}], validate:function(v, opt) {
if (!v || v.length === 0) { return true } if (!v || v.length === 0) { return true }
const errors = []
for (var i=0;i<v.length;i++) { for (var i=0;i<v.length;i++) {
if (/^\${[^}]+}$/.test(v[i].v)) {
// Allow ${ENV_VAR} value
continue
}
if (/msg|flow|global/.test(v[i].vt)) { if (/msg|flow|global/.test(v[i].vt)) {
if (!RED.utils.validatePropertyExpression(v[i].v)) { if (!RED.utils.validatePropertyExpression(v[i].v)) {
return RED._("node-red:inject.errors.invalid-prop", { prop: 'msg.'+v[i].p, error: v[i].v }); errors.push(RED._("node-red:inject.errors.invalid-prop", { prop: 'msg.'+v[i].p, error: v[i].v }))
} }
} else if (v[i].vt === "jsonata") { } else if (v[i].vt === "jsonata") {
try{ jsonata(v[i].v); } try{ jsonata(v[i].v); }
catch(e){ catch(e){
return RED._("node-red:inject.errors.invalid-jsonata", { prop: 'msg.'+v[i].p, error: e.message }); errors.push(RED._("node-red:inject.errors.invalid-jsonata", { prop: 'msg.'+v[i].p, error: e.message }))
} }
} else if (v[i].vt === "json") { } else if (v[i].vt === "json") {
try{ JSON.parse(v[i].v); } try{ JSON.parse(v[i].v); }
catch(e){ catch(e){
return RED._("node-red:inject.errors.invalid-json", { prop: 'msg.'+v[i].p, error: e.message }); errors.push(RED._("node-red:inject.errors.invalid-json", { prop: 'msg.'+v[i].p, error: e.message }))
} }
} else if (v[i].vt === "num"){ } else if (v[i].vt === "num"){
if (!/^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/.test(v[i].v)) { if (!/^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/.test(v[i].v)) {
return RED._("node-red:inject.errors.invalid-prop", { prop: 'msg.'+v[i].p, error: v[i].v }); errors.push(RED._("node-red:inject.errors.invalid-prop", { prop: 'msg.'+v[i].p, error: v[i].v }))
} }
} }
} }
if (errors.length > 0) {
return errors
}
return true; return true;
} }
}, },
repeat: { repeat: {
value:"", validate: function(v, opt) { value:"", validate: function(v, opt) {
if ((v === "") || if ((v === "") ||
(RED.validators.number(v) && (RED.validators.number()(v) &&
(v >= 0) && (v <= 2147483))) { (v >= 0) && (v <= 2147483))) {
return true; return true;
} }
@@ -263,7 +271,7 @@
}, },
crontab: {value:""}, crontab: {value:""},
once: {value:false}, once: {value:false},
onceDelay: {value:0.1}, onceDelay: {value:0.1, validate: RED.validators.number(true)},
topic: {value:""}, topic: {value:""},
payload: {value:"", validate: RED.validators.typedInput("payloadType", false) }, payload: {value:"", validate: RED.validators.typedInput("payloadType", false) },
payloadType: {value:"date"}, payloadType: {value:"date"},

View File

@@ -23,7 +23,7 @@
<dt class="optional">template <span class="property-type">string</span></dt> <dt class="optional">template <span class="property-type">string</span></dt>
<dd><code>msg.payload</code>msg</dd> <dd><code>msg.payload</code>msg</dd>
</dl> </dl>
<h3>Outputs</h3> <h3>输出</h3>
<dl class="message-properties"> <dl class="message-properties">
<dt>msg <span class="property-type">object</span></dt> <dt>msg <span class="property-type">object</span></dt>
<dd>由来自传入msg的属性来填充已配置的模板后输出的带有属性的msg</dd> <dd>由来自传入msg的属性来填充已配置的模板后输出的带有属性的msg</dd>
@@ -32,7 +32,7 @@
<p>默认情况下使用<i><a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache</a></i>格式如有需要也可以切换其他格式</p> <p>默认情况下使用<i><a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache</a></i>格式如有需要也可以切换其他格式</p>
<p>例如: <p>例如:
<pre>Hello {{payload.name}}. Today is {{date}}</pre> <pre>Hello {{payload.name}}. Today is {{date}}</pre>
<p>receives a message containing: <p>接收一条消息其中包含:
<pre>{ <pre>{
date: "Monday", date: "Monday",
payload: { payload: {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/nodes", "name": "@node-red/nodes",
"version": "3.1.4", "version": "3.1.7",
"license": "Apache-2.0", "license": "Apache-2.0",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@@ -36,7 +36,7 @@ async function getFlowsFromPath(path) {
promises.push(getFlowsFromPath(fullPath)); promises.push(getFlowsFromPath(fullPath));
} else if (/\.json$/.test(file)){ } else if (/\.json$/.test(file)){
validFiles.push(file); validFiles.push(file);
promises.push(Promise.resolve(file.split(".")[0])) promises.push(Promise.resolve(file.replace(/\.json$/, '')))
} }
}) })
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/registry", "name": "@node-red/registry",
"version": "3.1.4", "version": "3.1.7",
"license": "Apache-2.0", "license": "Apache-2.0",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {
@@ -16,7 +16,7 @@
} }
], ],
"dependencies": { "dependencies": {
"@node-red/util": "3.1.4", "@node-red/util": "3.1.7",
"clone": "2.1.2", "clone": "2.1.2",
"fs-extra": "11.1.1", "fs-extra": "11.1.1",
"semver": "7.5.4", "semver": "7.5.4",

View File

@@ -485,7 +485,7 @@ class Flow {
} }
if (!key.startsWith("$parent.")) { if (!key.startsWith("$parent.")) {
if (this._env.hasOwnProperty(key)) { if (this._env.hasOwnProperty(key)) {
return (Object.hasOwn(this._env[key], 'value') && this._env[key].__clone__) ? clone(this._env[key].value) : this._env[key] return (this._env[key] && Object.hasOwn(this._env[key], 'value') && this._env[key].__clone__) ? clone(this._env[key].value) : this._env[key]
} }
} else { } else {
key = key.substring(8); key = key.substring(8);

View File

@@ -41,7 +41,7 @@ class Group {
} }
if (!key.startsWith("$parent.")) { if (!key.startsWith("$parent.")) {
if (this._env.hasOwnProperty(key)) { if (this._env.hasOwnProperty(key)) {
return (Object.hasOwn(this._env[key], 'value') && this._env[key].__clone__) ? clone(this._env[key].value) : this._env[key] return (this._env[key] && Object.hasOwn(this._env[key], 'value') && this._env[key].__clone__) ? clone(this._env[key].value) : this._env[key]
} }
} else { } else {
key = key.substring(8); key = key.substring(8);

View File

@@ -376,7 +376,7 @@ class Subflow extends Flow {
} }
if (!key.startsWith("$parent.")) { if (!key.startsWith("$parent.")) {
if (this._env.hasOwnProperty(key)) { if (this._env.hasOwnProperty(key)) {
return (Object.hasOwn(this._env[key], 'value') && this._env[key].__clone__) ? clone(this._env[key].value) : this._env[key] return (this._env[key] && Object.hasOwn(this._env[key], 'value') && this._env[key].__clone__) ? clone(this._env[key].value) : this._env[key]
} }
} else { } else {
key = key.substring(8); key = key.substring(8);

View File

@@ -384,7 +384,8 @@ var api = module.exports = {
} }
} }
} else if (nodeType === "global-config") { } else if (nodeType === "global-config") {
const existingCredentialKeys = Object.keys(savedCredentials?.map || []) savedCredentials.map = savedCredentials.map || {}
const existingCredentialKeys = Object.keys(savedCredentials.map)
const newCredentialKeys = Object.keys(newCreds?.map || []) const newCredentialKeys = Object.keys(newCreds?.map || [])
existingCredentialKeys.forEach(key => { existingCredentialKeys.forEach(key => {
if (!newCreds.map?.[key]) { if (!newCreds.map?.[key]) {
@@ -396,7 +397,7 @@ var api = module.exports = {
}) })
newCredentialKeys.forEach(key => { newCredentialKeys.forEach(key => {
if (!/^has_/.test(key)) { if (!/^has_/.test(key)) {
if (!savedCredentials.map?.[key] || newCreds.map[key] !== '__PWRD__') { if (!savedCredentials.map[key] || newCreds.map[key] !== '__PWRD__') {
// This key either doesn't exist in current saved, or the // This key either doesn't exist in current saved, or the
// value has been changed // value has been changed
savedCredentials.map[key] = newCreds.map[key] savedCredentials.map[key] = newCreds.map[key]

View File

@@ -77,7 +77,7 @@ var storageModuleInterface = {
flows: flows, flows: flows,
credentials: creds credentials: creds
}; };
result.rev = crypto.createHash('md5').update(JSON.stringify(result.flows)).digest("hex"); result.rev = crypto.createHash('sha256').update(JSON.stringify(result.flows)).digest("hex");
return result; return result;
}) })
}); });
@@ -95,7 +95,7 @@ var storageModuleInterface = {
return credentialSavePromise.then(function() { return credentialSavePromise.then(function() {
return storageModule.saveFlows(flows, user).then(function() { return storageModule.saveFlows(flows, user).then(function() {
return crypto.createHash('md5').update(JSON.stringify(config.flows)).digest("hex"); return crypto.createHash('sha256').update(JSON.stringify(config.flows)).digest("hex");
}) })
}); });
}, },

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/runtime", "name": "@node-red/runtime",
"version": "3.1.4", "version": "3.1.7",
"license": "Apache-2.0", "license": "Apache-2.0",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {
@@ -16,8 +16,8 @@
} }
], ],
"dependencies": { "dependencies": {
"@node-red/registry": "3.1.4", "@node-red/registry": "3.1.7",
"@node-red/util": "3.1.4", "@node-red/util": "3.1.7",
"async-mutex": "0.4.0", "async-mutex": "0.4.0",
"clone": "2.1.2", "clone": "2.1.2",
"express": "4.18.2", "express": "4.18.2",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/util", "name": "@node-red/util",
"version": "3.1.4", "version": "3.1.7",
"license": "Apache-2.0", "license": "Apache-2.0",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -18,7 +18,7 @@
"fs-extra": "11.1.1", "fs-extra": "11.1.1",
"i18next": "21.10.0", "i18next": "21.10.0",
"json-stringify-safe": "5.0.1", "json-stringify-safe": "5.0.1",
"jsonata": "1.8.6", "jsonata": "1.8.7",
"lodash.clonedeep": "^4.5.0", "lodash.clonedeep": "^4.5.0",
"moment": "2.29.4", "moment": "2.29.4",
"moment-timezone": "0.5.43" "moment-timezone": "0.5.43"

View File

@@ -26,8 +26,8 @@ var server = null;
var apiEnabled = false; var apiEnabled = false;
const NODE_MAJOR_VERSION = process.versions.node.split('.')[0]; const NODE_MAJOR_VERSION = process.versions.node.split('.')[0];
if (NODE_MAJOR_VERSION > 14) { if (NODE_MAJOR_VERSION >= 16) {
const dns = require('node:dns'); const dns = require('dns');
dns.setDefaultResultOrder('ipv4first'); dns.setDefaultResultOrder('ipv4first');
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "node-red", "name": "node-red",
"version": "3.1.4", "version": "3.1.7",
"description": "Low-code programming for event-driven applications", "description": "Low-code programming for event-driven applications",
"homepage": "https://nodered.org", "homepage": "https://nodered.org",
"license": "Apache-2.0", "license": "Apache-2.0",
@@ -31,10 +31,10 @@
"flow" "flow"
], ],
"dependencies": { "dependencies": {
"@node-red/editor-api": "3.1.4", "@node-red/editor-api": "3.1.7",
"@node-red/runtime": "3.1.4", "@node-red/runtime": "3.1.7",
"@node-red/util": "3.1.4", "@node-red/util": "3.1.7",
"@node-red/nodes": "3.1.4", "@node-red/nodes": "3.1.7",
"basic-auth": "2.0.1", "basic-auth": "2.0.1",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"express": "4.18.2", "express": "4.18.2",

View File

@@ -33,16 +33,15 @@ describe("library api", function() {
should.not.exist(library.getExampleFlowPath('foo','bar')); should.not.exist(library.getExampleFlowPath('foo','bar'));
}); });
it('returns a valid example path', function(done) { it('returns valid example paths', function(done) {
library.init(); library.init();
library.addExamplesDir("test-module",path.resolve(__dirname+'/resources/examples')).then(function() { library.addExamplesDir("test-module",path.resolve(__dirname+'/resources/examples')).then(function() {
try { try {
var flows = library.getExampleFlows(); var flows = library.getExampleFlows();
flows.should.deepEqual({"test-module":{"f":["one"]}}); flows.should.deepEqual({"test-module":{"f":["1.2.3","one"]}});
var examplePath = library.getExampleFlowPath('test-module','one'); var examplePath = library.getExampleFlowPath('test-module','one');
examplePath.should.eql(path.resolve(__dirname+'/resources/examples/one.json')) examplePath.should.eql(path.resolve(__dirname+'/resources/examples/one.json'));
library.removeExamplesDir('test-module'); library.removeExamplesDir('test-module');
@@ -57,6 +56,5 @@ describe("library api", function() {
done(err); done(err);
} }
}); });
});
})
}); });