From 80d100f3f9cc41ed4489ee33424b7c6560d9c4f5 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Fri, 7 Feb 2020 16:49:41 +0000
Subject: [PATCH 01/67] Move receive metric position to better reflect async
changes Fixes #2444
---
packages/node_modules/@node-red/runtime/lib/nodes/Node.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/Node.js b/packages/node_modules/@node-red/runtime/lib/nodes/Node.js
index c62895f7f..a834c8c34 100644
--- a/packages/node_modules/@node-red/runtime/lib/nodes/Node.js
+++ b/packages/node_modules/@node-red/runtime/lib/nodes/Node.js
@@ -193,6 +193,7 @@ Node.prototype.emit = function(event, ...args) {
*/
Node.prototype._emitInput = function(arg) {
var node = this;
+ this.metric("receive", arg);
if (node._inputCallback) {
// Just one callback registered.
try {
@@ -448,7 +449,6 @@ Node.prototype.receive = function(msg) {
if (!msg._msgid) {
msg._msgid = redUtil.generateId();
}
- this.metric("receive",msg);
this.emit("input",msg);
};
From 389cbf4900c1d9b339c0323e7cb5628f7f8c9196 Mon Sep 17 00:00:00 2001
From: JIYE YU
Date: Mon, 10 Feb 2020 11:31:37 +0900
Subject: [PATCH 02/67] complete traditional chinese translation
---
.../editor-client/locales/zh-CN/editor.json | 5 +-
.../editor-client/locales/zh-CN/jsonata.json | 4 +
.../editor-client/locales/zh-TW/editor.json | 144 ++++--
.../editor-client/locales/zh-TW/jsonata.json | 52 +++
.../nodes/locales/zh-CN/messages.json | 10 +-
.../nodes/locales/zh-TW/common/20-inject.html | 35 ++
.../nodes/locales/zh-TW/common/21-debug.html | 25 +
.../locales/zh-TW/common/24-complete.html | 24 +
.../nodes/locales/zh-TW/common/25-catch.html | 36 ++
.../nodes/locales/zh-TW/common/25-status.html | 33 ++
.../nodes/locales/zh-TW/common/60-link.html | 31 ++
.../locales/zh-TW/common/90-comment.html | 21 +
.../locales/zh-TW/common/98-unknown.html | 24 +
.../locales/zh-TW/function/10-function.html | 51 ++
.../locales/zh-TW/function/10-switch.html | 37 ++
.../locales/zh-TW/function/15-change.html | 33 ++
.../locales/zh-TW/function/16-range.html | 40 ++
.../locales/zh-TW/function/80-template.html | 46 ++
.../locales/zh-TW/function/89-delay.html | 32 ++
.../locales/zh-TW/function/89-trigger.html | 33 ++
.../nodes/locales/zh-TW/function/90-exec.html | 74 +++
.../nodes/locales/zh-TW/messages.json | 434 ++++++++++--------
.../nodes/locales/zh-TW/network/05-tls.html | 19 +
.../locales/zh-TW/network/06-httpproxy.html | 22 +
.../nodes/locales/zh-TW/network/10-mqtt.html | 70 +++
.../locales/zh-TW/network/21-httpin.html | 81 ++++
.../locales/zh-TW/network/21-httprequest.html | 78 ++++
.../locales/zh-TW/network/22-websocket.html | 35 ++
.../nodes/locales/zh-TW/network/31-tcpin.html | 35 ++
.../nodes/locales/zh-TW/network/32-udp.html | 28 ++
.../nodes/locales/zh-TW/parsers/70-CSV.html | 43 ++
.../nodes/locales/zh-TW/parsers/70-HTML.html | 33 ++
.../nodes/locales/zh-TW/parsers/70-JSON.html | 43 ++
.../nodes/locales/zh-TW/parsers/70-XML.html | 48 ++
.../nodes/locales/zh-TW/parsers/70-YAML.html | 34 ++
.../locales/zh-TW/sequence/17-split.html | 133 ++++++
.../nodes/locales/zh-TW/sequence/18-sort.html | 41 ++
.../locales/zh-TW/sequence/19-batch.html | 34 ++
.../nodes/locales/zh-TW/storage/10-file.html | 59 +++
.../nodes/locales/zh-TW/storage/23-watch.html | 25 +
.../runtime/locales/zh-TW/runtime.json | 174 +++++++
41 files changed, 2013 insertions(+), 246 deletions(-)
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/common/20-inject.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/common/21-debug.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/common/24-complete.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-catch.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-status.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/common/60-link.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/common/90-comment.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/common/98-unknown.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-function.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-switch.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/function/15-change.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/function/16-range.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/function/80-template.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-delay.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-trigger.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/function/90-exec.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/network/05-tls.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/network/06-httpproxy.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/network/10-mqtt.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httpin.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httprequest.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/network/22-websocket.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/network/31-tcpin.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/network/32-udp.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-CSV.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-HTML.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-JSON.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-XML.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-YAML.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/17-split.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/18-sort.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/19-batch.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/storage/10-file.html
create mode 100644 packages/node_modules/@node-red/nodes/locales/zh-TW/storage/23-watch.html
create mode 100644 packages/node_modules/@node-red/runtime/locales/zh-TW/runtime.json
diff --git a/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json b/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json
index 3695eb263..95d3fa5ee 100644
--- a/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json
+++ b/packages/node_modules/@node-red/editor-client/locales/zh-CN/editor.json
@@ -24,7 +24,7 @@
"buffer": "buffer",
"object": "对象",
"jsonString": "JSON字符串",
- "undefined": "为定义",
+ "undefined": "未定义",
"null": "空"
}
},
@@ -1008,6 +1008,7 @@
"en-US": "英文",
"ja": "日语",
"ko": "韩文",
- "zh-CN": "简体中文"
+ "zh-CN": "简体中文",
+ "zh-TW": "繁体中文"
}
}
diff --git a/packages/node_modules/@node-red/editor-client/locales/zh-CN/jsonata.json b/packages/node_modules/@node-red/editor-client/locales/zh-CN/jsonata.json
index 56ede1b4e..f27ec1f51 100644
--- a/packages/node_modules/@node-red/editor-client/locales/zh-CN/jsonata.json
+++ b/packages/node_modules/@node-red/editor-client/locales/zh-CN/jsonata.json
@@ -262,5 +262,9 @@
"$distinct": {
"args": "array",
"desc": "返回一个数组,其中重复的值已从`数组`中删除"
+ },
+ "$type": {
+ "args": "value",
+ "desc": "以字符串形式返回`值`的类型。 如果该`值`未定义,则将返回`未定义`"
}
}
diff --git a/packages/node_modules/@node-red/editor-client/locales/zh-TW/editor.json b/packages/node_modules/@node-red/editor-client/locales/zh-TW/editor.json
index 492fce58c..897599bc7 100644
--- a/packages/node_modules/@node-red/editor-client/locales/zh-TW/editor.json
+++ b/packages/node_modules/@node-red/editor-client/locales/zh-TW/editor.json
@@ -15,6 +15,17 @@
"next": "下一步",
"clone": "複製專案",
"cont": "Continue"
+ },
+ "type": {
+ "string": "字符串",
+ "number": "數值",
+ "boolean": "布林",
+ "array": "數組",
+ "buffer": "buffer",
+ "object": "對象",
+ "jsonString": "JSON字符串",
+ "undefined": "未定義",
+ "null": "空"
}
},
"workspace": {
@@ -29,8 +40,7 @@
"enabled": "有效",
"disabled": "無效",
"info": "詳細描述",
- "selectNodes": "點擊節點用於選擇",
- "tip": "詳細描述支援Markdown羽量級標記語言,並將出現在資訊標籤中。"
+ "selectNodes": "點擊節點用於選擇"
},
"menu": {
"label": {
@@ -45,14 +55,14 @@
"ltr": "從左到右",
"rtl": "從右到左",
"auto": "上下文",
- "language": "Language",
- "browserDefault": "Browser default"
+ "language": "語言",
+ "browserDefault": "瀏覽器默認"
},
"sidebar": {
"show": "顯示側邊欄"
},
"palette": {
- "show": "Show palette"
+ "show": "顯示控制板"
},
"settings": "設置",
"userSettings": "使用者設置",
@@ -81,10 +91,7 @@
"projects-new": "新專案",
"projects-open": "開啟專案",
"projects-settings": "專案設定",
- "showNodeLabelDefault": "顯示新添加節點的標籤",
- "clipboard": "剪貼簿",
- "library": "庫",
- "examples": "範例"
+ "showNodeLabelDefault": "顯示新添加節點的標籤"
}
},
"actions": {
@@ -204,8 +211,7 @@
},
"copyMessagePath": "已複製路徑",
"copyMessageValue": "已複製數值",
- "copyMessageValue_truncated": "已複製捨棄的數值",
- "selectNodes": "選擇上面的文本並複製到剪貼簿"
+ "copyMessageValue_truncated": "已複製捨棄的數值"
},
"deploy": {
"deploy": "部署",
@@ -237,7 +243,7 @@
"undeployedChanges": "您有未部署的更改。\n\n離開此頁面將丟失這些更改。",
"improperlyConfigured": "工作區包含一些未正確配置的節點:",
"unknown": "工作區包含一些未知的節點類型:",
- "confirm": "你確定要部署嗎?",
+ "confirm": "確定要部署嗎?",
"doNotWarn": "不要再對此發出警告",
"conflict": "伺服器正在運行較新的一組流程。",
"backgroundUpdate": "伺服器上的流程已更新。",
@@ -300,8 +306,7 @@
"errors": {
"noNodesSelected": "無法創建子流程 : 未選擇節點",
"multipleInputsToSelection": "無法創建子流程 : 多個輸入到了選擇"
- },
- "format": "標記格式"
+ }
},
"editor": {
"configEdit": "編輯",
@@ -316,17 +321,53 @@
"addNewType": "添加新的__type__節點",
"nodeProperties": "節點屬性",
"label": "Label",
+ "color": "顏色",
"portLabels": "埠標籤",
"labelInputs": "輸入",
"labelOutputs": "輸出",
"settingIcon": "Icon",
+ "default": "默認",
"noDefaultLabel": "無",
"defaultLabel": "使用默認標籤",
- "searchIcons": "搜尋 icons",
+ "searchIcons": "搜尋圖標",
"useDefault": "使用默認",
"description": "描述",
"show": "顯示",
"hide": "隱藏",
+ "locale": "選擇界面語言",
+ "icon": "圖標",
+ "inputType": "輸入類型",
+ "inputs": {
+ "input": "輸入",
+ "select": "選擇",
+ "checkbox": "復選框",
+ "spinner": "微調器",
+ "none": "空",
+ "hidden": "隱藏屬性"
+ },
+ "types": {
+ "str": "字符串",
+ "num": "數字",
+ "bool": "布爾",
+ "json": "JSON",
+ "bin": "buffer",
+ "env": "環境變量"
+ },
+ "menu": {
+ "input": "輸入",
+ "select": "選擇",
+ "checkbox": "復選框",
+ "spinner": "微調器",
+ "hidden": "僅標簽"
+ },
+ "select": {
+ "label": "標簽",
+ "value": "值"
+ },
+ "spinner": {
+ "min": "最小值",
+ "max": "最大值"
+ },
"errors": {
"scopeChange": "更改範圍將使其他流程中的節點無法使用",
"invalidProperties": "無效的屬性:"
@@ -356,8 +397,9 @@
"cutNode": "剪切所選節點",
"pasteNode": "粘貼節點",
"undoChange": "撤銷上次執行的更改",
- "searchBox": "打開搜索框",
- "managePalette": "管理面板"
+ "searchBox": "打開搜尋框",
+ "managePalette": "管理面板",
+ "actionList": "動作列表"
},
"library": {
"library": "庫",
@@ -371,28 +413,27 @@
"savedNodes": "保存的節點",
"savedType": "已保存__type__",
"saveFailed": "保存失敗: __message__",
+ "newFolder": "新文件夾",
"types": {
"local": "本地",
"examples": "例子"
},
- "exportToLibrary": "將節點匯出到庫",
- "filename": "檔案名",
- "folder": "資料夾",
- "filenamePlaceholder": "文件",
- "fullFilenamePlaceholder": "a/b/文件",
- "folderPlaceholder": "a/b",
- "breadcrumb": "庫"
+ "exportToLibrary": "將節點匯出到庫"
},
"palette": {
"noInfo": "無可用資訊",
"filter": "過濾節點",
- "search": "搜索模組",
+ "search": "搜尋模組",
"addCategory": "添加新的...",
"label": {
"subflows": "子流程",
+ "network": "網絡",
+ "common": "共通",
"input": "輸入",
"output": "輸出",
"function": "功能",
+ "sequence": "序列",
+ "parser": "解析",
"social": "社交",
"storage": "存儲",
"analysis": "分析",
@@ -459,7 +500,7 @@
"sortRecent": "日期順序",
"more": "增加__count__個",
"errors": {
- "catalogLoadFailed": "無法載入節點目錄。 查看瀏覽器控制台瞭解更多資訊",
+ "catalogLoadFailed": "無法載入節點目錄。 查看瀏覽器控制臺瞭解更多資訊",
"installFailed": "無法安裝: __module__ __message__ 查看日誌瞭解更多資訊",
"removeFailed": "無法刪除: __module__ __message__ 查看日誌瞭解更多資訊",
"updateFailed": "無法更新: __module__ __message__ 查看日誌瞭解更多資訊",
@@ -529,8 +570,10 @@
"none": "無",
"subflows": "子流程",
"flows": "流程",
- "filterUnused": "未使用",
"filterAll": "所有",
+ "showAllConfigNodes": "顯示所有配置節點",
+ "filterUnused": "未使用",
+ "showAllUnusedConfigNodes": "顯示所有未使用的配置節點",
"filtered": "__count__ 個隱藏"
},
"context": {
@@ -543,7 +586,9 @@
"flow": "流程",
"global": "全局的",
"deleteConfirm": "你確定要刪除這個項目嗎?",
- "autoRefresh": "自動刷新"
+ "autoRefresh": "自動刷新",
+ "refrsh": "刷新",
+ "delete": "刪除"
},
"palette": {
"name": "節點管理",
@@ -558,6 +603,7 @@
"noSummaryAvailable": "無可用摘要",
"editDescription": "編輯專案描述",
"editDependencies": "編輯項目依賴",
+ "noDescriptionAvailable": "沒有可用的描述",
"editReadme": "Edit README.md",
"showProjectSettings": "顯示項目設置",
"projectSettings": {
@@ -657,15 +703,15 @@
"moreCommits": "更多提交",
"changeLocalBranch": "變更當地分支",
"createBranchPlaceholder": "查找或創建分支",
- "upstream": "上游的",
- "localOverwrite": "您有可通过切换分支覆盖的本地更改。您必须先提交或撤销那些更改。",
+ "upstream": "上遊的",
+ "localOverwrite": "您有可通過切換分支覆蓋的本地更改。您必須先提交或撤銷那些更改。",
"manageRemoteBranch": "管理遠程分支",
"unableToAccess": "無法訪問遠程存儲庫",
"retry": "重試",
- "setUpstreamBranch": "設置為上游分支",
+ "setUpstreamBranch": "設置為上遊分支",
"createRemoteBranchPlaceholder": "查找或創建遠程分支",
- "trackedUpstreamBranch": "創建的分支將被設置為跟踪的上游分支。",
- "selectUpstreamBranch": "分支將被創建。 在下面選擇以將其設置為被跟踪的上游分支。",
+ "trackedUpstreamBranch": "創建的分支將被設置為跟蹤的上遊分支。",
+ "selectUpstreamBranch": "分支將被創建。 在下面選擇以將其設置為被跟蹤的上遊分支。",
"pushFailed": "Push失敗,因為遠程具有更多的最新提交。請先進行pull與merge,然後再嘗試push。",
"push": "push",
"pull": "pull",
@@ -683,7 +729,7 @@
"minsAgo": "__count__分鐘前",
"minsAgo_plural": "__count__分鐘前",
"secondsAgo": "秒前",
- "notTracking": "您的本地分支當前未跟踪遠程分支。",
+ "notTracking": "您的本地分支當前未跟蹤遠程分支。",
"statusUnmergedChanged": "您的存儲庫中有未合併的更改。您需要解決衝突並提交結果。",
"repositoryUpToDate": "您的存儲庫是最新的。",
"commitsAhead": "您的倉庫領先遠程倉庫__count__次提交。您現在可以push這些提交。",
@@ -748,10 +794,23 @@
},
"jsonEditor": {
"title": "JSON編輯器",
- "format": "格式化JSON"
+ "format": "格式化JSON",
+ "rawMode": "編輯 JSON",
+ "uiMode": "Visual編輯器",
+ "insertAbove": "在上方插入",
+ "insertBelow": "在下方插入",
+ "addItem": "添加項目",
+ "copyPath": "復制路徑到項目",
+ "expandItems": "展開項目",
+ "collapseItems": "收合項目",
+ "duplicate": "重復",
+ "error": {
+ "invalidJSON": "無效的JSON: "
+ }
},
"markdownEditor": {
"title": "Markdown 編輯器",
+ "expand": "展開",
"format": "F使用markdown格式化",
"heading1": "Heading 1",
"heading2": "Heading 2",
@@ -786,7 +845,7 @@
},
"git-config": {
"setup": "設置您的版本控制客戶端",
- "desc0": "Node-RED使用開源工具Git進行版本控制。 它跟踪對項目文件的更改,並允許您將其推送到遠程存儲庫。",
+ "desc0": "Node-RED使用開源工具Git進行版本控制。 它跟蹤對項目文件的更改,並允許您將其推送到遠程存儲庫。",
"desc1": "提交一組更改時,Git會使用用戶名和電子郵件地址記錄誰進行了更改。 用戶名可以是您想要的任何名稱-不必是您的真實姓名。",
"desc2": "您的Git客戶端已經配置了以下詳細信息。",
"desc3": "您可以稍後在設置對話框的“ Git config”標籤下更改這些設置。",
@@ -905,7 +964,7 @@
"confirm": "您確定要刪除此項目嗎?"
},
"create-project-list": {
- "search": "搜索您的項目",
+ "search": "搜尋您的項目",
"current": "當前的"
},
"require-clean": {
@@ -938,8 +997,19 @@
},
"editor-tab": {
"properties": "屬性",
+ "envProperties": "環境變量",
"description": "描述",
"appearance": "外觀",
+ "preview": "UI預覽",
+ "defaultValue": "默認值",
"env": "環境變量"
+ },
+ "languages": {
+ "de": "德語",
+ "en-US": "英語",
+ "ja": "日語",
+ "ko": "韓語",
+ "zh-CN": "簡體中文",
+ "zh-TW": "繁體中文"
}
}
diff --git a/packages/node_modules/@node-red/editor-client/locales/zh-TW/jsonata.json b/packages/node_modules/@node-red/editor-client/locales/zh-TW/jsonata.json
index ae62fe068..6d99ffc6a 100644
--- a/packages/node_modules/@node-red/editor-client/locales/zh-TW/jsonata.json
+++ b/packages/node_modules/@node-red/editor-client/locales/zh-TW/jsonata.json
@@ -214,5 +214,57 @@
"$toMillis": {
"args": "timestamp",
"desc": "將ISO 8601格式的字串`timestamp`轉換為從UNIX時間 (1970年1月1日 UTC/GMT的午夜)開始到現在的毫秒數。如果該字串的格式不正確,則拋出錯誤。"
+ },
+ "$env": {
+ "args": "arg",
+ "desc": "返回環境變量的值。\n\n這是Node-RED定義的函數。"
+ },
+ "$eval": {
+ "args": "expr [, context]",
+ "desc": "使用當前上下文來作為評估依據,分析並評估字符串`expr`,其中包含文字JSON或JSONata表達式。"
+ },
+ "$formatInteger": {
+ "args": "number, picture",
+ "desc": "將“數字”轉換為字符串,並將其格式化為“圖片”字符串指定的整數表示形式。圖片字符串參數定義了數字的格式,並具有與XPath F&O 3.1 規範中的fn:format-integer相同的語法。"
+ },
+ "$parseInteger": {
+ "args": "string, picture",
+ "desc": "使用“圖片”字符串指定的格式將“字符串”參數的內容解析為整數(作為JSON數字)。圖片字符串參數與$formatInteger格式相同。."
+ },
+ "$error": {
+ "args": "[str]",
+ "desc": "引發錯誤並顯示一條消息。 可選的`str`將替代$error()函數評估的默認消息。"
+ },
+ "$assert": {
+ "args": "arg, str",
+ "desc": "如果`arg`為真,則該函數返回。 如果arg為假,則拋出帶有str的異常作為異常消息。"
+ },
+ "$single": {
+ "args": "array, function",
+ "desc": "返回滿足參數function謂語的array參數中的唯一值 (比如:傳遞值時,函數返回布林值“true”)。如果匹配值的數量不唯一時,則拋出異常。\n\n應在以下簽名中提供函數:`function(value [,index [,array []]])`其中value是數組的每個輸入,index是該值的位置,整個數組作為第三個參數傳遞。"
+ },
+ "$encodeUrl": {
+ "args": "str",
+ "desc": "通過用表示字符的UTF-8編碼的一個,兩個,三個或四個轉義序列替換某些字符的每個實例,對統一資源定位符(URL)組件進行編碼。\n\n示例:`$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
+ },
+ "$encodeUrlComponent": {
+ "args": "str",
+ "desc": "通過用表示字符的UTF-8編碼的一個,兩個,三個或四個轉義序列替換某些字符的每個實例,對統一資源定位符(URL)進行編碼。\n\n示例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
+ },
+ "$decodeUrl": {
+ "args": "str",
+ "desc": "解碼以前由encodeUrlComponent創建的統一資源定位器(URL)組件。 \n\n示例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
+ },
+ "$decodeUrlComponent": {
+ "args": "str",
+ "desc": "解碼先前由encodeUrl創建的統一資源定位符(URL)。 \n\n示例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
+ },
+ "$distinct": {
+ "args": "array",
+ "desc": "返回一個數組,其中重復的值已從`數組`中刪除"
+ },
+ "$type": {
+ "args": "value",
+ "desc": "以字符串形式返回`值`的類型。 如果該`值`未定義,則將返回`未定義`"
}
}
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json b/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json
index 46560d181..4fc5dc4d4 100644
--- a/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json
@@ -698,7 +698,7 @@
"output": "输出",
"includerow": "包含列名行",
"newline": "换行符",
- "usestrings": "parse numerical values"
+ "usestrings": "解析数值"
},
"placeholder": {
"columns": "用逗号分割列名"
@@ -898,7 +898,7 @@
}
},
"sort" : {
- "sort": "sort",
+ "sort": "排序",
"target" : "排序属性",
"seq" : "信息队列",
"key" : "键值",
@@ -907,9 +907,9 @@
"ascending" : "升序",
"descending" : "降序",
"as-number" : "作为数值",
- "invalid-exp" : "sort节点中存在无效的JSONata表达式",
- "too-many" : "sort节点中有太多待定信息",
- "clear" : "清空sort节点中的待定信息"
+ "invalid-exp" : "排序节点中存在无效的JSONata表达式",
+ "too-many" : "排序节点中有太多待定信息",
+ "clear" : "清空排序节点中的待定信息"
},
"batch" : {
"batch": "batch",
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/common/20-inject.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/20-inject.html
new file mode 100644
index 000000000..046eddd7e
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/20-inject.html
@@ -0,0 +1,35 @@
+
+
+
+
\ No newline at end of file
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/common/21-debug.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/21-debug.html
new file mode 100644
index 000000000..31f78e907
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/21-debug.html
@@ -0,0 +1,25 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/common/24-complete.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/24-complete.html
new file mode 100644
index 000000000..862745310
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/24-complete.html
@@ -0,0 +1,24 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-catch.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-catch.html
new file mode 100644
index 000000000..4e3db015d
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-catch.html
@@ -0,0 +1,36 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-status.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-status.html
new file mode 100644
index 000000000..d961c8e52
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/25-status.html
@@ -0,0 +1,33 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/common/60-link.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/60-link.html
new file mode 100644
index 000000000..e7723c499
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/60-link.html
@@ -0,0 +1,31 @@
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/common/90-comment.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/90-comment.html
new file mode 100644
index 000000000..d044f28db
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/90-comment.html
@@ -0,0 +1,21 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/common/98-unknown.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/98-unknown.html
new file mode 100644
index 000000000..c3588def1
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/common/98-unknown.html
@@ -0,0 +1,24 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-function.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-function.html
new file mode 100644
index 000000000..9f8ddb43f
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-function.html
@@ -0,0 +1,51 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-switch.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-switch.html
new file mode 100644
index 000000000..5a65eff93
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/10-switch.html
@@ -0,0 +1,37 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/function/15-change.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/15-change.html
new file mode 100644
index 000000000..91a320945
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/15-change.html
@@ -0,0 +1,33 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/function/16-range.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/16-range.html
new file mode 100644
index 000000000..62eb63d0b
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/16-range.html
@@ -0,0 +1,40 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/function/80-template.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/80-template.html
new file mode 100644
index 000000000..874ae3801
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/80-template.html
@@ -0,0 +1,46 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-delay.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-delay.html
new file mode 100644
index 000000000..28c291de8
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-delay.html
@@ -0,0 +1,32 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-trigger.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-trigger.html
new file mode 100644
index 000000000..6bbe72f4d
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/89-trigger.html
@@ -0,0 +1,33 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/function/90-exec.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/90-exec.html
new file mode 100644
index 000000000..27be34e00
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/function/90-exec.html
@@ -0,0 +1,74 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json b/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json
index 153a88300..7ece3333d 100644
--- a/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json
@@ -6,7 +6,9 @@
"name": "名稱",
"username": "使用者名稱",
"password": "密碼",
- "property": "屬性"
+ "property": "屬性",
+ "selectNodes": "選擇節點...",
+ "expand": "擴展"
},
"status": {
"connected": "已連接",
@@ -35,7 +37,22 @@
"stopped": "停止",
"failed": "注入失敗: __error__",
"label": {
- "repeat": "重複"
+ "repeat": "重複",
+ "flow": "流上下午",
+ "global": "全局上下文",
+ "str": "字符串",
+ "num": "數值",
+ "bool": "布爾值",
+ "json": "JSON對象",
+ "bin": "buffer",
+ "date": "時間戳",
+ "env": "環境變量",
+ "object": "對象",
+ "string": "字符串",
+ "boolean": "布爾值",
+ "number": "數值",
+ "Array": "數組",
+ "invalid": "無效的JSON對象"
},
"timestamp": "時間戳記",
"none": "無",
@@ -72,13 +89,11 @@
"catch": {
"catch": "監測所有節點",
"catchNodes": "監測__number__個節點",
+ "catchUncaught": "捕獲:未捕獲",
"label": {
"source": "監測範圍",
- "node": "節點",
- "type": "類型",
"selectAll": "全選",
- "sortByLabel": "按名稱排序",
- "sortByType": "按類型排序"
+ "uncaught": "忽略其他捕獲節點處理的錯誤"
},
"scope": {
"all": "所有節點",
@@ -90,10 +105,6 @@
"statusNodes": "報告__number__個節點狀態",
"label": {
"source": "報告狀態範圍",
- "node": "節點",
- "type": "類型",
- "selectAll": "全選",
- "sortByLabel": "按名稱排序",
"sortByType": "按類型排序"
},
"scope": {
@@ -101,8 +112,13 @@
"selected": "指定節點"
}
},
+ "complete": {
+ "completeNodes": "完成: __number__個節點"
+ },
"debug": {
"output": "輸出",
+ "none": "None",
+ "invalid-exp": "無效的JSONata表達式: __error__",
"msgprop": "資訊屬性",
"msgobj": "完整資訊",
"to": "目標",
@@ -124,7 +140,11 @@
"filterCurrent": "當前流程",
"debugNodes": "除錯節點",
"clearLog": "清空日誌",
- "openWindow": "在新視窗打開"
+ "filterLog": "過濾日誌",
+ "openWindow": "在新視窗打開",
+ "copyPath": "復制路徑",
+ "copyPayload": "復制值",
+ "pinPath": "固定展開"
},
"messageMenu": {
"collapseAll": "折疊所有路徑",
@@ -146,26 +166,33 @@
"key": "私密金鑰",
"passphrase": "密碼",
"ca": "CA證書",
- "verify-server-cert":"驗證伺服器憑證"
+ "verify-server-cert": "驗證伺服器憑證",
+ "servername": "服務器名"
},
"placeholder": {
- "cert":"憑證路徑 (PEM 格式)",
- "key":"私密金鑰路徑 (PEM 格式)",
- "ca":"CA憑證路徑 (PEM 格式)",
- "passphrase":"私密金鑰密碼 (可選)"
+ "cert": "憑證路徑 (PEM 格式)",
+ "key": "私密金鑰路徑 (PEM 格式)",
+ "ca": "CA憑證路徑 (PEM 格式)",
+ "passphrase": "私密金鑰密碼 (可選)",
+ "servername": "用於SNI"
},
"error": {
"missing-file": "未提供證書/金鑰檔案"
}
},
"exec": {
+ "exec": "exec",
+ "spawn": "spawn",
"label": {
"command": "命令",
"append": "追加",
"timeout": "超時",
"timeoutplace": "可選填",
"return": "輸出",
- "seconds": "秒"
+ "seconds": "秒",
+ "stdout": "標準輸出",
+ "stderr": "標準錯誤輸出",
+ "retcode": "返回碼"
},
"placeholder": {
"extraparams": "額外的輸入參數"
@@ -177,16 +204,18 @@
"oldrc": "使用舊式輸出 (相容模式)"
},
"function": {
+ "function": "函數",
"label": {
"function": "函數",
"outputs": "輸出"
},
"error": {
- "inputListener":"無法在函數中監聽對'注入'事件",
- "non-message-returned":"函數節點嘗試返回類型為 __type__ 的資訊"
+ "inputListener": "無法在函數中監聽對'注入'事件",
+ "non-message-returned": "函數節點嘗試返回類型為 __type__ 的資訊"
}
},
"template": {
+ "template": "模板",
"label": {
"template": "模版",
"property": "屬性",
@@ -233,21 +262,21 @@
"limit": "限制",
"limitTopic": "限制主題",
"random": "隨機",
- "units" : {
+ "units": {
"second": {
- "plural" : "秒",
+ "plural": "秒",
"singular": "秒"
},
"minute": {
- "plural" : "分鐘",
+ "plural": "分鐘",
"singular": "分鐘"
},
"hour": {
- "plural" : "小時",
+ "plural": "小時",
"singular": "小時"
},
"day": {
- "plural" : "天",
+ "plural": "天",
"singular": "天"
}
}
@@ -272,6 +301,9 @@
"wait-reset": "等待被重置",
"wait-for": "等待",
"wait-loop": "週期性重發",
+ "for": "處理",
+ "bytopics": "每個msg.topic",
+ "alltopics": "所有消息",
"duration": {
"ms": "毫秒",
"s": "秒",
@@ -284,12 +316,13 @@
"trigger-block": "觸發並阻止",
"trigger-loop": "週期性重發",
"reset": "重置觸發節點條件 如果:",
- "resetMessage":"msg.reset已設置",
- "resetPayload":"msg.payload等於",
+ "resetMessage": "msg.reset已設置",
+ "resetPayload": "msg.payload等於",
"resetprompt": "可選填"
}
},
"comment": {
+ "comment": "注釋"
},
"unknown": {
"label": {
@@ -303,26 +336,32 @@
"example": "e.g. localhost",
"output": "輸出",
"qos": "QoS",
+ "retain": "保持",
"clientid": "使用者端ID",
"port": "埠",
"keepalive": "Keepalive計時(秒)",
"cleansession": "使用新的會話",
"use-tls": "使用安全連接 (SSL/TLS)",
- "tls-config":"TLS 設置",
- "verify-server-cert":"驗證伺服器憑證",
+ "tls-config": "TLS 設置",
+ "verify-server-cert": "驗證伺服器憑證",
"compatmode": "使用舊式MQTT 3.1支援"
},
+ "sections-label": {
+ "birth-message": "連接時發送的消息(出生消息)",
+ "will-message": "意外斷開連接時的發送消息(Will消息)",
+ "close-message": "斷開連接前發送的消息(關閉消息)"
+ },
"tabs-label": {
"connection": "連接",
"security": "安全",
- "will": "Will信息",
- "birth": "Birth信息"
+ "messages": "消息"
},
"placeholder": {
"clientid": "留白則自動隨機生成",
- "clientid-nonclean":"如非新會話,必須設置使用者端ID",
+ "clientid-nonclean": "如非新會話,必須設置使用者端ID",
"will-topic": "留白將禁止Will資訊",
- "birth-topic": "留白將禁止Birth資訊"
+ "birth-topic": "留白將禁止Birth資訊",
+ "close-topic": "留白以禁用關閉消息"
},
"state": {
"connected": "已連接到服務端: __broker__",
@@ -333,7 +372,9 @@
"output": {
"buffer": "Buffer",
"string": "字串",
- "base64": "Base64編碼字串"
+ "base64": "Base64編碼字串",
+ "auto": "自動檢測 (字符串或buffer)",
+ "json": "解析的JSON對象"
},
"true": "是",
"false": "否",
@@ -342,7 +383,9 @@
"not-defined": "主題未設置",
"missing-config": "未設置服務端",
"invalid-topic": "主題無效",
- "nonclean-missingclientid": "使用者端ID未設定,使用新會話"
+ "nonclean-missingclientid": "使用者端ID未設定,使用新會話",
+ "invalid-json-string": "無效的JSON字符串",
+ "invalid-json-parse": "無法解析JSON字符串"
}
},
"httpin": {
@@ -354,12 +397,26 @@
"upload": "接受檔案上傳?",
"status": "狀態碼",
"headers": "Header",
- "other": "其他"
+ "other": "其他",
+ "paytoqs": "將msg.payload附加為查詢字符串參數",
+ "utf8String": "UTF8格式的字符串",
+ "binaryBuffer": "二進制buffer",
+ "jsonObject": "解析的JSON對象",
+ "authType": "類型",
+ "bearerToken": "Token"
},
"setby": "- 用 msg.method 設定 -",
"basicauth": "基本認證",
"use-tls": "使用安全連接 (SSL/TLS) ",
- "tls-config":"TLS 設置",
+ "tls-config": "TLS 設置",
+ "basic": "基本認證",
+ "digest": "摘要認證",
+ "bearer": "bearer認證",
+ "use-proxy": "使用代理服務器",
+ "persist": "對連接啟用keep-alive",
+ "proxy-config": "代理服務器設置",
+ "use-proxyauth": "使用代理身份驗證",
+ "noproxy-hosts": "代理例外",
"utf8": "UTF-8 字串",
"binary": "二進位資料",
"json": "JSON對象",
@@ -375,8 +432,11 @@
"no-response": "無響應物件",
"json-error": "JSON 解析錯誤",
"no-url": "未設定 URL",
- "deprecated-call":"__method__方法已棄用",
- "invalid-transport":"非HTTP傳輸請求"
+ "deprecated-call": "__method__方法已棄用",
+ "invalid-transport": "非HTTP傳輸請求",
+ "timeout-isnan": "超時值不是有效數字,忽略",
+ "timeout-isnegative": "超時值為負,忽略",
+ "invalid-payload": "無效的有效載荷"
},
"status": {
"requesting": "請求中"
@@ -399,13 +459,19 @@
"url1": "URL 應該使用ws://或者wss://方案並指向現有的websocket監聽器.",
"url2": "預設情況下,payload
將包含要發送或從Websocket接收的資料。可以將使用者端配置為以JSON格式的字串發送或接收整個消息物件."
},
+ "status": {
+ "connected": "連接數 __count__",
+ "connected_plural": "連接數 __count__"
+ },
"errors": {
"connect-error": "ws連接發生了錯誤: ",
"send-error": "發送時發生了錯誤: ",
- "missing-conf": "未設置伺服器"
+ "missing-conf": "未設置伺服器",
+ "duplicate-path": "同一路徑上不能有兩個WebSocket偵聽器: __path__"
}
},
"watch": {
+ "watch": "watch",
"label": {
"files": "文件",
"recursive": "遞迴所有子資料夾"
@@ -458,14 +524,12 @@
"connection-closed": "連接已關閉 __host__:__port__",
"connections": "__count__ 個連接",
"connections_plural": "__count__ 個連接"
-
},
"errors": {
"connection-lost": "連接中斷 __host__:__port__",
"timeout": "超時關閉通訊端連接,埠 __port__",
"cannot-listen": "無法監聽埠 __port__, 錯誤: __error__",
"error": "錯誤: __error__",
-
"socket-error": "通訊端連接錯誤來自 __host__:__port__",
"no-host": "主機位址或埠未設定",
"connect-timeout": "連接逾時",
@@ -480,14 +544,15 @@
"output": "輸出",
"group": "組",
"interface": "本地IP",
- "interfaceprompt": "(可選)本地 IP 綁定到",
"send": "發送一個",
"toport": "到埠",
"address": "地址",
- "decode-base64": "是否解碼Base64編碼的資訊?"
+ "decode-base64": "是否解碼Base64編碼的資訊?",
+ "interfaceprompt": "(可選)本地 IP 綁定到"
},
"placeholder": {
"interface": "(可選)eth0的IP地址",
+ "interfaceprompt": "(可選) 要綁定的本地接口或地址",
"address": "目標IP位址"
},
"udpmsgs": "udp信息",
@@ -529,36 +594,43 @@
"ip-notset": "udp: IP地址未設定",
"port-notset": "udp: 埠未設定",
"port-invalid": "udp: 無效埠號碼",
- "alreadyused": "udp: 埠已被佔用"
+ "alreadyused": "udp: 埠已被佔用",
+ "ifnotfound": "udp: 接口 __iface__ 未發現"
}
},
"switch": {
+ "switch": "switch",
"label": {
"property": "屬性",
"rule": "規則",
- "repair" : "重建資訊佇列"
+ "repair": "重建資訊佇列"
},
+ "previous": "先前值",
"and": "與",
"checkall": "全選所有規則",
"stopfirst": "接受第一條匹配資訊後停止",
"ignorecase": "忽略大小寫",
"rules": {
- "btwn":"在之間",
- "cont":"包含",
- "regex":"匹配規則運算式",
- "true":"為真",
- "false":"為假",
- "null":"為空",
- "nnull":"非空",
- "head":"head",
- "tail":"tail",
- "index":"index between",
- "exp":"JSONata運算式",
- "else":"除此以外"
+ "btwn": "在之間",
+ "cont": "包含",
+ "regex": "匹配規則運算式",
+ "true": "為真",
+ "false": "為假",
+ "null": "為空",
+ "nnull": "非空",
+ "istype": "類型是",
+ "empty": "為空",
+ "nempty": "非空",
+ "head": "head",
+ "tail": "tail",
+ "index": "index between",
+ "exp": "JSONata運算式",
+ "else": "除此以外",
+ "hask": "擁有鍵"
},
"errors": {
"invalid-expr": "無效的JSONata運算式: __error__",
- "too-many" : "Switch節點中有太多待定信息"
+ "too-many": "Switch節點中有太多待定信息"
}
},
"change": {
@@ -588,6 +660,7 @@
}
},
"range": {
+ "range": "range",
"label": {
"action": "操作",
"inputrange": "映射輸入資料",
@@ -623,7 +696,8 @@
"firstrow": "第一行包含列名",
"output": "輸出",
"includerow": "包含列名行",
- "newline": "分行符號"
+ "newline": "分行符號",
+ "usestrings": "解析數值"
},
"placeholder": {
"columns": "用逗號分割列名"
@@ -654,7 +728,8 @@
"html": {
"label": {
"select": "選取項",
- "output": "輸出"
+ "output": "輸出",
+ "in": "in"
},
"output": {
"html": "選定元素的html內容",
@@ -670,7 +745,9 @@
"errors": {
"dropped-object": "忽略非物件格式的有效負載",
"dropped": "忽略不支援格式的有效負載類型",
- "dropped-error": "轉換有效負載失敗"
+ "dropped-error": "轉換有效負載失敗",
+ "schema-error": "JSON架構錯誤",
+ "schema-error-compile": "JSON架構錯誤: 未能編譯架構"
},
"label": {
"o2j": "對象至JSON",
@@ -679,8 +756,8 @@
"property": "屬性",
"actions": {
"toggle": "JSON字串與物件互轉",
- "str":"總是轉為JSON字串",
- "obj":"總是轉為JS對象"
+ "str": "總是轉為JSON字串",
+ "obj": "總是轉為JS對象"
}
}
},
@@ -702,76 +779,6 @@
"xml_js": "此節點僅處理XML字串或JS物件."
}
},
- "rpi-gpio": {
- "label": {
- "gpiopin": "GPIO",
- "selectpin": "選擇引腳",
- "resistor": "電阻?",
- "readinitial": "在部署/重啟時讀取引腳的初始狀態?",
- "type": "類型",
- "initpin": "初始化引腳狀態?",
- "debounce": "去抖動",
- "freq": "頻率",
- "button": "按鈕",
- "pimouse": "Pi滑鼠",
- "pikeyboard": "Pi鍵盤",
- "left": "左",
- "right": "右",
- "middle": "中"
- },
- "resistor": {
- "none": "無",
- "pullup": "上拉電阻",
- "pulldown": "下拉電阻"
- },
- "digout": "數位輸出",
- "pwmout": "PWM輸出",
- "servo": "伺服輸出",
- "initpin0": "初始引腳電平 - 低(0)",
- "initpin1": "初始引腳電平 - 高(1)",
- "left": "左",
- "right": "右",
- "middle": "中",
- "any": "任何",
- "pinname": "引腳",
- "alreadyuse": "已被使用",
- "alreadyset": "已被設為",
- "tip": {
- "pin": "正在使用引腳 : ",
- "in": "提示: 僅接受數位輸入 - 輸出必須為0或1.",
- "dig": "提示: 如用數位輸出 - 輸入必須為0或1.",
- "pwm": "提示: 如用PWM輸出 - 輸入必須為0至100之間; 如用高頻率可能會比預期佔用更多CPU資源.",
- "ser": "提示 : 如用伺服輸出 - 輸入必須為0至100之間. 50為中間值."
- },
- "types": {
- "digout": "數位輸出",
- "input": "輸入",
- "pullup": "含有上拉電阻的輸入",
- "pulldown": "含有下拉電阻的輸入",
- "pwmout": "PWM輸出",
- "servo": "伺服輸出"
- },
- "status": {
- "stopped": "已停止",
- "closed": "已關閉",
- "not-running": "不運行"
- },
- "errors": {
- "ignorenode": "忽略樹莓派的特定節點",
- "version": "版本命令失敗",
- "sawpitype": "查看Pi類型",
- "libnotfound": "找不到樹莓派RPi.GPIO的python庫",
- "alreadyset": "GPIO引腳 __pin__ 已經被設定為類型: __type__",
- "invalidpin": "無效GPIO引腳",
- "invalidinput": "無效輸入",
- "needtobeexecutable": "__command__須為可運行命令",
- "mustbeexecutable": "nrgpio須為可運行",
- "commandnotfound": "nrgpio命令不存在",
- "commandnotexecutable": "nrgpio命令不可運行",
- "error": "錯誤: __error__",
- "pythoncommandnotfound": "nrpgio python命令未處於運行狀態"
- }
- },
"file": {
"label": {
"filename": "檔案名",
@@ -783,7 +790,10 @@
"breaklines": "分拆成行",
"filelabel": "文件",
"sendError": "發生錯誤時發送消息(傳統模式)",
- "deletelabel": "刪除 __file__"
+ "deletelabel": "刪除 __file__",
+ "encoding": "編碼",
+ "utf8String": "UTF8字符串",
+ "binaryBuffer": "二進制buffer"
},
"action": {
"append": "追加至文件",
@@ -801,6 +811,21 @@
"deletedfile": "刪除檔: __file__",
"appendedfile": "追加至文件: __file__"
},
+ "encoding": {
+ "none": "默認",
+ "native": "Native",
+ "unicode": "Unicode",
+ "japanese": "日本",
+ "chinese": "中國",
+ "korean": "韓國",
+ "taiwan": "臺灣/香港",
+ "windows": "Windows代碼頁",
+ "iso": "ISO代碼頁",
+ "ibm": "IBM代碼頁",
+ "mac": "Mac代碼頁",
+ "koi8": "KOI8代碼頁",
+ "misc": "其它"
+ },
"errors": {
"nofilename": "未指定檔案名",
"invaliddelete": "警告:無效刪除。請在配置對話方塊中使用特定的刪除選項",
@@ -812,50 +837,53 @@
"tip": "提示: 檔案名應該是絕對路徑,否則它將相對於Node-RED進程的工作目錄。"
},
"split": {
- "intro":"基於以下類型拆分msg.payload
:",
- "object":"對象 ",
- "objectSend":"每個鍵值對作為單個消息發送",
- "strBuff":"字串 / Buffer ",
- "array":"陣列 ",
- "splitUsing":"拆分使用",
- "splitLength":"固定長度",
- "stream":"作為消息流處理",
- "addname":" 複製鍵到 "
+ "split": "split",
+ "intro": "基於以下類型拆分msg.payload
:",
+ "object": "對象 ",
+ "objectSend": "每個鍵值對作為單個消息發送",
+ "strBuff": "字串 / Buffer ",
+ "array": "陣列 ",
+ "splitUsing": "拆分使用",
+ "splitLength": "固定長度",
+ "stream": "作為消息流處理",
+ "addname": " 複製鍵到 "
},
- "join":{
- "mode":{
- "mode":"模式",
- "auto":"自動",
- "merge":"合併序列",
- "reduce":"縮減序列",
- "custom":"手動"
+ "join": {
+ "join": "join",
+ "mode": {
+ "mode": "模式",
+ "auto": "自動",
+ "merge": "合併序列",
+ "reduce": "縮減序列",
+ "custom": "手動"
},
- "combine":"合併每個",
- "create":"輸出為",
- "type":{
- "string":"字串",
- "array":"陣列",
- "buffer":"Buffer",
- "object":"鍵值對對象",
- "merged":"合併對象"
+ "combine": "合併每個",
+ "completeMessage": "完整的消息",
+ "create": "輸出為",
+ "type": {
+ "string": "字串",
+ "array": "陣列",
+ "buffer": "Buffer",
+ "object": "鍵值對對象",
+ "merged": "合併對象"
},
- "using":"使用此值",
- "key":"作為鍵",
- "joinedUsing":"合併符號",
- "send":"發送資訊:",
- "afterCount":"達到一定數量的資訊時",
- "count":"數量",
- "subsequent":"和每個後續的消息",
- "afterTimeout":"第一條消息的若干時間後",
- "seconds":"秒",
- "complete":"在收到存在msg.complete
的消息後",
- "tip":"此模式假定此節點與split 相連, 或者接收到的消息有正確配置的msg.parts
屬性.",
- "too-many" : "join節點中有太多待定信息",
+ "using": "使用此值",
+ "key": "作為鍵",
+ "joinedUsing": "合併符號",
+ "send": "發送資訊:",
+ "afterCount": "達到一定數量的資訊時",
+ "count": "數量",
+ "subsequent": "和每個後續的消息",
+ "afterTimeout": "第一條消息的若幹時間後",
+ "seconds": "秒",
+ "complete": "在收到存在msg.complete
的消息後",
+ "tip": "此模式假定此節點與split 相連, 或者接收到的消息有正確配置的msg.parts
屬性.",
+ "too-many": "join節點中有太多待定信息",
"merge": {
- "topics-label":"合併主題",
- "topics":"主題",
- "topic" : "主題",
- "on-change":"當收到一個新主題時發送已合併資訊"
+ "topics-label": "合併主題",
+ "topics": "主題",
+ "topic": "主題",
+ "on-change": "當收到一個新主題時發送已合併資訊"
},
"reduce": {
"exp": "Reduce運算式",
@@ -868,43 +896,45 @@
"invalid-expr": "無效的JSONata運算式: __error__"
}
},
- "sort" : {
- "target" : "排序屬性",
- "seq" : "資訊佇列",
- "key" : "鍵值",
- "elem" : "元素值",
- "order" : "順序",
- "ascending" : "昇冪",
- "descending" : "降冪",
- "as-number" : "作為數值",
- "invalid-exp" : "sort節點中存在無效的JSONata運算式",
- "too-many" : "sort節點中有太多待定信息",
- "clear" : "清空sort節點中的待定資訊"
+ "sort": {
+ "sort": "排序",
+ "target": "排序屬性",
+ "seq": "資訊佇列",
+ "key": "鍵值",
+ "elem": "元素值",
+ "order": "順序",
+ "ascending": "昇冪",
+ "descending": "降冪",
+ "as-number": "作為數值",
+ "invalid-exp": "排序節點中存在無效的JSONata運算式",
+ "too-many": "排序節點中有太多待定信息",
+ "clear": "清空排序節點中的待定資訊"
},
- "batch" : {
+ "batch": {
+ "batch": "batch",
"mode": {
- "label" : "模式",
- "num-msgs" : "按指定數量分組",
- "interval" : "按時間間隔分組",
- "concat" : "按主題分組"
+ "label": "模式",
+ "num-msgs": "按指定數量分組",
+ "interval": "按時間間隔分組",
+ "concat": "按主題分組"
},
"count": {
- "label" : "分組數量",
- "overlap" : "隊末隊首重疊數量",
- "count" : "數量",
- "invalid" : "無效的分組數量或重疊數量"
+ "label": "分組數量",
+ "overlap": "隊末隊首重疊數量",
+ "count": "數量",
+ "invalid": "無效的分組數量或重疊數量"
},
"interval": {
- "label" : "時間間隔",
- "seconds" : "秒",
- "empty" : "無數據到達時發送空資訊"
+ "label": "時間間隔",
+ "seconds": "秒",
+ "empty": "無數據到達時發送空資訊"
},
"concat": {
"topics-label": "主題",
- "topic" : "主題"
+ "topic": "主題"
},
- "too-many" : "batch節點中有太多待定信息",
- "unexpected" : "未知模式",
- "no-parts" : "資訊中沒有parts屬性"
+ "too-many": "batch節點中有太多待定信息",
+ "unexpected": "未知模式",
+ "no-parts": "資訊中沒有parts屬性"
}
}
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/network/05-tls.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/05-tls.html
new file mode 100644
index 000000000..ee4b3bd95
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/05-tls.html
@@ -0,0 +1,19 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/network/06-httpproxy.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/06-httpproxy.html
new file mode 100644
index 000000000..23f899627
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/06-httpproxy.html
@@ -0,0 +1,22 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/network/10-mqtt.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/10-mqtt.html
new file mode 100644
index 000000000..825bf218e
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/10-mqtt.html
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httpin.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httpin.html
new file mode 100644
index 000000000..0d44ce3b1
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httpin.html
@@ -0,0 +1,81 @@
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httprequest.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httprequest.html
new file mode 100644
index 000000000..71ed96087
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/21-httprequest.html
@@ -0,0 +1,78 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/network/22-websocket.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/22-websocket.html
new file mode 100644
index 000000000..4bb2c7f4d
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/22-websocket.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/network/31-tcpin.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/31-tcpin.html
new file mode 100644
index 000000000..2898ca718
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/31-tcpin.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/network/32-udp.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/32-udp.html
new file mode 100644
index 000000000..401af48e3
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/network/32-udp.html
@@ -0,0 +1,28 @@
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-CSV.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-CSV.html
new file mode 100644
index 000000000..9a8638614
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-CSV.html
@@ -0,0 +1,43 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-HTML.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-HTML.html
new file mode 100644
index 000000000..b1559455f
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-HTML.html
@@ -0,0 +1,33 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-JSON.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-JSON.html
new file mode 100644
index 000000000..1a46c3690
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-JSON.html
@@ -0,0 +1,43 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-XML.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-XML.html
new file mode 100644
index 000000000..4f0491291
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-XML.html
@@ -0,0 +1,48 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-YAML.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-YAML.html
new file mode 100644
index 000000000..8ea4f87f8
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/parsers/70-YAML.html
@@ -0,0 +1,34 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/17-split.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/17-split.html
new file mode 100644
index 000000000..fd97b497a
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/17-split.html
@@ -0,0 +1,133 @@
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/18-sort.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/18-sort.html
new file mode 100644
index 000000000..cb8e7fa21
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/18-sort.html
@@ -0,0 +1,41 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/19-batch.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/19-batch.html
new file mode 100644
index 000000000..79879076e
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/sequence/19-batch.html
@@ -0,0 +1,34 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/10-file.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/10-file.html
new file mode 100644
index 000000000..03705ea5c
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/10-file.html
@@ -0,0 +1,59 @@
+
+
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/23-watch.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/23-watch.html
new file mode 100644
index 000000000..d8e1b5807
--- /dev/null
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/23-watch.html
@@ -0,0 +1,25 @@
+
+
+
diff --git a/packages/node_modules/@node-red/runtime/locales/zh-TW/runtime.json b/packages/node_modules/@node-red/runtime/locales/zh-TW/runtime.json
new file mode 100644
index 000000000..b96d87a6e
--- /dev/null
+++ b/packages/node_modules/@node-red/runtime/locales/zh-TW/runtime.json
@@ -0,0 +1,174 @@
+{
+ "runtime": {
+ "welcome": "歡迎使用Node-RED",
+ "version": "__component__ 版本: __version__",
+ "unsupported_version": "__component__的不受支持的版本。要求: __requires__ 找到: __version__",
+ "paths": {
+ "settings": "設置文件 : __path__",
+ "httpStatic": "HTTP Static : __path__"
+ }
+ },
+
+ "server": {
+ "loading": "加載控制板節點",
+ "palette-editor": {
+ "disabled": "控制板編輯器已禁用:用戶設置",
+ "npm-not-found": "控制板編輯器已禁用:找不到npm命令",
+ "npm-too-old": "控制板編輯器已禁用: npm版本太舊。需要版本npm >= 3.x"
+ },
+ "errors": "無法註冊__count__節點類型",
+ "errors_plural": "無法註冊__count__個節點類型",
+ "errors-help": "使用-v運行以獲取詳細信息",
+ "missing-modules": "缺少節點模組:",
+ "node-version-mismatch": "無法在此版本上加載節點模組。要求:__ version__",
+ "type-already-registered": "'__type__'已由模組__module__註冊",
+ "removing-modules": "從配置中刪除模組",
+ "added-types": "添加的節點類型:",
+ "removed-types": "刪除的節點類型:",
+ "install": {
+ "invalid": "無效的模組名稱",
+ "installing": "安裝模組:__ name__,版本:__ version__",
+ "installed": "已安裝的模組:__ name__",
+ "install-failed": "安裝失敗",
+ "install-failed-long": "模組__name__安裝失敗:",
+ "install-failed-not-found": "$t(server.install.install-failed-long) 模組未發現",
+ "upgrading": "更新模組: __name__ 至版本: __version__",
+ "upgraded": "更新模組: __name__。 重新啟動Node-RED以使用新版本",
+ "upgrade-failed-not-found": "$t(server.install.install-failed-long) 未發現版本",
+ "uninstalling": "卸載模組: __name__",
+ "uninstall-failed": "卸載失敗",
+ "uninstall-failed-long": "卸載模組__name__失敗:",
+ "uninstalled": "卸載模組: __name__"
+ },
+ "unable-to-listen": "無法在__listenpath__上收聽",
+ "port-in-use": "錯誤: 端口正在使用中",
+ "uncaught-exception": "未捕獲的異常:",
+ "admin-ui-disabled": "管理員界面已禁用",
+ "now-running": "服務器現在在__listenpath__上運行",
+ "failed-to-start": "無法啟動服務器:",
+ "headless-mode": "在headless模式下運行",
+ "httpadminauth-deprecated": "不建議使用httpAdminAuth。請改用adminAuth"
+ },
+
+ "api": {
+ "flows": {
+ "error-save": "保存流程錯誤: __message__",
+ "error-reload": "重載流程錯誤: __message__"
+ },
+ "library": {
+ "error-load-entry": "加載庫條目'__path__'時出錯:__message__",
+ "error-save-entry": "保存庫條目'__path__'時出錯:__ message__",
+ "error-load-flow": "加載流程'__path__'時出錯:__ message__",
+ "error-save-flow": "保存流'__path__'時出錯:__ message__"
+ },
+ "nodes": {
+ "enabled": "啟用的節點類型:",
+ "disabled": "禁用的節點類型:",
+ "error-enable": "無法啟用節點:"
+ }
+ },
+
+ "comms": {
+ "error": "通訊渠道錯誤:__ message__",
+ "error-server": "通信服務器錯誤:__ message__",
+ "error-send": "通訊發送錯誤:__ message__"
+ },
+
+ "settings": {
+ "user-not-available": "無法保存用戶設置:__ message__",
+ "not-available": "設置不可用",
+ "property-read-only": "屬性“ __prop__”是只讀的"
+ },
+
+ "nodes": {
+ "credentials": {
+ "error":"加載證書時出錯:__ message__",
+ "error-saving":"保存證書時出錯:__ message__",
+ "not-registered": "證書類型'__type__'未註冊",
+ "system-key-warning": "\n\n---------------------------------------------------------------------\n您的流程證書文件是使用系統生成的密鑰加密的。\n\n如果系統生成的密鑰由於任何原因丟失,則您的證書文件將無法恢復,您將必須刪除它並重新輸入您的證書。\n\n您應該使用您的設置文件中的'credentialSecret'選項設置自己的密鑰。然後,下次部署更改時,Node-RED將使用選擇的密鑰重新加密您的證書文件。\n---------------------------------------------------------------------\n"
+ },
+ "flows": {
+ "safe-mode": "流程在安全模式下停止。部署開始。",
+ "registered-missing": "缺少註冊的類型:__ type__",
+ "error": "錯誤加載流程:__ message__",
+ "starting-modified-nodes": "啟動修改的節點",
+ "starting-modified-flows": "啟動修改的流程",
+ "starting-flows": "啟動流程",
+ "started-modified-nodes": "修改的節點已啟動",
+ "started-modified-flows": "修改的流程已啟動",
+ "started-flows": "流程已啟動",
+ "stopping-modified-nodes": "停止修改的節點",
+ "stopping-modified-flows": "停止修改的流程",
+ "stopping-flows": "停止流程",
+ "stopped-modified-nodes": "修改的節點已停止",
+ "stopped-modified-flows": "修改的流程已停止",
+ "stopped-flows": "流程已停止",
+ "stopped": "已停止",
+ "stopping-error": "錯誤停止節點:__ message__",
+ "added-flow": "流程已添加: __label__",
+ "updated-flow": "流程已更新: __label__",
+ "removed-flow": "流程已移除: __label__",
+ "missing-types": "等待缺少的類型被註冊:",
+ "missing-type-provided": " - __type__ (由npm模組__module__提供)",
+ "missing-type-install-1": "要安裝所有缺少的模組,請運行:",
+ "missing-type-install-2": "在目錄中:"
+ },
+ "flow": {
+ "unknown-type": "未知類型: __type__",
+ "missing-types": "缺少類型",
+ "error-loop": "郵件已超過最大捕獲數"
+ },
+ "index": {
+ "unrecognised-id": "無法識別的ID: __id__",
+ "type-in-use": "使用中的類型: __msg__",
+ "unrecognised-module": "無法識別的模組: __module__"
+ },
+ "registry": {
+ "localfilesystem": {
+ "module-not-found": "找不到模組:'__module__'"
+ }
+ }
+ },
+
+ "storage": {
+ "index": {
+ "forbidden-flow-name": "禁止流程名稱"
+ },
+ "localfilesystem": {
+ "user-dir": "用戶目錄: __path__",
+ "flows-file": "流程文件: __path__",
+ "create": "創建新__type__文件",
+ "empty": "現有__type__文件為空",
+ "invalid": "現有__type__文件為無效json",
+ "restore": "恢復__type__文件備份:__path__",
+ "restore-fail": "恢復__type__文件備份失敗:__ message__",
+ "fsync-fail": "將文件__path__刷新到磁盤失敗:__message__",
+ "projects": {
+ "changing-project": "設置活動項目:__ project__",
+ "active-project": "活動項目:__ project__",
+ "project-not-found": "找不到項目:__ project__",
+ "no-active-project": "沒有活動的項目:使用默認流文件",
+ "disabled": "項目已禁用:editorTheme.projects.enabled = false",
+ "disabledNoFlag": "項目已禁用:設置editorTheme.projects.enabled = true來啟用",
+ "git-not-found": "項目已禁用:找不到git命令",
+ "git-version-old": "項目已禁用:不支持的git __version__。 需要的git版本為2.x",
+ "summary": "一個Node-RED項目",
+ "readme": "### 關於\n\n這是您項目的README.md文件。它可以幫助用戶了解您的項目,如何使用它以及他們可能需要知道的其他任何信息。"
+ }
+ }
+ },
+
+ "context": {
+ "log-store-init": "上下文儲存: '__name__' [__info__]",
+ "error-loading-module": "加載上下文存儲時出錯: __message__",
+ "error-loading-module2": "加載上下文存儲時出錯 '__module__': __message__",
+ "error-module-not-defined": "上下文存儲庫'__storage__'缺少“模組”選項",
+ "error-invalid-module-name": "無效的上下文存儲名稱:'__ name__'",
+ "error-invalid-default-module": "無效的默認的上下文存儲庫: '__storage__'",
+ "unknown-store": "指定了未知的上下文存儲庫'__name__'。 使用默認存儲庫。",
+ "localfilesystem": {
+ "error-circular": "上下文__scope__包含無法保留的循環引用",
+ "error-write": "編寫上下文時出錯:__ message__"
+ }
+ }
+}
From 634a51635c5138dd61322369d23a7649d95e02a3 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 10 Feb 2020 18:55:03 +0000
Subject: [PATCH 03/67] Battling Chrome Autocomplete, part 31: Wrap search
input with form
---
.../@node-red/editor-client/src/js/ui/common/searchBox.js | 5 ++++-
.../@node-red/editor-client/src/js/ui/keyboard.js | 4 ++--
.../src/js/ui/projects/projectUserSettings.js | 8 ++++----
.../editor-client/src/sass/ui/common/searchBox.scss | 3 +++
4 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/searchBox.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/searchBox.js
index 214668485..b707ccbf5 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/searchBox.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/searchBox.js
@@ -38,7 +38,10 @@
this.element.addClass("red-ui-searchBox-input");
this.uiContainer = this.element.wrap("").parent();
this.uiContainer.addClass("red-ui-searchBox-container");
-
+ if (this.element.parents("form").length === 0) {
+ var form = this.element.wrap("
';
- RED.sidebar.info.set(aboutHeader+marked(data));
+ RED.sidebar.info.set(aboutHeader+RED.utils.renderMarkdown(data));
RED.sidebar.info.show();
});
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/expression.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/expression.js
index c8a93964d..9a9765c35 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/expression.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/expression.js
@@ -102,7 +102,7 @@
var f = $(this).val();
var args = RED._('jsonata:'+f+".args",{defaultValue:''});
var title = ""+f+"("+args+") ";
- var body = marked(RED._('jsonata:'+f+'.desc',{defaultValue:''}));
+ var body = RED.utils.renderMarkdown(RED._('jsonata:'+f+'.desc',{defaultValue:''}));
$("#red-ui-editor-type-expression-help").html(title+""+body+"
");
})
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/markdown.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/markdown.js
index 97957eadf..f89c8f3a7 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/markdown.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/markdown.js
@@ -107,7 +107,7 @@
clearTimeout(changeTimer);
changeTimer = setTimeout(function() {
var currentScrollTop = $(".red-ui-editor-type-markdown-panel-preview").scrollTop();
- $(".red-ui-editor-type-markdown-panel-preview").html(marked(expressionEditor.getValue()));
+ $(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
$(".red-ui-editor-type-markdown-panel-preview").scrollTop(currentScrollTop);
},200);
})
@@ -116,7 +116,7 @@
}
if (value) {
- $(".red-ui-editor-type-markdown-panel-preview").html(marked(expressionEditor.getValue()));
+ $(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
}
panels = RED.panels.create({
id:"red-ui-editor-type-markdown-panels",
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js
index 967a61f51..b70854bfa 100755
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js
@@ -269,7 +269,7 @@ RED.palette = (function() {
RED.view.focus();
var helpText;
if (nt.indexOf("subflow:") === 0) {
- helpText = marked(RED.nodes.subflow(nt.substring(8)).info||"")||(''+RED._("sidebar.info.none")+' ');
+ helpText = RED.utils.renderMarkdown(RED.nodes.subflow(nt.substring(8)).info||"")||(''+RED._("sidebar.info.none")+' ');
} else {
helpText = $("script[data-help-name='"+d.attr("data-palette-type")+"']").html()||(''+RED._("sidebar.info.none")+' ');
}
@@ -370,7 +370,7 @@ RED.palette = (function() {
RED.workspaces.show(nt.substring(8));
e.preventDefault();
});
- nodeInfo = marked(def.info||"");
+ nodeInfo = RED.utils.renderMarkdown(def.info||"");
}
setLabel(nt,d,label,nodeInfo);
@@ -440,7 +440,7 @@ RED.palette = (function() {
} else if (portOutput.length !== 0 && sf.out.length === 0) {
portOutput.remove();
}
- setLabel(sf.type+":"+sf.id,paletteNode,sf.name,marked(sf.info||""));
+ setLabel(sf.type+":"+sf.id,paletteNode,sf.name,RED.utils.renderMarkdown(sf.info||""));
setIcon(paletteNode,sf);
var currentCategory = paletteNode.data('category');
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js b/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js
index 2d377ba54..f0944c879 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js
@@ -158,7 +158,7 @@ RED.projects.settings = (function() {
container.empty();
var desc;
if (activeProject.description) {
- desc = marked(activeProject.description);
+ desc = RED.utils.renderMarkdown(activeProject.description);
} else {
desc = '' + RED._("sidebar.project.noDescriptionAvailable") + ' ';
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js
index b8e3b150b..bfa4e4b23 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js
@@ -15,17 +15,6 @@
**/
RED.sidebar.info = (function() {
- marked.setOptions({
- renderer: new marked.Renderer(),
- gfm: true,
- tables: true,
- breaks: false,
- pedantic: false,
- sanitize: true,
- smartLists: true,
- smartypants: false
- });
-
var content;
var sections;
var propertiesSection;
@@ -314,7 +303,7 @@ RED.sidebar.info = (function() {
if (subflowNode && node.type !== "subflow") {
// Selected a subflow instance node.
// - The subflow template info goes into help
- helpText = (marked(subflowNode.info||"")||(''+RED._("sidebar.info.none")+' '));
+ helpText = (RED.utils.renderMarkdown(subflowNode.info||"")||(''+RED._("sidebar.info.none")+' '));
} else {
helpText = $("script[data-help-name='"+node.type+"']").html()||(''+RED._("sidebar.info.none")+' ');
}
@@ -326,10 +315,10 @@ RED.sidebar.info = (function() {
if (node._def && node._def.info) {
var info = node._def.info;
var textInfo = (typeof info === "function" ? info.call(node) : info);
- infoText = infoText + marked(textInfo);
+ infoText = infoText + RED.utils.renderMarkdown(textInfo);
}
if (node.info) {
- infoText = infoText + marked(node.info || "")
+ infoText = infoText + RED.utils.renderMarkdown(node.info || "")
}
setInfoText(infoText, infoSection.content);
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 d35d1f1ba..a9c1c9500 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
@@ -16,6 +16,28 @@
RED.utils = (function() {
+ window._marked = window.marked;
+ window.marked = function(txt) {
+ console.warn("Use of 'marked()' is deprecated. Use RED.utils.renderMarkdown() instead");
+ return renderMarkdown(txt);
+ }
+
+ _marked.setOptions({
+ renderer: new _marked.Renderer(),
+ gfm: true,
+ tables: true,
+ breaks: false,
+ pedantic: false,
+ smartLists: true,
+ smartypants: false
+ });
+
+ function renderMarkdown(txt) {
+ var rendered = _marked(txt);
+ var cleaned = DOMPurify.sanitize(rendered, {SAFE_FOR_JQUERY: true})
+ return cleaned;
+ }
+
function formatString(str) {
return str.replace(/\r?\n/g,"↵").replace(/\t/g,"→");
}
@@ -1053,6 +1075,7 @@ RED.utils = (function() {
decodeObject: decodeObject,
parseContextKey: parseContextKey,
createIconElement: createIconElement,
- sanitize: sanitize
+ sanitize: sanitize,
+ renderMarkdown: renderMarkdown
}
})();
diff --git a/packages/node_modules/@node-red/editor-client/src/vendor/marked/marked.min.js b/packages/node_modules/@node-red/editor-client/src/vendor/marked/marked.min.js
deleted file mode 100644
index 555c1dc1d..000000000
--- a/packages/node_modules/@node-red/editor-client/src/vendor/marked/marked.min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * marked - a markdown parser
- * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
- * https://github.com/chjj/marked
- */
-(function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+block.def.source+")")();block.blockquote=replace(block.blockquote)("def",block.def)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b";block.html=replace(block.html)("comment",//)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1","\\2")+"|"+block.list.source.replace("\\1","\\3")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm){if(this.options.tables){this.rules=block.tables}else{this.rules=block.gfm}}}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)};Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top,bq){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1){this.tokens.push({type:"space"})}}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm,"");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]||""});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i ?/gm,"");this.token(cap,top,true);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length);bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i1&&b.length>1)){src=cap.slice(i+1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item.charAt(item.length-1)==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false,bq);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:!this.options.sanitizer&&(cap[1]==="pre"||cap[1]==="script"||cap[1]==="style"),text:cap[0]});continue}if(!bq&&top&&(cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal;this.renderer=this.options.renderer||new Renderer;this.renderer.options=this.options;if(!this.links){throw new Error("Tokens array requires a `links` property.")}if(this.options.gfm){if(this.options.breaks){this.rules=inline.breaks}else{this.rules=inline.gfm}}else if(this.options.pedantic){this.rules=inline.pedantic}}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length);out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1].charAt(6)===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+=this.renderer.link(href,null,text);continue}if(!this.inLink&&(cap=this.rules.url.exec(src))){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+=this.renderer.link(href,null,text);continue}if(cap=this.rules.tag.exec(src)){if(!this.inLink&&/^/i.test(cap[0])){this.inLink=false}src=src.substring(cap[0].length);out+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(cap[0]):escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);this.inLink=true;out+=this.outputLink(cap,{href:cap[2],title:cap[3]});this.inLink=false;continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0].charAt(0);src=cap[0].substring(1)+src;continue}this.inLink=true;out+=this.outputLink(cap,link);this.inLink=false;continue}if(cap=this.rules.strong.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.strong(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.em(this.output(cap[2]||cap[1]));continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.codespan(escape(cap[2],true));continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.br();continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.del(this.output(cap[1]));continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=this.renderer.text(escape(this.smartypants(cap[0])));continue}if(src){throw new Error("Infinite loop on byte: "+src.charCodeAt(0))}}return out};InlineLexer.prototype.outputLink=function(cap,link){var href=escape(link.href),title=link.title?escape(link.title):null;return cap[0].charAt(0)!=="!"?this.renderer.link(href,title,this.output(cap[1])):this.renderer.image(href,title,escape(cap[1]))};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…")};InlineLexer.prototype.mangle=function(text){if(!this.options.mangle)return text;var out="",l=text.length,i=0,ch;for(;i.5){ch="x"+ch.toString(16)}out+=""+ch+";"}return out};function Renderer(options){this.options=options||{}}Renderer.prototype.code=function(code,lang,escaped){if(this.options.highlight){var out=this.options.highlight(code,lang);if(out!=null&&out!==code){escaped=true;code=out}}if(!lang){return""+(escaped?code:escape(code,true))+"\n
"}return''+(escaped?code:escape(code,true))+"\n
\n"};Renderer.prototype.blockquote=function(quote){return"\n"+quote+" \n"};Renderer.prototype.html=function(html){return html};Renderer.prototype.heading=function(text,level,raw){return"\n"};Renderer.prototype.hr=function(){return this.options.xhtml?" \n":" \n"};Renderer.prototype.list=function(body,ordered){var type=ordered?"ol":"ul";return"<"+type+">\n"+body+""+type+">\n"};Renderer.prototype.listitem=function(text){return""+text+" \n"};Renderer.prototype.paragraph=function(text){return""+text+"
\n"};Renderer.prototype.table=function(header,body){return"\n"+"\n"+header+" \n"+"\n"+body+" \n"+"
\n"};Renderer.prototype.tablerow=function(content){return"\n"+content+" \n"};Renderer.prototype.tablecell=function(content,flags){var type=flags.header?"th":"td";var tag=flags.align?"<"+type+' style="text-align:'+flags.align+'">':"<"+type+">";return tag+content+""+type+">\n"};Renderer.prototype.strong=function(text){return""+text+" "};Renderer.prototype.em=function(text){return""+text+" "};Renderer.prototype.codespan=function(text){return""+text+"
"};Renderer.prototype.br=function(){return this.options.xhtml?" ":" "};Renderer.prototype.del=function(text){return""+text+""};Renderer.prototype.link=function(href,title,text){if(this.options.sanitize){try{var prot=decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase()}catch(e){return""}if(prot.indexOf("javascript:")===0||prot.indexOf("vbscript:")===0){return""}}var out='"+text+" ";return out};Renderer.prototype.image=function(href,title,text){var out=' ":">";return out};Renderer.prototype.text=function(text){return text};function Parser(options){this.tokens=[];this.token=null;this.options=options||marked.defaults;this.options.renderer=this.options.renderer||new Renderer;this.renderer=this.options.renderer;this.renderer.options=this.options}Parser.parse=function(src,options,renderer){var parser=new Parser(options,renderer);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options,this.renderer);this.tokens=src.reverse();var out="";while(this.next()){out+=this.tok()}return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text;while(this.peek().type==="text"){body+="\n"+this.next().text}return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case"space":{return""}case"hr":{return this.renderer.hr()}case"heading":{return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text)}case"code":{return this.renderer.code(this.token.text,this.token.lang,this.token.escaped)}case"table":{var header="",body="",i,row,cell,flags,j;cell="";for(i=0;i /g,">").replace(/"/g,""").replace(/'/g,"'")}function unescape(html){return html.replace(/&([#\w]+);/g,function(_,n){n=n.toLowerCase();if(n==="colon")return":";if(n.charAt(0)==="#"){return n.charAt(1)==="x"?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1))}return""})}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i=1,target,key;for(;iAn error occured:
"+escape(e.message+"",true)+" "}throw e}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,sanitizer:null,mangle:true,smartLists:false,silent:false,highlight:null,langPrefix:"lang-",smartypants:false,headerPrefix:"",renderer:new Renderer,xhtml:false};marked.Parser=Parser;marked.parser=Parser.parse;marked.Renderer=Renderer;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output;marked.parse=marked;if(typeof module!=="undefined"&&typeof exports==="object"){module.exports=marked}else if(typeof define==="function"&&define.amd){define(function(){return marked})}else{this.marked=marked}}).call(function(){return this||(typeof window!=="undefined"?window:global)}());
\ No newline at end of file
From 40c3099e4e4f4eafa5e1f5ccedcd8608726d2d23 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 24 Feb 2020 11:41:27 +0000
Subject: [PATCH 15/67] Avoid adding extra newlines when formating jsonata
Fixes #2472
---
.../@node-red/editor-client/src/vendor/jsonata/formatter.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js b/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js
index 382537be3..9fbab4fbf 100644
--- a/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js
+++ b/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js
@@ -59,8 +59,8 @@
stack.pop();
}
}
-
}
+
// console.log(stack);
var result = str;
var indent = 0;
@@ -83,7 +83,7 @@
pre = result.substring(0,offset+f.pos+1);
post = result.substring(offset+f.pos+1);
indented = indentLine(post,indent);
- result = pre+"\n"+indented;
+ result = pre+(/\n$/.test(pre)?"":"\n")+indented;
offset += indented.length-post.length+1;
} else {
longStack.push(false);
@@ -94,7 +94,7 @@
pre = result.substring(0,offset+f.pos);
post = result.substring(offset+f.pos);
indented = indentLine(post,indent);
- result = pre+"\n"+indented;
+ result = pre+(/\n$/.test(pre)?"":"\n")+indented;
offset += indented.length-post.length+1;
}
longStack.pop();
From 04d398192190db914869a52a278386e14de2f551 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 24 Feb 2020 11:42:56 +0000
Subject: [PATCH 16/67] Bump to jsonata 1.8.1
---
package.json | 2 +-
packages/node_modules/@node-red/util/package.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index 3db93d8c6..a410aa12f 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,7 @@
"is-utf8": "0.2.1",
"js-yaml": "3.13.1",
"json-stringify-safe": "5.0.1",
- "jsonata": "1.8.0",
+ "jsonata": "1.8.1",
"media-typer": "1.1.0",
"memorystore": "1.6.1",
"mime": "2.4.4",
diff --git a/packages/node_modules/@node-red/util/package.json b/packages/node_modules/@node-red/util/package.json
index 411c35a7c..9ad86f6c9 100644
--- a/packages/node_modules/@node-red/util/package.json
+++ b/packages/node_modules/@node-red/util/package.json
@@ -18,7 +18,7 @@
"clone": "2.1.2",
"i18next": "15.1.2",
"json-stringify-safe": "5.0.1",
- "jsonata": "1.8.0",
+ "jsonata": "1.8.1",
"when": "3.7.8"
}
}
From e16fe1e6a514572854fcc776892fe06716c1a061 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 24 Feb 2020 13:27:42 +0000
Subject: [PATCH 17/67] Add better regex highlighting in jsonata edit mode
Fixes #2465
---
.../src/vendor/jsonata/mode-jsonata.js | 82 ++++++++++++-------
1 file changed, 52 insertions(+), 30 deletions(-)
diff --git a/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/mode-jsonata.js b/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/mode-jsonata.js
index 2a90e4ce7..48358517e 100644
--- a/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/mode-jsonata.js
+++ b/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/mode-jsonata.js
@@ -28,6 +28,11 @@ ace.define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/m
}, "identifier");
this.$rules = {
"start" : [
+ {
+ token: "string.regexp",
+ regex: "\\/",
+ next: "regex"
+ },
{
token : "string",
regex : "'(?=.)",
@@ -46,34 +51,35 @@ ace.define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/m
token : "constant.numeric", // float
regex : /[+-]?\d[\d_]*(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/
},
- { token: "keyword",
- regex: /λ/
- },
- {
- token: "keyword",
- regex: jsonataFunctions
- },
- {
- token : keywordMapper,
- regex : "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*"
- },
- {
- token : "punctuation.operator",
- regex : /[.](?![.])/
- },
- {
- token : "keyword.operator",
- regex : /\|\||<=|>=|\.\.|\*\*|!=|:=|[=<>`!$%&*+\-~\/^]/,
- next : "start"
- },
- {
- token : "punctuation.operator",
- regex : /[?:,;.]/,
- next : "start"
- },
- {
- token : "paren.lparen",
- regex : /[\[({]/,
+ {
+ token: "keyword",
+ regex: /λ/
+ },
+ {
+ token: "keyword",
+ regex: jsonataFunctions
+ },
+ {
+ token : keywordMapper,
+ regex : "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*"
+ },
+ {
+ token : "punctuation.operator",
+ regex : /[.](?![.])/
+ },
+ {
+ token : "keyword.operator",
+ regex : /\|\||<=|>=|\.\.|\*\*|!=|:=|[=<>`!$%&*+\-~\/^]/,
+ next : "start"
+ },
+ {
+ token : "punctuation.operator",
+ regex : /[?:,;.]/,
+ next : "start"
+ },
+ {
+ token : "paren.lparen",
+ regex : /[\[({]/,
next : "start"
},
{
@@ -86,7 +92,8 @@ ace.define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/m
token : "string",
regex : '"|$',
next : "start"
- }, {
+ },
+ {
defaultToken: "string"
}
],
@@ -95,9 +102,24 @@ ace.define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/m
token : "string",
regex : "'|$",
next : "start"
- }, {
+ },
+ {
defaultToken: "string"
}
+ ],
+ "regex" : [
+ {
+ token: "string.regexp",
+ regex: "\\\\/"
+ },
+ {
+ token: "string.regexp",
+ regex: "/[sxngimy]*",
+ next: "start"
+ },
+ {
+ defaultToken: "string.regexp"
+ }
]
};
};
From 79feb691bdf0f8ff55d82304153858cfdd6fee40 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 24 Feb 2020 16:08:58 +0000
Subject: [PATCH 18/67] Add regex awareness to jsonata formatter
---
.../src/vendor/jsonata/formatter.js | 79 +++++++++++++++----
1 file changed, 62 insertions(+), 17 deletions(-)
diff --git a/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js b/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js
index 9fbab4fbf..49a02c206 100644
--- a/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js
+++ b/packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js
@@ -11,6 +11,7 @@
var length = str.length;
var start = 0;
var inString = false;
+ var inRegex = false;
var inBox = false;
var quoteChar;
var list = [];
@@ -24,8 +25,13 @@
}
for (var i=0;i 70) {
+ post = result.substring(offset+f.pos+1);
+ if (!/^\n/.test(post)) {
+ indented = indentLine(post,indent);
+ hasNewline = /\n$/.test(pre);
+ result = pre+(hasNewline?"":"\n")+indented;
+ offset += indented.length-post.length+(hasNewline?0:1);
+ }
+ }
+
} else if (f.type === "open-block") {
- if (f.width > 30) {
+ if (f.width > 40) {
longStack.push(true);
indent += 4;
pre = result.substring(0,offset+f.pos+1);
post = result.substring(offset+f.pos+1);
+ hasNewline = /\n$/.test(pre);
indented = indentLine(post,indent);
- result = pre+(/\n$/.test(pre)?"":"\n")+indented;
- offset += indented.length-post.length+1;
+ result = pre+(hasNewline?"":"\n")+indented;
+ offset += indented.length-post.length+(hasNewline?0:1);
} else {
longStack.push(false);
}
} else if (f.type === "close-block") {
- if (f.width > 30) {
+ if (f.width > 40) {
indent -= 4;
pre = result.substring(0,offset+f.pos);
post = result.substring(offset+f.pos);
indented = indentLine(post,indent);
- result = pre+(/\n$/.test(pre)?"":"\n")+indented;
- offset += indented.length-post.length+1;
+ hasNewline = /\n *$/.test(pre);
+ if (hasNewline) {
+ result = pre + post;
+ } else {
+ result = pre+"\n"+indented;
+ offset += indented.length-post.length+1;
+ }
}
longStack.pop();
}
From 22de8855c19da76049eeab8f38090509ced40dce Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 24 Feb 2020 21:08:29 +0000
Subject: [PATCH 19/67] Handle httpAdminRoot missing ending slash with login
strategy Fixes #2473
---
packages/node_modules/@node-red/editor-api/lib/auth/index.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/packages/node_modules/@node-red/editor-api/lib/auth/index.js b/packages/node_modules/@node-red/editor-api/lib/auth/index.js
index a7ee2e7f3..189f903d8 100644
--- a/packages/node_modules/@node-red/editor-api/lib/auth/index.js
+++ b/packages/node_modules/@node-red/editor-api/lib/auth/index.js
@@ -100,7 +100,10 @@ function login(req,res) {
}
} else if (mergedAdminAuth.type === "strategy") {
- var urlPrefix = (settings.httpAdminRoot==='/')?"":settings.httpAdminRoot;
+ var urlPrefix = (settings.httpAdminRoot||"").replace(/\/$/,"");
+ if (urlPrefix.length > 0) {
+ urlPrefix += "/";
+ }
response = {
"type":"strategy",
"prompts":[{type:"button",label:mergedAdminAuth.strategy.label, url: urlPrefix + "auth/strategy"}]
From 01a143cd5af295b39cd93347edafab10221bbae9 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Mon, 24 Feb 2020 21:28:40 +0000
Subject: [PATCH 20/67] Emsure trigger complete 2nd msg when set to send latest
and add test
to close #2474
---
.../@node-red/nodes/core/function/89-trigger.js | 10 +++++-----
test/nodes/core/function/89-trigger_spec.js | 8 +++++---
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/function/89-trigger.js b/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
index 48a595ccc..a068550e2 100644
--- a/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
+++ b/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
@@ -106,7 +106,9 @@ module.exports = function(RED) {
});
}
+ var npay;
this.on('input', function(msg) {
+ if (node.op2type === "payl") { npay = RED.util.cloneMessage(msg); }
processMessageQueue(msg);
});
@@ -124,7 +126,7 @@ module.exports = function(RED) {
else {
if (((!node.topics[topic].tout) && (node.topics[topic].tout !== 0)) || (node.loop === true)) {
promise = Promise.resolve();
- if (node.op2type === "pay" || node.op2type === "payl") { node.topics[topic].m2 = RED.util.cloneMessage(msg.payload); }
+ if (node.op2type === "pay") { node.topics[topic].m2 = RED.util.cloneMessage(msg.payload); }
else if (node.op2Templated) { node.topics[topic].m2 = mustache.render(node.op2,msg); }
else if (node.op2type !== "nul") {
promise = new Promise((resolve,reject) => {
@@ -188,7 +190,8 @@ module.exports = function(RED) {
promise.then(() => {
msg2.payload = node.topics[topic].m2;
delete node.topics[topic];
- node.send(msg2);
+ if (node.op2type === "payl") { node.send(npay); }
+ else { node.send(msg2); }
node.status({});
}).catch(err => {
node.error(err);
@@ -244,9 +247,6 @@ module.exports = function(RED) {
});
}, node.duration);
}
- else {
- if (node.op2type === "payl") { node.topics[topic].m2 = RED.util.cloneMessage(msg.payload); }
- }
}
return Promise.resolve();
}
diff --git a/test/nodes/core/function/89-trigger_spec.js b/test/nodes/core/function/89-trigger_spec.js
index 5f7bfc2d1..be0094ccf 100644
--- a/test/nodes/core/function/89-trigger_spec.js
+++ b/test/nodes/core/function/89-trigger_spec.js
@@ -736,10 +736,12 @@ describe('trigger node', function() {
try {
if (c === 0) {
msg.should.have.a.property("payload", "Goodbye");
+ msg.should.have.a.property("topic", "test2");
c += 1;
}
else {
msg.should.have.a.property("payload", "World");
+ msg.should.have.a.property("topic", "test3");
(Date.now() - ss).should.be.greaterThan(70);
done();
}
@@ -747,12 +749,12 @@ describe('trigger node', function() {
catch(err) { done(err); }
});
var ss = Date.now();
- n1.emit("input", {payload:"Hello"});
+ n1.emit("input", {payload:"Hello", topic:"test1"});
setTimeout( function() {
- n1.emit("input", {payload:"Goodbye"});
+ n1.emit("input", {payload:"Goodbye", topic:"test2"});
},20);
setTimeout( function() {
- n1.emit("input", {payload:"World"});
+ n1.emit("input", {payload:"World", topic:"test3"});
},80);
});
});
From 1fd4b2b9fc817bb4c14c0d6bacc3c5c3a67e5181 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Mon, 24 Feb 2020 21:31:01 +0000
Subject: [PATCH 21/67] join node - check existance before clearing timeout
---
packages/node_modules/@node-red/nodes/core/sequence/17-split.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/node_modules/@node-red/nodes/core/sequence/17-split.js b/packages/node_modules/@node-red/nodes/core/sequence/17-split.js
index 5d93c8faf..0492a0dc2 100644
--- a/packages/node_modules/@node-red/nodes/core/sequence/17-split.js
+++ b/packages/node_modules/@node-red/nodes/core/sequence/17-split.js
@@ -429,7 +429,7 @@ module.exports = function(RED) {
var completeSend = function(partId) {
var group = inflight[partId];
- clearTimeout(group.timeout);
+ if (group.timeout) { clearTimeout(group.timeout); }
if ((node.accumulate !== true) || group.msg.hasOwnProperty("complete")) { delete inflight[partId]; }
if (group.type === 'array' && group.arrayLen > 1) {
var newArray = [];
From 608834eafbee4c3b48f60748d99ca1bc5e3e3e06 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 24 Feb 2020 21:49:58 +0000
Subject: [PATCH 22/67] Ensure IPv6 broker names are wrapped in brackets Fixes
#2462
---
.../node_modules/@node-red/nodes/core/network/10-mqtt.js | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js
index 6f682b279..3f5b2dff4 100644
--- a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js
+++ b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js
@@ -153,7 +153,12 @@ module.exports = function(RED) {
this.brokerurl="mqtt://";
}
if (this.broker !== "") {
- this.brokerurl = this.brokerurl+this.broker+":";
+ //Check for an IPv6 address
+ if (/(?:^|(?<=\s))(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(?=\s|$)/.test(this.broker)) {
+ this.brokerurl = this.brokerurl+"["+this.broker+"]:";
+ } else {
+ this.brokerurl = this.brokerurl+this.broker+":";
+ }
// port now defaults to 1883 if unset.
if (!this.port){
this.brokerurl = this.brokerurl+"1883";
From 5ecf8c83db90f9022ec02c2b64aa26200bdcac4e Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Tue, 25 Feb 2020 18:46:02 +0900
Subject: [PATCH 23/67] Support to input JSON path in debug node property
---
test/editor/pageobjects/nodes/core/common/21-debug_page.js | 2 ++
test/editor/specs/scenario/cookbook_httprequests_uispec.js | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/test/editor/pageobjects/nodes/core/common/21-debug_page.js b/test/editor/pageobjects/nodes/core/common/21-debug_page.js
index 602d4d542..56854b195 100644
--- a/test/editor/pageobjects/nodes/core/common/21-debug_page.js
+++ b/test/editor/pageobjects/nodes/core/common/21-debug_page.js
@@ -33,6 +33,8 @@ debugNode.prototype.setOutput = function (complete) {
// Select the "msg" type.
browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options")][1]/a[1]');
// Input the path in msg.
+ browser.clickWithWait('//*[contains(@class, "red-ui-typedInput-input")]/input');
+ browser.keys(Array('payload'.length).fill('Backspace'));
browser.setValue('//*[contains(@class, "red-ui-typedInput-input")]/input', complete);
} else {
// Select the "complete msg object" type.
diff --git a/test/editor/specs/scenario/cookbook_httprequests_uispec.js b/test/editor/specs/scenario/cookbook_httprequests_uispec.js
index 785451429..797b06041 100644
--- a/test/editor/specs/scenario/cookbook_httprequests_uispec.js
+++ b/test/editor/specs/scenario/cookbook_httprequests_uispec.js
@@ -190,7 +190,7 @@ describe('cookbook', function () {
httpRequestNode.clickOk();
debugNode.edit();
- debugNode.setOutput('.title');
+ debugNode.setOutput('payload.title');
debugNode.clickOk();
injectNode.connect(changeNodeSetPost);
From f7d2314d64eb0af5fa0db9f9af942da462531fb5 Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Tue, 25 Feb 2020 19:01:17 +0900
Subject: [PATCH 24/67] Add page object code for split node and remove
duplicated code
---
.../editor/pageobjects/nodes/core/sequence/17-split_page.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/test/editor/pageobjects/nodes/core/sequence/17-split_page.js b/test/editor/pageobjects/nodes/core/sequence/17-split_page.js
index 6029e4d90..3c8c70aa5 100644
--- a/test/editor/pageobjects/nodes/core/sequence/17-split_page.js
+++ b/test/editor/pageobjects/nodes/core/sequence/17-split_page.js
@@ -18,13 +18,13 @@ var util = require('util');
var nodePage = require('../../node_page');
-function joinNode(id) {
+function splitNode(id) {
nodePage.call(this, id);
}
-util.inherits(joinNode, nodePage);
+util.inherits(splitNode, nodePage);
-module.exports = joinNode;
+module.exports = splitNode;
function joinNode(id) {
nodePage.call(this, id);
From 21c57f968a0f92e696dbc532a6669995645e24b6 Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Tue, 25 Feb 2020 19:02:46 +0900
Subject: [PATCH 25/67] Add page object code for nodes
---
.../editor/pageobjects/editor/palette_page.js | 8 +++-
.../nodes/core/common/24-complete_page.js | 47 ++++++++++++++++++
.../nodes/core/common/25-catch_page.js | 48 +++++++++++++++++++
.../nodes/core/common/25-status_page.js | 48 +++++++++++++++++++
.../nodes/core/common/90-comment_page.js | 27 +++++++++++
.../nodes/core/function/89-delay_page.js | 33 +++++++++++++
.../nodes/core/sequence/19-batch_page.js | 39 +++++++++++++++
.../pageobjects/nodes/nodefactory_page.js | 12 +++++
8 files changed, 261 insertions(+), 1 deletion(-)
create mode 100644 test/editor/pageobjects/nodes/core/common/24-complete_page.js
create mode 100644 test/editor/pageobjects/nodes/core/common/25-catch_page.js
create mode 100644 test/editor/pageobjects/nodes/core/common/25-status_page.js
create mode 100644 test/editor/pageobjects/nodes/core/common/90-comment_page.js
create mode 100644 test/editor/pageobjects/nodes/core/function/89-delay_page.js
create mode 100644 test/editor/pageobjects/nodes/core/sequence/19-batch_page.js
diff --git a/test/editor/pageobjects/editor/palette_page.js b/test/editor/pageobjects/editor/palette_page.js
index 97077059b..6af0b5271 100644
--- a/test/editor/pageobjects/editor/palette_page.js
+++ b/test/editor/pageobjects/editor/palette_page.js
@@ -18,11 +18,16 @@ var idMap = {
// common
"inject": ".red-ui-palette-node[data-palette-type='inject']",
"debug": ".red-ui-palette-node[data-palette-type='debug']",
+ "complete": ".red-ui-palette-node[data-palette-type='complete']",
+ "catch": ".red-ui-palette-node[data-palette-type='catch']",
+ "status": ".red-ui-palette-node[data-palette-type='status']",
+ "comment": ".red-ui-palette-node[data-palette-type='comment']",
// function
"function": ".red-ui-palette-node[data-palette-type='function']",
"change": ".red-ui-palette-node[data-palette-type='change']",
"range": ".red-ui-palette-node[data-palette-type='range']",
"template": ".red-ui-palette-node[data-palette-type='template']",
+ "delay": ".red-ui-palette-node[data-palette-type='delay']",
// network
"mqttIn": ".red-ui-palette-node[data-palette-type='mqtt in']",
"mqttOut": ".red-ui-palette-node[data-palette-type='mqtt out']",
@@ -30,8 +35,9 @@ var idMap = {
"httpResponse": ".red-ui-palette-node[data-palette-type='http response']",
"httpRequest": ".red-ui-palette-node[data-palette-type='http request']",
// sequence
- "join": ".red-ui-palette-node[data-palette-type='join']",
"split": ".red-ui-palette-node[data-palette-type='split']",
+ "join": ".red-ui-palette-node[data-palette-type='join']",
+ "batch": ".red-ui-palette-node[data-palette-type='batch']",
// parser
"csv": ".red-ui-palette-node[data-palette-type='csv']",
"html": ".red-ui-palette-node[data-palette-type='html']",
diff --git a/test/editor/pageobjects/nodes/core/common/24-complete_page.js b/test/editor/pageobjects/nodes/core/common/24-complete_page.js
new file mode 100644
index 000000000..558ee709a
--- /dev/null
+++ b/test/editor/pageobjects/nodes/core/common/24-complete_page.js
@@ -0,0 +1,47 @@
+/**
+ * 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 nodePage = require('../../node_page');
+
+function completeNode(id) {
+ nodePage.call(this, id);
+}
+
+util.inherits(completeNode, nodePage);
+
+completeNode.prototype.setScope = function (scope) {
+ if (scope) {
+ browser.clickWithWait('//*[@id="node-input-complete-target-select"]');
+ browser.pause(1000);
+ if (Array.isArray(scope)) {
+ for (var i = 0; i < scope.length; i++) {
+ browser.moveToObject(scope[i].id);
+ browser.buttonDown();
+ browser.buttonUp();
+ }
+ } else {
+ browser.moveToObject(scope.id);
+ browser.buttonDown();
+ browser.buttonUp();
+ }
+ browser.clickWithWait('//*[contains(@class, "red-ui-notification")]/div/button[2]');
+ browser.pause(1000);
+ }
+}
+
+module.exports = completeNode;
diff --git a/test/editor/pageobjects/nodes/core/common/25-catch_page.js b/test/editor/pageobjects/nodes/core/common/25-catch_page.js
new file mode 100644
index 000000000..89bcb7f1e
--- /dev/null
+++ b/test/editor/pageobjects/nodes/core/common/25-catch_page.js
@@ -0,0 +1,48 @@
+/**
+ * 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 nodePage = require('../../node_page');
+
+function catchNode(id) {
+ nodePage.call(this, id);
+}
+
+util.inherits(catchNode, nodePage);
+
+catchNode.prototype.setScope = function (scope) {
+ if (scope) {
+ browser.selectWithWait('#node-input-scope-select', 'target');
+ browser.clickWithWait('//*[@id="node-input-catch-target-select"]');
+ browser.pause(1000);
+ if (Array.isArray(scope)) {
+ for (var i = 0; i < scope.length; i++) {
+ browser.moveToObject(scope[i].id);
+ browser.buttonDown();
+ browser.buttonUp();
+ }
+ } else {
+ browser.moveToObject(scope.id);
+ browser.buttonDown();
+ browser.buttonUp();
+ }
+ browser.clickWithWait('//*[contains(@class, "red-ui-notification")]/div/button[2]');
+ browser.pause(1000);
+ }
+}
+
+module.exports = catchNode;
diff --git a/test/editor/pageobjects/nodes/core/common/25-status_page.js b/test/editor/pageobjects/nodes/core/common/25-status_page.js
new file mode 100644
index 000000000..6de0fcde7
--- /dev/null
+++ b/test/editor/pageobjects/nodes/core/common/25-status_page.js
@@ -0,0 +1,48 @@
+/**
+ * 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 nodePage = require('../../node_page');
+
+function statusNode(id) {
+ nodePage.call(this, id);
+}
+
+util.inherits(statusNode, nodePage);
+
+statusNode.prototype.setScope = function (scope) {
+ if (scope) {
+ browser.selectWithWait('#node-input-scope-select', 'target');
+ browser.clickWithWait('//*[@id="node-input-status-target-select"]');
+ browser.pause(1000);
+ if (Array.isArray(scope)) {
+ for (var i = 0; i < scope.length; i++) {
+ browser.moveToObject(scope[i].id);
+ browser.buttonDown();
+ browser.buttonUp();
+ }
+ } else {
+ browser.moveToObject(scope.id);
+ browser.buttonDown();
+ browser.buttonUp();
+ }
+ browser.clickWithWait('//*[contains(@class, "red-ui-notification")]/div/button[2]');
+ browser.pause(1000);
+ }
+}
+
+module.exports = statusNode;
diff --git a/test/editor/pageobjects/nodes/core/common/90-comment_page.js b/test/editor/pageobjects/nodes/core/common/90-comment_page.js
new file mode 100644
index 000000000..2687dacfe
--- /dev/null
+++ b/test/editor/pageobjects/nodes/core/common/90-comment_page.js
@@ -0,0 +1,27 @@
+/**
+ * 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 nodePage = require('../../node_page');
+
+function commentNode(id) {
+ nodePage.call(this, id);
+}
+
+util.inherits(commentNode, nodePage);
+
+module.exports = commentNode;
diff --git a/test/editor/pageobjects/nodes/core/function/89-delay_page.js b/test/editor/pageobjects/nodes/core/function/89-delay_page.js
new file mode 100644
index 000000000..a4e2197e4
--- /dev/null
+++ b/test/editor/pageobjects/nodes/core/function/89-delay_page.js
@@ -0,0 +1,33 @@
+/**
+ * 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 nodePage = require("../../node_page");
+
+var keyPage = require("../../../util/key_page");
+
+function delayNode(id) {
+ nodePage.call(this, id);
+}
+
+util.inherits(delayNode, nodePage);
+
+delayNode.prototype.setTimeout = function (timeout) {
+ browser.setValue('//*[@id="node-input-timeout"]', timeout);
+}
+
+module.exports = delayNode;
diff --git a/test/editor/pageobjects/nodes/core/sequence/19-batch_page.js b/test/editor/pageobjects/nodes/core/sequence/19-batch_page.js
new file mode 100644
index 000000000..0d7b13028
--- /dev/null
+++ b/test/editor/pageobjects/nodes/core/sequence/19-batch_page.js
@@ -0,0 +1,39 @@
+/**
+ * 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 nodePage = require('../../node_page');
+
+function batchNode(id) {
+ nodePage.call(this, id);
+}
+
+batchNode.prototype.setMode = function (mode) {
+ browser.selectWithWait('#node-input-mode', mode);
+}
+
+batchNode.prototype.setCount = function (count) {
+ browser.setValue('#node-input-count', count);
+}
+
+batchNode.prototype.setOverlap = function (overlap) {
+ browser.setValue('#node-input-overlap', overlap);
+}
+
+util.inherits(batchNode, nodePage);
+
+module.exports = batchNode;
diff --git a/test/editor/pageobjects/nodes/nodefactory_page.js b/test/editor/pageobjects/nodes/nodefactory_page.js
index 33193e112..17949e313 100644
--- a/test/editor/pageobjects/nodes/nodefactory_page.js
+++ b/test/editor/pageobjects/nodes/nodefactory_page.js
@@ -16,10 +16,15 @@
var injectNode = require('./core/common/20-inject_page');
var debugNode = require('./core/common/21-debug_page');
+var completeNode = require('./core/common/24-complete_page');
+var catchNode = require('./core/common/25-catch_page');
+var statusNode = require('./core/common/25-status_page');
+var commentNode = require('./core/common/90-comment_page');
var functionNode = require('./core/function/10-function_page');
var changeNode = require('./core/function/15-change_page');
var rangeNode = require('./core/function/16-range_page');
var templateNode = require('./core/function/80-template_page');
+var delayNode = require('./core/function/89-delay_page');
var mqttInNode = require('./core/network/10-mqttin_page');
var mqttOutNode = require('./core/network/10-mqttout_page');
var httpInNode = require('./core/network/21-httpin_page');
@@ -27,6 +32,7 @@ var httpResponseNode = require('./core/network/21-httpresponse_page');
var httpRequestNode = require('./core/network/21-httprequest_page');
var splitNode = require('./core/sequence/17-split_page');
var joinNode = require('./core/sequence/17-split_page');
+var batchNode = require('./core/sequence/19-batch_page');
var csvNode = require('./core/parsers/70-CSV_page');
var htmlNode = require('./core/parsers/70-HTML_page');
var jsonNode = require('./core/parsers/70-JSON_page');
@@ -38,11 +44,16 @@ var nodeCatalog = {
// common
"inject": injectNode,
"debug": debugNode,
+ "complete": completeNode,
+ "catch": catchNode,
+ "status": statusNode,
+ "comment": commentNode,
// function
"function": functionNode,
"change": changeNode,
"range": rangeNode,
"template": templateNode,
+ "delay": delayNode,
// network
"mqttIn": mqttInNode,
"mqttOut": mqttOutNode,
@@ -52,6 +63,7 @@ var nodeCatalog = {
// sequence
"split": splitNode,
"join": joinNode,
+ "batch": batchNode,
// parser
"csv": csvNode,
"html": htmlNode,
From 00477fd67a159faf3fb26cefea503fbd483a2b6a Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Tue, 25 Feb 2020 19:56:48 +0900
Subject: [PATCH 26/67] Add UI test case for error handling
---
.../scenario/cookbook_errorhandling_uispec.js | 74 +++++++++++++++++++
1 file changed, 74 insertions(+)
create mode 100644 test/editor/specs/scenario/cookbook_errorhandling_uispec.js
diff --git a/test/editor/specs/scenario/cookbook_errorhandling_uispec.js b/test/editor/specs/scenario/cookbook_errorhandling_uispec.js
new file mode 100644
index 000000000..5285c5c0f
--- /dev/null
+++ b/test/editor/specs/scenario/cookbook_errorhandling_uispec.js
@@ -0,0 +1,74 @@
+/**
+ * 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 when = require('when');
+var should = require('should');
+var fs = require('fs-extra');
+
+var helper = require('../../editor_helper');
+var debugTab = require('../../pageobjects/editor/debugTab_page');
+var workspace = require('../../pageobjects/editor/workspace_page');
+var specUtil = require('../../pageobjects/util/spec_util_page');
+
+var httpNodeRoot = '/api';
+
+// https://cookbook.nodered.org/
+describe('cookbook', function () {
+ beforeEach(function () {
+ workspace.init();
+ });
+
+ before(function () {
+ helper.startServer();
+ });
+
+ after(function () {
+ helper.stopServer();
+ });
+
+ describe('messages', function () {
+ it('trigger a flow when a node throws an error', function () {
+ var injectNode = workspace.addNode('inject');
+ var functionNode = workspace.addNode('function');
+ var catchNode = workspace.addNode('catch', 0 , 80);
+ var debugNode = workspace.addNode('debug');
+
+ functionNode.edit();
+ functionNode.setFunction('node.error("an example error", msg);');
+ functionNode.clickOk();
+
+ catchNode.edit();
+ catchNode.setScope(functionNode);
+ catchNode.clickOk();
+
+ debugNode.edit();
+ debugNode.setOutput('error');
+ debugNode.clickOk();
+
+ injectNode.connect(functionNode);
+ catchNode.connect(debugNode);
+
+ workspace.deploy();
+
+ debugTab.open();
+ injectNode.clickLeftButton();
+ debugTab.getMessage().should.eql(['"an example error"', 'function']);
+ });
+
+ // skip this case since the flow outputs random results.
+ it.skip('automatically retry an action after an error');
+ });
+});
From 1868289b7127e372be9b2eb72e61240e89be2b53 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Tue, 25 Feb 2020 22:15:53 +0000
Subject: [PATCH 27/67] Better fix for trigegr 2nd message in last payload mode
Now works correctly in multiple topics mode.
And update tests
---
.../nodes/core/function/89-trigger.js | 15 +++++---
test/nodes/core/function/89-trigger_spec.js | 35 +++++++++++++++++++
2 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/function/89-trigger.js b/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
index a068550e2..4debeacde 100644
--- a/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
+++ b/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
@@ -76,6 +76,7 @@ module.exports = function(RED) {
var node = this;
node.topics = {};
+ var npay = {};
var pendingMessages = [];
var activeMessagePromise = null;
var processMessageQueue = function(msg) {
@@ -106,9 +107,7 @@ module.exports = function(RED) {
});
}
- var npay;
this.on('input', function(msg) {
- if (node.op2type === "payl") { npay = RED.util.cloneMessage(msg); }
processMessageQueue(msg);
});
@@ -124,6 +123,7 @@ module.exports = function(RED) {
node.status({});
}
else {
+ if (node.op2type === "payl") { npay[topic] = RED.util.cloneMessage(msg); }
if (((!node.topics[topic].tout) && (node.topics[topic].tout !== 0)) || (node.loop === true)) {
promise = Promise.resolve();
if (node.op2type === "pay") { node.topics[topic].m2 = RED.util.cloneMessage(msg.payload); }
@@ -188,10 +188,15 @@ module.exports = function(RED) {
});
}
promise.then(() => {
- msg2.payload = node.topics[topic].m2;
+ if (node.op2type === "payl") {
+ node.send(npay[topic]);
+ delete npay[topic];
+ }
+ else {
+ msg2.payload = node.topics[topic].m2;
+ node.send(msg2);
+ }
delete node.topics[topic];
- if (node.op2type === "payl") { node.send(npay); }
- else { node.send(msg2); }
node.status({});
}).catch(err => {
node.error(err);
diff --git a/test/nodes/core/function/89-trigger_spec.js b/test/nodes/core/function/89-trigger_spec.js
index be0094ccf..7d7450580 100644
--- a/test/nodes/core/function/89-trigger_spec.js
+++ b/test/nodes/core/function/89-trigger_spec.js
@@ -759,6 +759,41 @@ describe('trigger node', function() {
});
});
+ it('should be able output the 2nd payload and handle multiple topics', function(done) {
+ var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", extend:"false", op1type:"nul", op2type:"payl", op1:"false", op2:"true", duration:"80", bytopic:"topic", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(triggerNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ var c = 0;
+ n2.on("input", function(msg) {
+ try {
+ if (c === 0) {
+ msg.should.have.a.property("payload", "Goodbye1");
+ msg.should.have.a.property("topic", "test1");
+ c += 1;
+ }
+ else {
+ msg.should.have.a.property("payload", "Goodbye2");
+ msg.should.have.a.property("topic", "test2");
+ done();
+ }
+ }
+ catch(err) { done(err); }
+ });
+ n1.emit("input", {payload:"Hello1", topic:"test1"});
+ setTimeout( function() {
+ n1.emit("input", {payload:"Hello2", topic:"test2"});
+ },20);
+ setTimeout( function() {
+ n1.emit("input", {payload:"Goodbye2", topic:"test2"});
+ },20);
+ setTimeout( function() {
+ n1.emit("input", {payload:"Goodbye1", topic:"test1"});
+ },20);
+ });
+ });
+
it('should be able to apply mustache templates to payloads', function(done) {
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"val", op1:"{{payload}}", op2:"{{topic}}", duration:"50", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
From 43970b404eef80bdf08bcd4a05e14011a5738702 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Tue, 25 Feb 2020 23:05:59 +0000
Subject: [PATCH 28/67] Update github templates
---
.github/ISSUE_TEMPLATE/--bug_report.md | 2 +-
.github/PULL_REQUEST_TEMPLATE.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/ISSUE_TEMPLATE/--bug_report.md b/.github/ISSUE_TEMPLATE/--bug_report.md
index 63923455e..7cdc9caad 100644
--- a/.github/ISSUE_TEMPLATE/--bug_report.md
+++ b/.github/ISSUE_TEMPLATE/--bug_report.md
@@ -1,6 +1,6 @@
---
name: Bug report
-about: Reproducable software issues in the core of Node-RED
+about: Reproducible software issues in the core of Node-RED
title: ''
labels: ''
assignees: ''
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 05fdacd51..92a0abb8a 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -29,6 +29,6 @@ the [forum](https://discourse.nodered.org) or
- [ ] I have read the [contribution guidelines](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md)
-- [ ] For non-bugfix PRs, I have discussed this change on the mailing list/slack team.
+- [ ] For non-bugfix PRs, I have discussed this change on the forum/slack team.
- [ ] I have run `grunt` to verify the unit tests pass
- [ ] I have added suitable unit tests to cover the new/changed functionality
From bba6855872b915eab70ffc3226418bc83b8b5d0d Mon Sep 17 00:00:00 2001
From: KAZUHIRO ITO
Date: Wed, 26 Feb 2020 12:59:40 +0900
Subject: [PATCH 29/67] Add admin api authentication function
---
.../@node-red/editor-api/lib/auth/index.js | 3 +-
.../editor-api/lib/auth/strategies.js | 24 ++++++++++-
.../@node-red/editor-api/lib/auth/users.js | 14 +++++-
.../editor-api/lib/auth/strategies_spec.js | 32 ++++++++++++++
.../editor-api/lib/auth/users_spec.js | 43 +++++++++++++++++++
5 files changed, 112 insertions(+), 4 deletions(-)
diff --git a/packages/node_modules/@node-red/editor-api/lib/auth/index.js b/packages/node_modules/@node-red/editor-api/lib/auth/index.js
index a7ee2e7f3..c3948cd27 100644
--- a/packages/node_modules/@node-red/editor-api/lib/auth/index.js
+++ b/packages/node_modules/@node-red/editor-api/lib/auth/index.js
@@ -36,6 +36,7 @@ var log = require("@node-red/util").log; // TODO: separate module
passport.use(strategies.bearerStrategy.BearerStrategy);
passport.use(strategies.clientPasswordStrategy.ClientPasswordStrategy);
passport.use(strategies.anonymousStrategy);
+passport.use(strategies.tokensStrategy);
var server = oauth2orize.createServer();
@@ -60,7 +61,7 @@ function init(_settings,storage) {
function needsPermission(permission) {
return function(req,res,next) {
if (settings && settings.adminAuth) {
- return passport.authenticate(['bearer','anon'],{ session: false })(req,res,function() {
+ return passport.authenticate(['bearer','anon','tokens'],{ session: false })(req,res,function() {
if (!req.user) {
return next();
}
diff --git a/packages/node_modules/@node-red/editor-api/lib/auth/strategies.js b/packages/node_modules/@node-red/editor-api/lib/auth/strategies.js
index b17bf1473..9705ddd28 100644
--- a/packages/node_modules/@node-red/editor-api/lib/auth/strategies.js
+++ b/packages/node_modules/@node-red/editor-api/lib/auth/strategies.js
@@ -123,9 +123,31 @@ AnonymousStrategy.prototype.authenticate = function(req) {
});
}
+function TokensStrategy() {
+ passport.Strategy.call(this);
+ this.name = 'tokens';
+}
+util.inherits(TokensStrategy, passport.Strategy);
+TokensStrategy.prototype.authenticate = function(req) {
+ var self = this;
+ var token = req.headers[Users.tokenHeader()];
+ if (token) {
+ Users.tokens(token).then(function(admin) {
+ if (admin) {
+ self.success(admin,{scope:admin.permissions});
+ } else {
+ self.fail(401);
+ }
+ });
+ } else {
+ self.fail(401);
+ }
+}
+
module.exports = {
bearerStrategy: bearerStrategy,
clientPasswordStrategy: clientPasswordStrategy,
passwordTokenExchange: passwordTokenExchange,
- anonymousStrategy: new AnonymousStrategy()
+ anonymousStrategy: new AnonymousStrategy(),
+ tokensStrategy: new TokensStrategy()
}
diff --git a/packages/node_modules/@node-red/editor-api/lib/auth/users.js b/packages/node_modules/@node-red/editor-api/lib/auth/users.js
index 24a762958..f032332db 100644
--- a/packages/node_modules/@node-red/editor-api/lib/auth/users.js
+++ b/packages/node_modules/@node-red/editor-api/lib/auth/users.js
@@ -59,7 +59,9 @@ function getDefaultUser() {
var api = {
get: get,
authenticate: authenticate,
- default: getDefaultUser
+ default: getDefaultUser,
+ tokens: getDefaultUser,
+ tokenHeader: "authorization"
}
function init(config) {
@@ -105,6 +107,12 @@ function init(config) {
} else {
api.default = getDefaultUser;
}
+ if (config.tokens && typeof config.tokens === "function") {
+ api.tokens = config.tokens;
+ if (config.tokenHeader && typeof config.tokenHeader === "string") {
+ api.tokenHeader = config.tokenHeader.toLowerCase();
+ }
+ }
}
function cleanUser(user) {
if (user && user.hasOwnProperty('password')) {
@@ -118,5 +126,7 @@ module.exports = {
init: init,
get: function(username) { return api.get(username).then(cleanUser)},
authenticate: function() { return api.authenticate.apply(null, arguments) },
- default: function() { return api.default(); }
+ default: function() { return api.default(); },
+ tokens: function(token) { return api.tokens(token); },
+ tokenHeader: function() { return api.tokenHeader }
};
diff --git a/test/unit/@node-red/editor-api/lib/auth/strategies_spec.js b/test/unit/@node-red/editor-api/lib/auth/strategies_spec.js
index d30f6198a..13573f22a 100644
--- a/test/unit/@node-red/editor-api/lib/auth/strategies_spec.js
+++ b/test/unit/@node-red/editor-api/lib/auth/strategies_spec.js
@@ -129,6 +129,38 @@ describe("api/auth/strategies", function() {
})
});
+ describe("Tokens Strategy", function() {
+ it('Succeeds if tokens user enabled',function(done) {
+ var userDefault = sinon.stub(Users,"tokens",function(token) {
+ return when.resolve("tokens-"+token);
+ });
+ strategies.tokensStrategy._success = strategies.tokensStrategy.success;
+ strategies.tokensStrategy.success = function(user) {
+ user.should.equal("tokens-1234");
+ strategies.tokensStrategy.success = strategies.tokensStrategy._success;
+ delete strategies.tokensStrategy._success;
+ done();
+ };
+ strategies.tokensStrategy.authenticate({headers:{"authorization":"1234"}});
+ });
+ it('Fails if tokens user not enabled',function(done) {
+ var userDefault = sinon.stub(Users,"tokens",function() {
+ return when.resolve(null);
+ });
+ strategies.tokensStrategy._fail = strategies.tokensStrategy.fail;
+ strategies.tokensStrategy.fail = function(err) {
+ err.should.equal(401);
+ strategies.tokensStrategy.fail = strategies.tokensStrategy._fail;
+ delete strategies.tokensStrategy._fail;
+ done();
+ };
+ strategies.tokensStrategy.authenticate({headers:{"authorization":"1234"}});
+ });
+ afterEach(function() {
+ Users.tokens.restore();
+ })
+ });
+
describe("Bearer Strategy", function() {
it('Rejects invalid token',function(done) {
var getToken = sinon.stub(Tokens,"get",function(token) {
diff --git a/test/unit/@node-red/editor-api/lib/auth/users_spec.js b/test/unit/@node-red/editor-api/lib/auth/users_spec.js
index 515d23034..228163684 100644
--- a/test/unit/@node-red/editor-api/lib/auth/users_spec.js
+++ b/test/unit/@node-red/editor-api/lib/auth/users_spec.js
@@ -227,4 +227,47 @@ describe("api/auth/users", function() {
});
});
});
+
+ describe('Initialised with tokens set as function',function() {
+ before(function() {
+ Users.init({
+ type:"strategy",
+ tokens: function(token) { return("Done-"+token); }
+ });
+ });
+ after(function() {
+ Users.init({});
+ });
+ describe('#tokens',function() {
+ it('handles api.tokens being a function',function(done) {
+ Users.should.have.property('tokens').which.is.a.Function();
+ (Users.tokens("1234")).should.equal("Done-1234");
+ (Users.tokenHeader()).should.equal("authorization");
+ done();
+ });
+ });
+ });
+
+ describe('Initialised with tokens set as function and tokenHeader set as token header name',function() {
+ before(function() {
+ Users.init({
+ type:"strategy",
+ tokens: function(token) { return("Done-"+token); },
+ tokenHeader: "X-TEST-TOKEN"
+ });
+ });
+ after(function() {
+ Users.init({});
+ });
+ describe('#tokens',function() {
+ it('handles api.tokens being a function and api.tokenHeader being a header name',function(done) {
+ Users.should.have.property('tokens').which.is.a.Function();
+ (Users.tokens("1234")).should.equal("Done-1234");
+ Users.should.have.property('tokenHeader').which.is.a.Function();
+ (Users.tokenHeader()).should.equal("x-test-token");
+ done();
+ });
+ });
+ });
+
});
From d09ee6611f5aceeb2e7fbee1f150af7b368a7c42 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Wed, 26 Feb 2020 11:37:37 +0000
Subject: [PATCH 30/67] Update dependencies
---
package.json | 18 +++++++++---------
.../@node-red/editor-api/package.json | 6 +++---
.../node_modules/@node-red/nodes/package.json | 10 +++++-----
.../@node-red/registry/package.json | 2 +-
4 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/package.json b/package.json
index a5c4816f4..335dddbb3 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,7 @@
}
],
"dependencies": {
- "ajv": "6.10.2",
+ "ajv": "6.12.0",
"basic-auth": "2.0.1",
"bcryptjs": "2.4.3",
"body-parser": "1.19.0",
@@ -34,7 +34,7 @@
"cookie": "0.4.0",
"cookie-parser": "1.4.4",
"cors": "2.8.5",
- "cron": "1.7.2",
+ "cron": "1.8.2",
"denque": "1.4.1",
"express": "4.17.1",
"express-session": "1.17.0",
@@ -43,33 +43,33 @@
"hash-sum": "2.0.0",
"https-proxy-agent": "5.0.0",
"i18next": "15.1.2",
- "iconv-lite": "0.5.0",
+ "iconv-lite": "0.5.1",
"is-utf8": "0.2.1",
"js-yaml": "3.13.1",
"json-stringify-safe": "5.0.1",
"jsonata": "1.8.1",
"media-typer": "1.1.0",
- "memorystore": "1.6.1",
+ "memorystore": "1.6.2",
"mime": "2.4.4",
"mqtt": "2.18.8",
"multer": "1.4.2",
- "mustache": "3.0.2",
+ "mustache": "4.0.0",
"node-red-node-rbe": "^0.2.6",
"node-red-node-sentiment": "^0.1.6",
"node-red-node-tail": "^0.1.0",
"nopt": "4.0.1",
"oauth2orize": "1.11.0",
"on-headers": "1.0.2",
- "passport": "0.4.0",
+ "passport": "0.4.1",
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
"raw-body": "2.4.1",
"request": "2.88.0",
"semver": "6.3.0",
- "uglify-js": "3.6.9",
+ "uglify-js": "3.8.0",
"when": "3.7.8",
"ws": "6.2.1",
- "xml2js": "0.4.22"
+ "xml2js": "0.4.23"
},
"optionalDependencies": {
"bcrypt": "3.0.6"
@@ -104,7 +104,7 @@
"mocha": "^5.2.0",
"mosca": "^2.8.3",
"node-red-node-test-helper": "^0.2.3",
- "node-sass": "^4.13.0",
+ "node-sass": "^4.13.1",
"should": "^8.4.0",
"sinon": "1.17.7",
"stoppable": "^1.1.0",
diff --git a/packages/node_modules/@node-red/editor-api/package.json b/packages/node_modules/@node-red/editor-api/package.json
index 824f4df5b..81be91b6d 100644
--- a/packages/node_modules/@node-red/editor-api/package.json
+++ b/packages/node_modules/@node-red/editor-api/package.json
@@ -24,13 +24,13 @@
"cors": "2.8.5",
"express-session": "1.17.0",
"express": "4.17.1",
- "memorystore": "1.6.1",
+ "memorystore": "1.6.2",
"mime": "2.4.4",
- "mustache": "3.0.2",
+ "mustache": "4.0.0",
"oauth2orize": "1.11.0",
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
- "passport": "0.4.0",
+ "passport": "0.4.1",
"when": "3.7.8",
"ws": "6.2.1"
},
diff --git a/packages/node_modules/@node-red/nodes/package.json b/packages/node_modules/@node-red/nodes/package.json
index ca4e26626..1b707b95b 100644
--- a/packages/node_modules/@node-red/nodes/package.json
+++ b/packages/node_modules/@node-red/nodes/package.json
@@ -15,14 +15,14 @@
}
],
"dependencies": {
- "ajv": "6.10.2",
+ "ajv": "6.12.0",
"body-parser": "1.19.0",
"cheerio": "0.22.0",
"content-type": "1.0.4",
"cookie-parser": "1.4.4",
"cookie": "0.4.0",
"cors": "2.8.5",
- "cron": "1.7.2",
+ "cron": "1.8.2",
"denque": "1.4.1",
"fs-extra": "8.1.0",
"fs.notify": "0.0.4",
@@ -33,12 +33,12 @@
"media-typer": "1.1.0",
"mqtt": "2.18.8",
"multer": "1.4.2",
- "mustache": "3.0.2",
+ "mustache": "4.0.0",
"on-headers": "1.0.2",
"raw-body": "2.4.1",
"request": "2.88.0",
"ws": "6.2.1",
- "xml2js": "0.4.22",
- "iconv-lite": "0.5.0"
+ "xml2js": "0.4.23",
+ "iconv-lite": "0.5.1"
}
}
diff --git a/packages/node_modules/@node-red/registry/package.json b/packages/node_modules/@node-red/registry/package.json
index fefb24360..c1ee06050 100644
--- a/packages/node_modules/@node-red/registry/package.json
+++ b/packages/node_modules/@node-red/registry/package.json
@@ -18,7 +18,7 @@
"dependencies": {
"@node-red/util": "1.0.3",
"semver": "6.3.0",
- "uglify-js": "3.6.9",
+ "uglify-js": "3.8.0",
"when": "3.7.8"
}
}
From cc5fdd984459f74bb022bfc4f34d7a4f95eb8b7a Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Wed, 26 Feb 2020 13:17:03 +0000
Subject: [PATCH 31/67] Avoid adding extra divs to edit form to avoid size
miscalculation
---
.../node_modules/@node-red/editor-client/src/js/ui/editor.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
index 9fb29833a..6641e9b88 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
@@ -584,8 +584,8 @@ RED.editor = (function() {
// cases, and also prevent browser auto-fill of password
// - the elements cannot be hidden otherwise Chrome will ignore them.
// - the elements need to have id's that imply password/username
- $('
').prependTo(dialogForm);
- $('
').prependTo(dialogForm);
+ $(' ').prependTo(dialogForm);
+ $(' ').prependTo(dialogForm);
dialogForm.on("submit", function(e) { e.preventDefault();});
dialogForm.find('input').attr("autocomplete","off");
return dialogForm;
From 95982ad46493650a725627142872303cc5e0ea3f Mon Sep 17 00:00:00 2001
From: KAZUHIRO ITO
Date: Thu, 27 Feb 2020 16:01:57 +0900
Subject: [PATCH 32/67] Update adminAuth tokensStrategy test spec
---
.../editor-api/lib/auth/strategies_spec.js | 33 ++++++++++++++++---
1 file changed, 28 insertions(+), 5 deletions(-)
diff --git a/test/unit/@node-red/editor-api/lib/auth/strategies_spec.js b/test/unit/@node-red/editor-api/lib/auth/strategies_spec.js
index 13573f22a..848aaf99d 100644
--- a/test/unit/@node-red/editor-api/lib/auth/strategies_spec.js
+++ b/test/unit/@node-red/editor-api/lib/auth/strategies_spec.js
@@ -130,10 +130,13 @@ describe("api/auth/strategies", function() {
});
describe("Tokens Strategy", function() {
- it('Succeeds if tokens user enabled',function(done) {
- var userDefault = sinon.stub(Users,"tokens",function(token) {
+ it('Succeeds if tokens user enabled custom header',function(done) {
+ var userTokens = sinon.stub(Users,"tokens",function(token) {
return when.resolve("tokens-"+token);
});
+ var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
+ return "x-test-token";
+ });
strategies.tokensStrategy._success = strategies.tokensStrategy.success;
strategies.tokensStrategy.success = function(user) {
user.should.equal("tokens-1234");
@@ -141,12 +144,31 @@ describe("api/auth/strategies", function() {
delete strategies.tokensStrategy._success;
done();
};
- strategies.tokensStrategy.authenticate({headers:{"authorization":"1234"}});
+ strategies.tokensStrategy.authenticate({headers:{"x-test-token":"1234"}});
+ });
+ it('Succeeds if tokens user enabled default header',function(done) {
+ var userTokens = sinon.stub(Users,"tokens",function(token) {
+ return when.resolve("tokens-"+token);
+ });
+ var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
+ return "authorization";
+ });
+ strategies.tokensStrategy._success = strategies.tokensStrategy.success;
+ strategies.tokensStrategy.success = function(user) {
+ user.should.equal("tokens-1234");
+ strategies.tokensStrategy.success = strategies.tokensStrategy._success;
+ delete strategies.tokensStrategy._success;
+ done();
+ };
+ strategies.tokensStrategy.authenticate({headers:{"authorization":"Bearer 1234"}});
});
it('Fails if tokens user not enabled',function(done) {
- var userDefault = sinon.stub(Users,"tokens",function() {
+ var userTokens = sinon.stub(Users,"tokens",function() {
return when.resolve(null);
});
+ var userTokenHeader = sinon.stub(Users,"tokenHeader",function(token) {
+ return "authorization";
+ });
strategies.tokensStrategy._fail = strategies.tokensStrategy.fail;
strategies.tokensStrategy.fail = function(err) {
err.should.equal(401);
@@ -154,10 +176,11 @@ describe("api/auth/strategies", function() {
delete strategies.tokensStrategy._fail;
done();
};
- strategies.tokensStrategy.authenticate({headers:{"authorization":"1234"}});
+ strategies.tokensStrategy.authenticate({headers:{"authorization":"Bearer 1234"}});
});
afterEach(function() {
Users.tokens.restore();
+ Users.tokenHeader.restore();
})
});
From 458d794f52492a311316add9486a3986c2b64904 Mon Sep 17 00:00:00 2001
From: KAZUHIRO ITO
Date: Thu, 27 Feb 2020 19:41:59 +0900
Subject: [PATCH 33/67] Fix tokensStrategy order
---
packages/node_modules/@node-red/editor-api/lib/auth/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/node_modules/@node-red/editor-api/lib/auth/index.js b/packages/node_modules/@node-red/editor-api/lib/auth/index.js
index c3948cd27..88e924e53 100644
--- a/packages/node_modules/@node-red/editor-api/lib/auth/index.js
+++ b/packages/node_modules/@node-red/editor-api/lib/auth/index.js
@@ -61,7 +61,7 @@ function init(_settings,storage) {
function needsPermission(permission) {
return function(req,res,next) {
if (settings && settings.adminAuth) {
- return passport.authenticate(['bearer','anon','tokens'],{ session: false })(req,res,function() {
+ return passport.authenticate(['bearer','tokens','anon'],{ session: false })(req,res,function() {
if (!req.user) {
return next();
}
From 83942c255151aee0e92b2045b93a927576483f54 Mon Sep 17 00:00:00 2001
From: KAZUHIRO ITO
Date: Thu, 27 Feb 2020 19:55:21 +0900
Subject: [PATCH 34/67] Fix plugin only receives the actual token
---
.../@node-red/editor-api/lib/auth/strategies.js | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/packages/node_modules/@node-red/editor-api/lib/auth/strategies.js b/packages/node_modules/@node-red/editor-api/lib/auth/strategies.js
index 9705ddd28..87023a487 100644
--- a/packages/node_modules/@node-red/editor-api/lib/auth/strategies.js
+++ b/packages/node_modules/@node-red/editor-api/lib/auth/strategies.js
@@ -130,7 +130,14 @@ function TokensStrategy() {
util.inherits(TokensStrategy, passport.Strategy);
TokensStrategy.prototype.authenticate = function(req) {
var self = this;
- var token = req.headers[Users.tokenHeader()];
+ var token = null;
+ if (Users.tokenHeader() === 'authorization') {
+ if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
+ token = req.headers.authorization.split(' ')[1];
+ }
+ } else {
+ token = req.headers[Users.tokenHeader()];
+ }
if (token) {
Users.tokens(token).then(function(admin) {
if (admin) {
From 2a6bedbd8d2467da4b1f37607cd486902ba02a6a Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Thu, 27 Feb 2020 11:38:44 +0000
Subject: [PATCH 35/67] update changelog
---
CHANGELOG.md | 490 ++++++++++++++++++++++++++++-----------------------
1 file changed, 272 insertions(+), 218 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7b75d30f..7ea3845c2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,57 @@
+#### 1.0.4: Maintenance Release
+
+Runtime
+
+ - Update all dependencies to latest fix versions
+ - Update JSONata to 1.8.1
+ - #2473 Handle httpAdminRoot missing ending slash with login strategy Fixes
+ - #2470 Update https-proxy-agent
+ - #2461 Allow credentials to be provided as part of /flows api
+ - #2444 Move receive metric position to better reflect async changes Fixes
+ - #2406 Improve file store error when cache disabled and sync api used Closes
+ - #2399 cloneMessage should handle undefined without throwing err Fixes
+ - #2418 Fix the library api routes to prevent too broad matching of regex URLs
+ - #2417 Remove undefined loadFlowLibrary call
+
+Editor
+
+ - #2465 Add better regex highlighting in jsonata edit mode Fixes
+ - Add regex awareness to jsonata formatter
+ - #2472 Avoid adding extra newlines when formating jsonata Fixes
+ - #2475 Add UI test case for error handling
+ - Avoid adding extra divs to edit form to avoid size miscalculation
+ - Upgrade to latest marked and dompurify libs
+ - Ensure catalog load errors are logged to the console
+ - #2460 Track context sidebar element paths to track formatting changes Fixes
+ - Battling Chrome Autocomplete, part 31: Wrap search input with form
+ - #2445 Trick chrome into autofilling dummy username/password inputs Fixes
+ - #2457 Fix garbled characters in library
+ - #2409 Filter palette using raw label not html formatted label Fixes
+ - #2400 Wrap long context values when displaying in sidebar Fixes
+ - Fix duplicating array item in visual json editor
+ - #2338 Modify history sidebar button positioning to handle long labels Fixes
+ - #2438 Add some auto-complete snippets to the nrjavascript mode Close
+ - #2430 Ignore disabled nodes when checking for invalid configs on deploy Closes
+ - #2442 #2458 #2453 Update zh-CN translations
+ - #2235 Add initial zh-TW translation
+ - Re-enable jshint on editor and fixup issues
+ - #2431 Remove unnecessary namespaces for i18n
+ - #2440 Support BrowserStack in UI testing
+ - #2358 Add path property to debug messages Fixes
+ - Fix false change detection when no config node selected
+ - Fix IME bug in text editor
+ - Make node highlighting a bit more obvious for busy flows
+ - #2392 Add icons and support i18n in typedInput of JSON editor
+
+Nodes
+ - #2462 MQTT: Ensure IPv6 broker names are wrapped in brackets Fixes
+ - Join node - check existance before clearing timeout
+ - Trigger: Complete 2nd msg when set to send latest
+ - TCP: clarify text regarding blank parameters.
+ - #2449 HTTP Request: Add HEAD as Method
+ - Make min-height for change, switch, batch and mqtt consistent
+
+
#### 1.0.3: Maintenance Release
Runtime
@@ -44,7 +98,7 @@ Runtime
Editor
- Ensure node status is refreshed whenever node is edited
- - #2315 #2316 Ensure z property included in full message debug payload
+ - #2316 Ensure z property included in full message debug payload #2315
- #2321 Fixed editor.json (JA nls)
- #2313 Fix element to collapse items in visual JSON editor
- #2314 Insert divider in menu by calling RED.menu.addItem('id', null);
@@ -113,9 +167,9 @@ Editor
- Move flow-status button to footer for consistency
- Fix node hover effect to prevent jumping position
- Filter quick-add properly when splicing a wire
- - Mark workspace dirty when deleting link node link Fixes #2274
+ - #2274 Mark workspace dirty when deleting link node link Fixes
- Add red-ui-button class to strategy login button
- - Fix padding of subflow locale select Closes #2276
+ - #2276 Fix padding of subflow locale select Closes
- Update info text of complete node & add JP text
- Add class red-ui-button to cancel button
- Add css class to login submit button (#2275)
@@ -138,12 +192,12 @@ Runtime
- [FEATURE] Add Node Done API - make message passing async
- Ensure the subflow stop promise is waiting for before restarting
- Limit the regex for the /nodes/ api end points
- - Add error event handler to ssh-keygen child_process Fixes #2255
- - Fix default value handling on context array access Fixes #2252
+ - #2255 Add error event handler to ssh-keygen child_process Fixes
+ - #2252 Fix default value handling on context array access Fixes
- Remove all ui test dependencies from package.json
- Add req back to audit log events and extend to Projects api
- - Ensure 2nd arg to node.error is an object Fixes #2228
- - Use a more atomic process for writing context files Fixes #2271
+ - #2228 Ensure 2nd arg to node.error is an object Fixes
+ - #2271 Use a more atomic process for writing context files Fixes
Editor
@@ -162,25 +216,25 @@ Editor
- [FEATURE] add support for specifying subflow template color
- [FEATURE] Use ctrl-click on wire to splice node in place
- [FEATURE] Allow search results to show more than 25 results
- - [FEATURE] Allow a node to change if it has an input port Closes #2268
- - Revealing node position needs to account for zoom level Fixes #2172
- - Fix typedInput option selection Fixes #2174
- - Fix palette node id handling so search works Fixes #2173
+ - #2268 [FEATURE] Allow a node to change if it has an input port Closes
+ - #2172 Revealing node position needs to account for zoom level Fixes
+ - #2174 Fix typedInput option selection Fixes
+ - #2173 Fix palette node id handling so search works Fixes
- Add popover tooltips to debug sidebar,function and template
- Add popovers to context sidebar mini buttons
- Ensure node status icon is shown when value set
- Revert treeList children function signature change
- Restore tray component css for compatibility. Mark as deprecated
- fix function name & string compare function
- - Handle empty list of example flows Fixes #2171
+ - #2171 Handle empty list of example flows Fixes
- Ensure library list has an item selected when opened
- Ensure tooltip popover doesn't replace normal popover
- Fix clipboard export download button
- Ensure input box has focus on repeated quick add
- Fix width calculation of typedInput
- Remove some hardcoded css colors
- - Fix display of node help when clicking in palette Fixes #2194
- - Ensure node help is loaded in the right language Fixes #2195
+ - #2194 Fix display of node help when clicking in palette Fixes
+ - #2195 Ensure node help is loaded in the right language Fixes
- Do not allow tab focus on clipboard hidden element
- Fix undefined error on typedInput due to valueLabel used before being added
- Fix undo of flow disable state change
@@ -193,7 +247,7 @@ Editor
- Update all node icons to SVG
- Handle png/svg fallback for def.icon values. Remove old pngs
- Ignore empty examples directories (don't add to import menu)
- - better handle example file at any depth - #2222
+ - #2222 better handle example file at any depth -
- Properly escape node types in palette
- Ensure session expiry timeout doesn't exceed limit
- Use node/tab map to make filterNodes more efficient
@@ -201,22 +255,22 @@ Editor
- Handle undefined node.\_def in edit stack title.
- fix converting selection to subflow
- Fix inserting new subflow node to existing wire between nodes
- - Support displaying falsey node status values Fixes #2246
+ - #2246 Support displaying falsey node status values Fixes
- Remove tab menu from node property UI for subflow and config nodes
- - Mark workspace dirty when shift-click-drag detaches wires Fixes #2260
+ - #2260 Mark workspace dirty when shift-click-drag detaches wires Fixes
- Fix subflow category change on palette
Nodes
- Remove pi gpi, twitter, email and feedparser nodes from core
- - Fix error handling in Websocket broadcast function Fixes #2182
+ - #2182 Fix error handling in Websocket broadcast function Fixes
- Handle websocket item being parseable but not an object better
- stop join tripping up if last message of buffer is blank.
- Add support for env var propety in switch node
- Improve handling of file upload in request node
- Add "has key" rule to switch node + tests
- Optimise generation of switch node edit dialog
- - Add keep-alive option to HTTP Request - #2261
+ - #2261 Add keep-alive option to HTTP Request -
#### 1.0.0-beta.2: Beta Release
@@ -228,7 +282,7 @@ Runtime
Runtime
- Update runtime apis to support multiple libraries
- Add Node 12 to travis (allow_failures)
- - Bump all dependencies Fixes #2152
+ - #2152 Bump all dependencies Fixes
Editor
- [BREAKING] complete overhaul of editor DOM/CSS structure
@@ -240,17 +294,17 @@ Editor
- Allow script tags with src to reference esm modules
- Upgrade to jq 3.4.1 / jq-ui 1.12.1
- Allow editor language to be chosen in editor settings
- - Only NLS status text that starts with a letter Fixes #2128
- - Fix display of link node list within subflow Fixes #2140
- - Blur the active element when closing edit dialog via action Fixes #2097
- - Trigger change evnt on typedInput when type changes and options present Fixes #2160
+ - #2128 Only NLS status text that starts with a letter Fixes
+ - #2140 Fix display of link node list within subflow Fixes
+ - #2097 Blur the active element when closing edit dialog via action Fixes
+ - #2160 Trigger change evnt on typedInput when type changes and options present Fixes
- Move library import/export to single dialog
- Move type-library dialogs to new style dialog
- Fix node drag and drop animation
- let status be simple text if wanted
- Add workspace statusBar
- Complete refresh of German translations
- - Fix memory leak in Debug sidebar #2163
+ - #2163 Fix memory leak in Debug sidebar
- Introduce toggleButton and move flow-disabled to use it
- Allow RED.settings.get/set to use full property desc
- Add auto-refresh toggle to context sidebar
@@ -269,26 +323,26 @@ Nodes
#### 0.20.8: Maintenance Release
- Sanitize tab name in edit dialog
- - Pass httpServer to runtime even when httpAdmin disabled Fixes #2272
+ - #2272 Pass httpServer to runtime even when httpAdmin disabled Fixes
#### 0.20.7: Maintenance Release
- - Update jsonata to 1.6.5 which should fix #2183
+ - #2183 Update jsonata to 1.6.5 which should fix
- Ensure the subflow stop promise is waiting for before restarting
- Properly escape node types in palette
#### 0.20.6: Maintenance Release
- - Revealing node position needs to account for zoom level Fixes #2172
+ - #2172 Revealing node position needs to account for zoom level Fixes
- stop join tripping up if last message of buffer is blank.
- Improve handling of file upload in request node
- - Handle subflow internal node wired to a non-existant node Fixes #2202
+ - #2202 Handle subflow internal node wired to a non-existant node Fixes
- Do not save subflow env vars with blank names
- Don't allow a link node virtual wire to connect to normal port
- - Clear HTTP Request node authType when auth disabled Fixes #2215
- - Fix parsing of content-type header Fixes #2216
+ - #2215 Clear HTTP Request node authType when auth disabled Fixes
+ - #2216 Fix parsing of content-type header Fixes
- Fix join node reset issue with merging objects
- - Copy data-i18n attribute on TypedInput Fixes #2211
+ - #2211 Copy data-i18n attribute on TypedInput Fixes
#### 0.20.5: Maintenance Release
@@ -325,27 +379,27 @@ Nodes
#### 0.20.1: Maintenance Release
- - Ensure all subflow instances are stopped when flow stopping Fixes #2095
- - modify name of korean locale forders #2091
+ - #2095 Ensure all subflow instances are stopped when flow stopping Fixes
+ - #2091 modify name of korean locale forders
- Ensure node names are sanitized before being presented
- - Subflow status node must pass status to parent flow Fixes #2087
- - fix problem on displaying option label on Firefox #2090
+ - #2087 Subflow status node must pass status to parent flow Fixes
+ - #2090 fix problem on displaying option label on Firefox
#### 0.20.0: Milestone Release
Runtime
- Pass complete status to Status node and filter to editor
- - Ensure flows wait for all nodes to close before restarting Fixes #2067
+ - #2067 Ensure flows wait for all nodes to close before restarting Fixes
- Fix git clone with password protected key
- Allow a project to be located below the root of repo
- Detect the cloning of an empty git repo properly
- Fix use of custom auth strategy plugins
- - Remove remnants of when library in git/index Fixes #2057
+ - #2057 Remove remnants of when library in git/index Fixes
- Clear subflow status on close
- Add exportGlobalContextKeys to prevent exposing functionGlobalContext keys
- Add --no-audit and --no-update-notifier flags to npm commands to reduce workload
- Add envVarExcludes setting to block named env vars
- - Update settings.js docs on userDir to match reality Fixes #2082
+ - #2082 Update settings.js docs on userDir to match reality Fixes
- Add Korean Language
@@ -389,16 +443,16 @@ Editor
- Add env type to subflow env var types
- Display parent subflow properties in edit dialog
- Fix direction value of subflow output
- - Add Status Node to Subflow to allow subflow-specific status Closes #597
- - Better handling of multiple flow merges Fixes #2039
+ - #597 Add Status Node to Subflow to allow subflow-specific status Closes
+ - #2039 Better handling of multiple flow merges Fixes
Nodes
- Various translation updates
- - Catch: Add 'catch uncaught only' mode. Closes #1747
+ - #1747 Catch: Add 'catch uncaught only' mode. Closes
- Link: scroll to current flow in node list
- HTTPRequest: add option to urlencode cookies
- - HTTPRequest: option to use msg.payload as query params on GET. #1981
+ - #1981 HTTPRequest: option to use msg.payload as query params on GET.
- Debug: Add local time display option to numerics in debug window
- MQTT: Add parsed JSON output option
@@ -416,9 +470,9 @@ Editor
- German translation
- Change default dropdown appearance and sidebar tab menu handling
- - Handle multiple-select box when nothing selected Fixes #2021
- - Handle i18n properly when key is a valid sub-identifier Fixes #2028
- - Avoid duplicate links when missing node type installed Fixes #2032
+ - #2021 Handle multiple-select box when nothing selected Fixes
+ - #2028 Handle i18n properly when key is a valid sub-identifier Fixes
+ - #2032 Avoid duplicate links when missing node type installed Fixes
- Add View Tools
- Don't collapse version control header when clicking refresh
- Add fast entry via keyboard for string of nodes
@@ -438,15 +492,15 @@ Editor
- Update palette manager view properly when module updated
- Add TreeList common widget
- - Fix visual jump when opening Comment editor on Safari Part of #2008
- - Fix vertical align of markdown editor in Safari Fixes #2008
- - Avoid marking node as changed if label state is default Fixes #2009
+ - #2008 Fix visual jump when opening Comment editor on Safari Part of
+ - #2008 Fix vertical align of markdown editor in Safari Fixes
+ - #2009 Avoid marking node as changed if label state is default Fixes
- Highlight port on node hover while joining
- Support drag-wiring of link nodes
- Allow TypeSearch to include a filter option
- Improve diff colouring
- Allow sections to toggle in 2-element stack
- - Add support for ${} env var syntax when skipping validation Closes #1980
+ - #1980 Add support for ${} env var syntax when skipping validation Closes
- i18 support for markdown editor tooltip
- Add RED.editor.registerTypeEditor for custom type editors
- Tidy up markdown toolbar handling across all editors
@@ -456,15 +510,15 @@ Editor
Runtime
- - Bump JSONata to 1.6.4 Fixes #2023
+ - #2023 Bump JSONata to 1.6.4 Fixes
- Add audit logging to admin api
- - Fix failure of RED.require #2010
- - Allow oauth strategy callback method to be customised Closes #1998
- - Ensure fs context cache is flushed on close Fixes #2001
+ - #2010 Fix failure of RED.require
+ - #1998 Allow oauth strategy callback method to be customised Closes
+ - #2001 Ensure fs context cache is flushed on close Fixes
- Fix library Buffer( to Buffer.alloc( for node 10
- Catch file-not-found on startup when non-existant flow file specified
- Actively expire login sesssions and notify user
- - Add quotation marks for basic auth challenge #1976
+ - #1976 Add quotation marks for basic auth challenge
Nodes
@@ -482,7 +536,7 @@ Nodes
Editor
- Allow the editor to use a custom admin api url root
- - Improve performance of Flow Diff dialog - @TothiViseo #1989
+ - #1989 Improve performance of Flow Diff dialog - @TothiViseo
- Add 'open project' option to Projects Welcome dialog
- Add 'type already registered' check in palette editor
- Handle missing tab.disabled property
@@ -500,11 +554,11 @@ Editor
- Allow left-hand node button to act as toggle
- Support dbl-click in tab bar to add new flow in position
- Fix duplicate subflow detection on import
- - Add import notification with info on what has been imported Closes #1862
+ - #1862 Add import notification with info on what has been imported Closes
- Show error details when trying to import invalid json
- Show default icon when non-existent font-awesome icon was specified
- Add configurable option for showing node label
- - Avoid http redirects as Safari doesn't reuse Auth header Fixes #1903
+ - #1903 Avoid http redirects as Safari doesn't reuse Auth header Fixes
- Tidy up ace tooltip styling
- Add event log to editor
- Add tooltips to multiple editor elements
@@ -532,30 +586,30 @@ Editor
Runtime
- Allow a project to be loaded from cmdline
- - Handle lookup of undefined property in Global context Fixes #1978
+ - #1978 Handle lookup of undefined property in Global context Fixes
- Refuse to enable Manage Palette if npm too old
- Remove restriction on upgrading non-local modules
- - Remove deprecated Buffer constructor usage Fixes #1709
+ - #1709 Remove deprecated Buffer constructor usage Fixes
- Update httpServerOptions doc in settings.js
- Exclude non-testable .js files from the unit tests
- Add --safe mode flag to allow starting without flows running
- - Add setting-defined accessToken for automated access to the adminAPI - #1789
+ - #1789 Add setting-defined accessToken for automated access to the adminAPI -
Nodes
- - Move all core node EN help to their own locale files - #1990
+ - #1990 Move all core node EN help to their own locale files -
- CSV: better regex for number detection
- Debug: hide button if not configured to send to sidebar
- Delay: report queue activity when in by-topic mode
- Delay: add msg.flush mode
- Exec: Preserve existing properties on msg object
- File: remove CR/LF from incoming filename
- - Function: create custom ace javascript mode to handle ES6 Fixes #1911
+ - #1911 Function: create custom ace javascript mode to handle ES6 Fixes
- Function: add env.get
- - HTTP Request: Add http-proxy config #1913
+ - #1913 HTTP Request: Add http-proxy config
- HTTP Request: add msg.redirectList to output
- - HTTP Request: add msg.requestTimeout option for per-message setting - @natcl #1959
- - MQTT: add auto-detect and base64 output to mqtt node Fixes #1912 - @DurandA
+ - #1959 HTTP Request: add msg.requestTimeout option for per-message setting - @natcl
+ - #1912 - @DurandA MQTT: add auto-detect and base64 output to mqtt node Fixes
- MQTT: only unsubscribe node that is being removed
- Sentiment: move to node-red-node-sentiment
- Switch: add missing edit dialog icon
@@ -570,48 +624,48 @@ Nodes
#### 0.19.6: Maintenance Release
- - Fix encoding of file node from binary to utf8 - #2051
+ - #2051 Fix encoding of file node from binary to utf8 -
#### 0.19.5: Maintenance Release
- Recognize pip installs of RPi.GPIO (#1934)
- - Merge pull request #1941 from node-red-hitachi/master-batch
- - Merge pull request #1931 from node-red-hitachi/master-typedinput
+ - #1941 from node-red-hitachi/master-batch Merge pull request
+ - #1931 from node-red-hitachi/master-typedinput Merge pull request
- Set min value of properties and spinners for batch
- Fix that unnecessary optionMenu remains
- - Merge pull request #1894 from node-red-hitachi/fix-overlapping-file-node-execution
- - Merge pull request #1924 from imZack/patch-1
+ - #1894 from node-red-hitachi/fix-overlapping-file-node-execution Merge pull request
+ - #1924 from imZack/patch-1 Merge pull request
- Add missing comma
- - Do not disable context sidebar during node edit Fixes #1921
- - Don't allow virtual links to be spliced Fixes #1920
+ - #1921 Do not disable context sidebar during node edit Fixes
+ - #1920 Don't allow virtual links to be spliced Fixes
- Merge project package changes to avoid overwritten changes
- - Handle manually added project deps that are unused Fixes #1908
+ - #1908 Handle manually added project deps that are unused Fixes
- update close & input handling of File node
- make close handler argument only one
- - Merge pull request #1907 from amilajack/patch-2
+ - #1907 from amilajack/patch-2 Merge pull request
- Change repo badge to point to master branch
- invoke callbacks if async handler is specified
- - Merge pull request #1891 from camlow325/resolve-example-path-for-windows-support
- - Merge pull request #1900 from kazuhitoyokoi/master-addtestcases4settings.js
+ - #1891 from camlow325/resolve-example-path-for-windows-support Merge pull request
+ - #1900 from kazuhitoyokoi/master-addtestcases4settings.js Merge pull request
- wait closing while pending messages exist
- Add test cases for red/api/editor/settings.js
- - Ensure all palette categories are opened properly Closes #1893
+ - #1893 Ensure all palette categories are opened properly Closes
- Resolve path when sending example file for Windows support
- fix multiple input message processing of file node
#### 0.19.4: Maintenance Release
- - Fix race condition in non-cache lfs context Fixes #1888
+ - #1888 Fix race condition in non-cache lfs context Fixes
- LocalFileSystem Context: Remove extra flush code
- Prevent race condition in caching mode of lfs context (#1889)
- Allow context store name to be provided in the key
- Switch node: only use promises when absolutely necessary
- Fix dbl-click handling on webkit-based browsers
- Ensure context.flow/global cannot be deleted or enumerated
- - Handle context.get with multiple levels of unknown key Fixes #1883
+ - #1883 Handle context.get with multiple levels of unknown key Fixes
- Fix global.get("foo.bar") for functionGlobalContext set values
- Fix node color bug (#1877)
- - Merge pull request #1857 from cclauss/patch-1
+ - #1857 from cclauss/patch-1 Merge pull request
- Define raw_input() in Python 3 & fix time.sleep()
#### 0.19.3: Maintenance Release
@@ -626,14 +680,14 @@ Nodes
- TCP-request node - only write payload
- JSON schema: perform validation when obj -> obj or str -> str
- JSON schema: add draft-06 support (via $schema keyword)
- - Mqtt proxy configuration for websocket connection, #1651.
+ - #1651. Mqtt proxy configuration for websocket connection,
- Allows MQTT Shared Subscriptions for MQTT-In core node
- Fix use of HTML tag or CSS class specification as icon of typedInput
#### 0.19.2: Maintenance Release
- Ensure node default colour is used if palette.theme has no match
- - fix lost messages / properties in TCPRequest Node; closes #1863 (#1864)
+ - #1863 (#1864) fix lost messages / properties in TCPRequest Node; closes
- Fix typo in template.html
- Improve error reporting from context plugin loading
- Prevent no-op edit of node marking as changed due to icon
@@ -653,8 +707,8 @@ Nodes
Editor
- Add editorTheme.palette.theme to allow overriding colours
- - Index all node properties when searching Fixes #1446
- - Handle NaN and Infinity properly in debug sidebar Fixes #1778 #1779
+ - #1446 Index all node properties when searching Fixes
+ - #1779 Handle NaN and Infinity properly in debug sidebar Fixes #1778
- Prevent horizontal scroll when palette name cannot wrap
- Ignore middle-click on node/ports to enable panning
- Better wire layout when looping back
@@ -668,7 +722,7 @@ Editor
- Only edit nodes on dbl click on primary button with no modifiers
- Allow subflows to be put in any palette category
- Add flow navigator widget
- - Cache flow library result to improve response time Fixes #1753
+ - #1753 Cache flow library result to improve response time Fixes
- Add middle-button-drag to pan the workspace
- allow multi-line category name in editor
- Redesign sidebar tabs
@@ -676,20 +730,20 @@ Editor
Nodes
- - Change: Ensure runtime errors in Change node can be caught Fixes #1769
+ - #1769 Change: Ensure runtime errors in Change node can be caught Fixes
- File: Add output to File Out node
- Function: add expandable JavaScript editor pane
- Function: allow id and name reference in function node code (#1731)
- HTTP Request: Move to request module
- - HTTP: Ensure apiMaxLength applies to HTTP Nodes Fixes #1278
+ - #1278 HTTP: Ensure apiMaxLength applies to HTTP Nodes Fixes
- Join: accumulate top level properties
- Join: allow environment variable as reduce init value
- JSON: add JSON schema validation via msg.schema
- Pi: Let nrgpio code work with python 3
- Pi: let Pi nodes be visible/editable on all platforms
- Switch: add isEmpty rule
- - TCP: queue messages while connecting; closes #1414
- - TLS: Add servername option to TLS config node for SNI Fixes #1805
+ - #1414 TCP: queue messages while connecting; closes
+ - #1805 TLS: Add servername option to TLS config node for SNI Fixes
- UDP: Don't accidentally re-use udp port when set to not do so
Persistent Context
@@ -704,8 +758,8 @@ Persistent Context
Runtime
- Support flow.disabled and .info in /flow API
- - Node errors should be Strings not Errors Fixes #1781
- - Add detection of connection timeout in git communication Fixes #1770
+ - #1781 Node errors should be Strings not Errors Fixes
+ - #1770 Add detection of connection timeout in git communication Fixes
- Handle loading empty nodesDir
- Add 'private' property to userDir generated package.json
- Add RED.require to allow nodes to access other modules
@@ -715,7 +769,7 @@ Runtime
Editor Fixes
- - Do not trim wires if node declares outputs in defaults but misses value Fixes #1737
+ - #1737 Do not trim wires if node declares outputs in defaults but misses value Fixes
Node Fixes
@@ -725,16 +779,16 @@ Node Fixes
- typo fix in node help (#1735)
Other Fixes
- - Tidy up default grunt task and fixup test break due to reorder Fixes #1738
+ - #1738 Tidy up default grunt task and fixup test break due to reorder Fixes
- Bump jsonata version
#### 0.18.6: Maintenance Release
Editor Fixes
- - Handle a node having wires in the editor on ports it no longer has Fixes #1724
+ - #1724 Handle a node having wires in the editor on ports it no longer has Fixes
- Add missing ACE snippet files
- - Fix wireClippedNodes is not defined Fixes #1726
+ - #1726 Fix wireClippedNodes is not defined Fixes
- Split node html to isolate bad nodes when loading
- Avoid unnecessary use of .html() where .text() will do
@@ -761,32 +815,32 @@ New Features
Editor Fixes
- - Highlight subflow node when log msg comes from inside Fixes #1698
- - Ensure node wires array is not longer than outputs value Fixes #1678
- - Allow importing an unknown config node to be undone Fixes #1681
- - Ensure keyboard shortcuts get saved in runtime settings Fixes #1696
+ - #1698 Highlight subflow node when log msg comes from inside Fixes
+ - #1678 Ensure node wires array is not longer than outputs value Fixes
+ - #1681 Allow importing an unknown config node to be undone Fixes
+ - #1696 Ensure keyboard shortcuts get saved in runtime settings Fixes
- Don't mark a subflow changed when actually modified nothing (#1665)
Node Fixes
- bind to correct port when doing udp broadcast/multicast (#1686)
- Provide full error stack in Function node log message (#1700)
- - Fix http request doc type Fixes #1690
+ - #1690 Fix http request doc type Fixes
- Make debug slightly larger to pass WCAG AA rating
- - Make core nodes labels more consistent, to close #1673
- - Allow template node to be updated more than once Fixes #1671
+ - #1673 Make core nodes labels more consistent, to close
+ - #1671 Allow template node to be updated more than once Fixes
- Fix the problem that output labels of switch node sometimes disappear (#1664)
- Chinese translations for core nodes (#1607)
Runtime Fixes
- - Handle and display for invalid flow credentials when project is disabled #1689 (#1694)
+ - #1689 (#1694) Handle and display for invalid flow credentials when project is disabled
- node-red-pi: fix behavior with old bash version (#1713)
- Fix ENOENT error on first start when no user dir (#1711)
- - Handle null error object in Flow.handleError Fixes #1721
+ - #1721 Handle null error object in Flow.handleError Fixes
- update settings comments to describe how to setup for ipv6 (#1675)
- - Remove credential props after diffing flow to prevent future false positives Fixes #1359
- - Log error if settings unavailable when saving user settings Fixes #1645
+ - #1359 Remove credential props after diffing flow to prevent future false positives Fixes
+ - #1645 Log error if settings unavailable when saving user settings Fixes
- Keep backup of .config.json
- Add warning if using \_credentialSecret from .config.json
- Filter req.user in /settings to prevent potentially leaking info
@@ -812,7 +866,7 @@ Editor Fixes
- Fix merging a remote diff
- Fixed the problems when using a node without defaults
- Disable user defined icon for subflow
- - getDefaultNodeIcon should handle subflow instance nodes Fixes #1635
+ - #1635 getDefaultNodeIcon should handle subflow instance nodes Fixes
- Add Japanese info text for core nodes
- Fix message lookup for core nodes in case of i18 locales directory exists
- Prevent the last tab from being deleted
@@ -843,7 +897,7 @@ Editor Fixes
- Fix offset calculation when dragging node from palette
- Allow a library entry to use non-default node-input- prefixes
- - Change remote-diff shortcut and add it to keymap Fixes #1628
+ - #1628 Change remote-diff shortcut and add it to keymap Fixes
#### 0.18.2: Maintenance Release
@@ -882,7 +936,7 @@ Projects
- Handle more repo clone error cases
- Relax validation of git urls
- Revalidate project name on return to project-details view
- - Avoid unnecessary project refresh on branch-switch Fixes #1597
+ - #1597 Avoid unnecessary project refresh on branch-switch Fixes
- Add support for file:// git urls
- Handle project first-run without existing flow file
- Handle delete of last remote in project settings
@@ -893,9 +947,9 @@ Projects
Node Fixes
- Trigger node migration - ensure bytopic not blank
- - Add HEAD to list of methods with no body in http req node #1598
- - Do not include payload in GET requests Fixes #1598
- - Update sort/batch docs Fixes #1601
+ - #1598 Add HEAD to list of methods with no body in http req node
+ - #1598 Do not include payload in GET requests Fixes
+ - #1601 Update sort/batch docs Fixes
- Don't assume node has defaults when exporting icon property
@@ -908,11 +962,11 @@ Runtime
- Better error reporting when module provides duplicate type
- Update jsonata to 1.5.0
- add express-session memorystore without leaks (#1435)
- - Allow adminAuth.user to be a Function Fixes #1461
+ - #1461 Allow adminAuth.user to be a Function Fixes
- Ensure RED.server is set even if admin api disabled
- - Ensure strategy login button uses relative URL Fixes #1481
+ - #1481 Ensure strategy login button uses relative URL Fixes
- ignore `_msgid` when merging full objects
- - Move node install to spawn to allow for big stdout Fixes #1488
+ - #1488 Move node install to spawn to allow for big stdout Fixes
- SIGINT handler should wait for stop to complete before exit
Editor
@@ -920,12 +974,12 @@ Editor
- allow a node's icon to be set dynamically (#1490)
- Batch messages sent over comms to increase throughput
- Migrate deploy confirmations to notifications
- - `oneditdelete` should be available to all node types Closes #1346
+ - #1346 `oneditdelete` should be available to all node types Closes
- Sort typeSearch results based on position of match
- Update ACE to test and add python highlighter (#1373)
- - Clear mouse state when typeSearch cancelled Fixes #1517
+ - #1517 Clear mouse state when typeSearch cancelled Fixes
- Handle scoped modules via palette editor
- - TypedInput: handle user defined value/labels options Fixes #1549
+ - #1549 TypedInput: handle user defined value/labels options Fixes
Nodes
@@ -940,7 +994,7 @@ Nodes
- Add support for rejectUnauthorized msg property
- Add TLS options to WebSocket client
- Added parsed YAML support for template node (#1443)
- - Allow delay node in rate-limit mode to be reset Fixes #1360
+ - #1360 Allow delay node in rate-limit mode to be reset Fixes
- Allow setTimeout in Function node to be promisified in node 8
- Debug to status option (#1499)
- enable template config via msg.template for stored or generated templates (#1503)
@@ -959,13 +1013,13 @@ Nodes
- MQTT node - if Server/URL config contains '//' use it as a complete url; enabled ws:// and wss://
- clone messages before delayed send (#1474)
- Decrement connected client count rather than show disconnected
- - Don't end mqtt client on first error Fixes #1566
- - File out - create dirs synchronously to ensure they exist Fixes #1489
+ - #1566 Don't end mqtt client on first error Fixes
+ - #1489 File out - create dirs synchronously to ensure they exist Fixes
- Fix debug message format for Buffer (#1444)
- Fix global.keys() bug in function node (#1417)
- Handle escape characters in template node which uses Mustache format and JSON output mode (#1377)
- - Move all node.send to end of timer functions in trigger node (issue #1527) (#1539)
- - Publish null/undefined to mqtt as blank not toString Fixes #1521
+ - #1527) (#1539) Move all node.send to end of timer functions in trigger node (issue
+ - #1521 Publish null/undefined to mqtt as blank not toString Fixes
- remove inject node at specific time spinner
- restrict inject interval to less that 2^31 millisecs
- tag UDP ports in use properly so they get closed correctly (#1508)
@@ -974,10 +1028,10 @@ Nodes
- Add express-session missing dependency for oauth
- Fix improper type tests is core test cases
- - File node: recreate write stream when file deleted Fixes #1351
+ - #1351 File node: recreate write stream when file deleted Fixes
- Add flow stopping trace messages
- Fix userDir test case when .config.json exists (#1350)
- - Do not try to send msg after http request error handled Fixes #1344
+ - #1344 Do not try to send msg after http request error handled Fixes
- Fix boundary problem in range node (#1338)
- Modify messages in node properties to refer messages.json (#1339)
- Fix settings.js replacing webSocketVerifyClient by webSocketNodeVerifyClient (#1343)
@@ -988,16 +1042,16 @@ Nodes
- Add request node test case for POSTing 0
- Allow false and 0 in payload for httprequest (#1334)
- Add file extension into flow name of library automatically (#1331)
- - Fix accessing global context from jsonata expressions Fixes #1335
- - Disable editor whilst a deploy is inflight Fixes #1332
+ - #1335 Fix accessing global context from jsonata expressions Fixes
+ - #1332 Disable editor whilst a deploy is inflight Fixes
- Replace Unknown nodes with their real versions when node loaded
- Retry auto-install of modules that fail
- Fix column name in link nodes to refer language file (#1330)
- - Use namespaces with link node title attributes i18n name Fixes #1329
- - Tidy up GPIO pin table presentation Fixes #1328
+ - #1329 Use namespaces with link node title attributes i18n name Fixes
+ - #1328 Tidy up GPIO pin table presentation Fixes
- Join: count of 0 should not send on every msg
- Handle importing only one end of a link node pair
- - Make sending to Debug synchronous again Fixes #1323
+ - #1323 Make sending to Debug synchronous again Fixes
- Make send-error behaviour optional in file node
- Restore File In node behaviour of sending msg on error
- Expose context.keys within Function node
@@ -1011,10 +1065,10 @@ Nodes
- Fix missing icons for some nodes (#1321)
- Add reformat button to JSONata test data editor
- Update delay node status without spawning unnecessary intervals
- - Avoid stringify ServerResponse and Socket in Debug node Fixes #1311
+ - #1311 Avoid stringify ServerResponse and Socket in Debug node Fixes
- Fix creating userDir other than system drive on Windows (#1317)
- - Trigger node not handling a duration of 0 as block mode Fixes #1316
- - Unable to config GPIO Pin 13 Fixes #1314
+ - #1316 Trigger node not handling a duration of 0 as block mode Fixes
+ - #1314 Unable to config GPIO Pin 13 Fixes
#### 0.17.2: Maintenance Release
@@ -1023,7 +1077,7 @@ Nodes
#### 0.17.1: Maintenance Release
- Fix PI gpio to use BCM
- - Prevent event thread contention when sending to Debug node Closes #1311
+ - #1311 Prevent event thread contention when sending to Debug node Closes
- Fix Bug: Can not display node icon when npm package has scope (#1305) (#1309)
- Clear moved flag when nodes are deployed
@@ -1031,7 +1085,7 @@ Nodes
Runtime
- - Return flow rev on reload api when api v2 enabled Closes #1273
+ - #1273 Return flow rev on reload api when api v2 enabled Closes
- Provide single endpoint to load all node message catalogs
- Add .trace and .debug to Node prototype
- Rename oauth auth scheme to strategy as it works for openid
@@ -1039,16 +1093,16 @@ Runtime
- Add support for oauth adminAuth configs
- Cache auth details to save needlessly recalculating hashes
- Add context.keys function to list top-level keys
- - Strip BOM character from JSON files if present Fixes #1239
+ - #1239 Strip BOM character from JSON files if present Fixes
- Version check no meta (#1243)
- - Ensure all nodes have access to global context Fixes #1230
- - Don't process subscription for unauthenticated comms link Fixes #851
- - Clone credentials when passing to node Fixes #1198
+ - #1230 Ensure all nodes have access to global context Fixes
+ - #851 Don't process subscription for unauthenticated comms link Fixes
+ - #1198 Clone credentials when passing to node Fixes
- Resolve dir argument of getLocalNodeFiles function (#1216)
- Add wait for writing a library entry into a file. (#1186)
- Use correct Buffer.from method rather than constructor
- update core nodes to use newer Buffer syntax
- - Treat missing msg properties as undefined rather than throw error Fixes #1167
+ - #1167 Treat missing msg properties as undefined rather than throw error Fixes
- Allows flows to be enabled/disabled in the runtime
- add off option to logging settings comment
- Log error stack traces if verbose flag is set
@@ -1081,8 +1135,8 @@ Nodes
- Fix wrong number of double quotes in CSV parsing
- let csv node handle ip addresses without trying to parse
- Update debug node to register the settings it uses
- - Handle IncomingMessage/ServerResponse object types in debug Fixes #1202
- - Toggling debug node enabled/disabled state should set state dirty Fixes #1203
+ - #1202 Handle IncomingMessage/ServerResponse object types in debug Fixes
+ - #1203 Toggling debug node enabled/disabled state should set state dirty Fixes
- redo delay node status messages to be interval based
- Update delay node ui
- Add new msg.delay option to delay node
@@ -1118,16 +1172,16 @@ Nodes
- First pass of new node-info style
- MQTT new style info
- Fix empty extra node help content issue
- - Handle HTTP In url that is missing its leading / Fixes #1218
+ - #1218 Handle HTTP In url that is missing its leading / Fixes
- Add file upload support to HTTP In node
- HTTP Request node: add info on how to do form encoding
- - Prevent unmodified msg.headers from breaking HTTP Request flows Closed #1015
+ - #1015 Prevent unmodified msg.headers from breaking HTTP Request flows Closed
- Add cookie handling to HTTP Request node
- Add guard against the http-request buffer fix being reverted
- Multipart streaming
- Add http-request node unit tests
- http request node add transport validity check and warn.
- - Update follow_redirects to fix http_proxy handling Fixes #1172
+ - #1172 Update follow_redirects to fix http_proxy handling Fixes
- Allow statusCode/headers to be set directly within HTTP Response node
- let inject "between time" also fire at start - Plus new info
- remove repeat symbol from inject if repeat is 0
@@ -1176,7 +1230,7 @@ Nodes
- Move udp sock error listener to only be instantiated once.
- Let watch node recurse into subdirectories
- Misconfigured WebSocket nodes should not register msg handlers
- - Add websocketVerifyClient option to enable custom websocket auth Fixes #1127
+ - #1127 Add websocketVerifyClient option to enable custom websocket auth Fixes
Editor
@@ -1198,11 +1252,11 @@ Editor
- Remove unused modified flag on debug messages
- Add copy path/value buttons to debug messages
- dont match only part of the node type (#1242)
- - Add editorTheme.logout.redirect to allow redirect on logout Closes #1213
- - Handle logging out and already logged-out editor Fixes #1288
+ - #1213 Add editorTheme.logout.redirect to allow redirect on logout Closes
+ - #1288 Handle logging out and already logged-out editor Fixes
- Fix bug: Export Subflows (#1282)
- destroy editor to ensure fully removed on close (function, template, comment)
- - Don't try to nls status text starting with '.' Fixes #1258
+ - #1258 Don't try to nls status text starting with '.' Fixes
- Add note of removed flows in diffConfig (#1253)
- Add description to flow same as subflow
- Allow tabs to be enabled/disabled in the editor
@@ -1274,7 +1328,7 @@ Editor
- Allow RED.validators.number to allow blank values as valid
- Support dropping json files into the editor
- NLS Expression/JSON editor and fix their height calculation
- - Update JSONata to 1.2.4 Closes #1275
+ - #1275 Update JSONata to 1.2.4 Closes
- Remember test expression data on a per-node basis
- NLS jsonata test messages
- Add JSONata expr tester and improved feedback
@@ -1291,13 +1345,13 @@ Other
#### 0.16.2: Maintenance Release
- - Ensure custom mustache context parent set in Template node fixes #1126
+ - #1126 Ensure custom mustache context parent set in Template node fixes
- Display debug node name in debug panel if its known
- Ensure auth-tokens are removed when no user is specified in settings
- Ensure all a tags have blank target in info sidebar
- Ensure links do not span tabs in the editor
- Avoid creating multiple reconnect timers in websocket node
- - Fix inner reference in install fail message catalog entry Fixes #1120
+ - #1120 Fix inner reference in install fail message catalog entry Fixes
- Display buffer data properly for truncated buffers under Object property
#### 0.16.1: Maintenance Release
@@ -1305,9 +1359,9 @@ Other
- Add colour swatches to debug when hex colour matched
- Nodes with hasUsers set to false should not appear unused
- Change hard error to verbose warning if using old node.js level
- - Don't filter debug properties starting with _ Fixes #1117
- - Node logged errors not displayed properly in debug pane Fixes #1116
- - Do not look for existing nodes when checking for wires on paste Fixes #1114
+ - #1117 Don't filter debug properties starting with _ Fixes
+ - #1116 Node logged errors not displayed properly in debug pane Fixes
+ - #1114 Do not look for existing nodes when checking for wires on paste Fixes
- -v option not enabling verbose mode properly
- Add node.js version check on startup
@@ -1319,10 +1373,10 @@ Runtime
Nodes
- - Add option to colourise debug console output Closes #1103
+ - #1103 Add option to colourise debug console output Closes
- Add property validation to nodes using typedInput
- - Add common validator for typedInput fields Closes #1104
- - Update debug node console logging indicator icon Closes #1094
+ - #1104 Add common validator for typedInput fields Closes
+ - #1094 Update debug node console logging indicator icon Closes
- Let exec node (spawn) handle commands with spaces in path
- Add symbol to debug node to indicate debugging also to console.log
- Change file node to use node 4 syntax (drops support for 0.8)
@@ -1334,9 +1388,9 @@ Nodes
Editor
- - Add install/remove dialog to increase friction Closes #1109
- - Report node catalogue load errors Closes #1009
- - Properly report module remove errors in palette editor Fixes #1043
+ - #1109 Add install/remove dialog to increase friction Closes
+ - #1009 Report node catalogue load errors Closes
+ - #1043 Properly report module remove errors in palette editor Fixes
- Update rather than hide install button after success install
- Tweak search box styling
- Display info tips slightly longer
@@ -1357,36 +1411,36 @@ Editor
- Focus tray body when edit dialog opened
- Hit enter to edit first node in selection
- Add node delete button to edit dialog
- - Add notification when runtime stopped due to missing types Part of #832
+ - #832 Add notification when runtime stopped due to missing types Part of
Fixes
- - Do not tie debug src loading to needsPermission Fixes #1111
- - Initialise nodeApp regardless of httpAdmin setting Closes #1096 #1095
+ - #1111 Do not tie debug src loading to needsPermission Fixes
+ - #1095 Initialise nodeApp regardless of httpAdmin setting Closes #1096
- Speed up reveal of search dialogs
- - Ensure flows exist before delegating status/error events Fixes #1069
+ - #1069 Ensure flows exist before delegating status/error events Fixes
- Update package dependencies
- Update MQTT to latest 2.2.1
- Node status not being refreshed properly in the editor
- - Try to prevent auto-fill of password fields in node edit tray Fixes #1081
+ - #1081 Try to prevent auto-fill of password fields in node edit tray Fixes
- Fix whitespace in localfilesystem
- fix bug where savesettings did not honor local settings variables (#1073)
- - Tidy up unused/duplicate editor messages Closes #922
+ - #922 Tidy up unused/duplicate editor messages Closes
- Property expressions must not be blank
- Tidy up merge commit of validatePropertyExpression
- add port if wires array > number of ports declared.
- - Allow quoted property expressions Fixes #1101
+ - #1101 Allow quoted property expressions Fixes
- Index all node properties for node search
- Remove node 0.10 from travis config
- update welcome message to use logger so it can be turned off/on if required (#1083)
- Fix dynamically loading multiple node-sets from palette editor
- - Allow a node to reorder its outputs and maintain links Fixes #1031
+ - #1031 Allow a node to reorder its outputs and maintain links Fixes
#### 0.15.3: Maintenance Release
- Tcpgetfix: Another small check (#1070)
- TCPGet: Ensure done() is called only once (#1068)
- - Allow $ and _ at start of property identifiers Fixes #1063
+ - #1063 Allow $ and _ at start of property identifiers Fixes
- TCPGet: Separated the node.connected property for each instance (#1062)
- Corrected 'overide' typo in XML node help (#1061)
- TCPGet: Last property check (hopefully) (#1059)
@@ -1419,11 +1473,11 @@ Fixes
#### 0.15.2: Maintenance Release
- - Revert bidi changes to nodes and hide menu option until fixed Fixes #1024
+ - #1024 Revert bidi changes to nodes and hide menu option until fixed Fixes
- Let xml node set options both ways
- Bump serialport to use version 4
- gpio node handle multiple bits of data returned in one go
- - HTTP In should pass application/octet-stream as buffer not string Fixes #1023
+ - #1023 HTTP In should pass application/octet-stream as buffer not string Fixes
- Handle missing httpNodeRoot setting properly
- Config sidebar not handling node definition error properly
- Add minimum show time to deploy spinner to avoid flicker
@@ -1431,24 +1485,24 @@ Fixes
- Add log.removeHandler function
- Add Crtl/Shift/p shortcut for manage palette
- Add spinner to deploy button
- - Status messages from nodes in subflows not delegated properly Fixes #1016
+ - #1016 Status messages from nodes in subflows not delegated properly Fixes
- fix spelling in join node info
- Speed up tab scrolling
- - Update delay burst test to be more tolerant of timing Fixes #1013
+ - #1013 Update delay burst test to be more tolerant of timing Fixes
#### 0.15.1: Maintenance Release
- Update default palette catalogue to use https
- Disable palette editor if npm not found - and fix for Windows
- - Searching package catalogue should be case-insensitive Fixes #1010
- - contenteditable fields not handled in config nodes Fixes #1011
+ - #1010 Searching package catalogue should be case-insensitive Fixes
+ - #1011 contenteditable fields not handled in config nodes Fixes
- Change html link refs from `_new` to `_blank` to be standards compliant
#### 0.15.0: Milestone Release
Runtime
- - Increase default apiMaxLength to 5mb and add to default settings Closes #1001
+ - #1001 Increase default apiMaxLength to 5mb and add to default settings Closes
- Add v2 /flows api and deploy-overwrite protection
- Encrypt credentials by default
- Ensure errors thrown by RED.events handlers don't percolate up
@@ -1457,7 +1511,7 @@ Editor
- Mark nodes as changed when they are moved
- Added parent containment option for draggable. (#1006)
- - Ignore bidi event handling on non-existent and non-Input elements Closes #999
+ - #999 Ignore bidi event handling on non-existent and non-Input elements Closes
- Remove list of flows from menu
- Allow nodes to be imported with their credentials
- Add workspace search option
@@ -1469,7 +1523,7 @@ Editor
- Add import-to-new-tab option
- Add new options to export-nodes dialog
- Stop nodes being added beyond the outer bounds of the workspace
- - Default config nodes to global scope unless in a subflow Closes #972
+ - #972 Default config nodes to global scope unless in a subflow Closes
- Bidi support for Text Direction and Structured Text (#961)
- Fix jQuery selector, selecting more than one help pane/popover and displaying incorrectly. (#970)
- Fixes removeItem not passing row data to callback. (#965)
@@ -1483,7 +1537,7 @@ Nodes
- Clean up status on close for several core nodes.
- Change node: re-parse JSON set value each time to avoid pass-by-ref
- Better handle HTTP Request header capitalisation
- - Enable ES6 parsing in Function editor by default Fixes #985
+ - #985 Enable ES6 parsing in Function editor by default Fixes
- Update debug sidebar to use RED.view.reveal to show debug nodes
- Add full path tip to file node, And tidy up Pi node tips
- Remove WebSocket node maxlistener warning
@@ -1502,7 +1556,7 @@ Nodes
Other
- - Add npm build/test scripts Closes #946 #660
+ - #660 Add npm build/test scripts Closes #946
- Move travis to node 6 and 7 - drop 5 and 0.12
@@ -1510,15 +1564,15 @@ Other
Fixes
- - Tell ace about Function node globals. Closes #927
- - Tidy up mqtt nodes - linting and done handling. Closes #935
+ - #927 Tell ace about Function node globals. Closes
+ - #935 Tidy up mqtt nodes - linting and done handling. Closes
- Fix invalid html in TCP and HTML node edit templates
- Add proper help text to link nodes
- Handle importing old mqtt-broker configs that lack properties
- Update ace to 1.2.4
- Allow config nodes to provide a sort function for their select list
- Add log warning if node module required version cannot be satisfied
- - Handle empty credentials file. Closes #937
+ - #937 Handle empty credentials file. Closes
- Add RPi.GPIO lib test for ArchLinux
#### 0.14.5: Maintenance Release
@@ -1528,8 +1582,8 @@ Fixes
- Cannot clear cookies with http nodes
- let HTML parse node allow msg.select set select
- Validate nodes on import after any references have been remapped
- - Debug node handles objects without constructor property Fixes #933
- - Ensure 'false' property values are displayed in info panel Fixes #940
+ - #933 Debug node handles objects without constructor property Fixes
+ - #940 Ensure 'false' property values are displayed in info panel Fixes
- Fix node enable/disable over restart - load configs after settings init
#### 0.14.4: Maintenance Release
@@ -1538,20 +1592,20 @@ Nodes
- Update trigger node ui to use typedInputs
- Better handling of quotes in CSV node
- - Clarify the MQTT node sends msg.payload - closes #929
- - Inject node should reuse the message it is triggered with Closes #914
+ - #929 Clarify the MQTT node sends msg.payload - closes
+ - #914 Inject node should reuse the message it is triggered with Closes
- Stop trigger node re-using old message
- Allow node.status text to be 'falsey' values
Fixes
- - Handle DOMException when embedded in an iframe of different origin Fixes #932
+ - #932 Handle DOMException when embedded in an iframe of different origin Fixes
- Fix double firing of menu actions
- - Fix select box handling in Safari - fixes #928
- - Clear context in node test helper Fixes #858
- - Allow node properties to be same as existing object functions Fixes #880
+ - #928 Fix select box handling in Safari - fixes
+ - #858 Clear context in node test helper Fixes
+ - #880 Allow node properties to be same as existing object functions Fixes
- Handle comms link closing whilst completing the initial connect
- - Protect against node type names that clash with Object property names Fixes #917
+ - #917 Protect against node type names that clash with Object property names Fixes
- Clone default node properties to avoid reference leakage
- Strip tab node definition when exporting
- Check for null config properties in editor before over-writing them
@@ -1561,16 +1615,16 @@ Editor
- Add sql mode to ace editor
- Keyboard shortcuts dialog update (#923)
- - Ensure importing link nodes to a subflow doesn't add outbound links Fixes #921
+ - #921 Ensure importing link nodes to a subflow doesn't add outbound links Fixes
- Add updateConfigNodeUsers function to editor
- Scroll to bottom when item added to editableList
- - Form input widths behave more consistently when resizing Fixes #919 #920
+ - #920 Form input widths behave more consistently when resizing Fixes #919
#### 0.14.3: Maintenance Release
Fixes
- - Create default setting.js in user-specified directory. Fixes #908
+ - #908 Create default setting.js in user-specified directory. Fixes
- MQTT In subscription qos not defaulting properly
- Let exec node handle 0 as well as "0"
@@ -1578,7 +1632,7 @@ Fixes
Fixes
- - Cannot add new twitter credentials. Fixes #913
+ - #913 Cannot add new twitter credentials. Fixes
- Support array references in Debug property field
#### 0.14.1: Maintenance Release
@@ -1586,8 +1640,8 @@ Fixes
Fixes
- Handle undefined property that led to missing wires in the editor
- - Remove duplicate 'Delete' entry in keyboard shortcut window. Closes #911
- - Add 'exec' to node-red-pi launch script. Closes #910
+ - #911 Remove duplicate 'Delete' entry in keyboard shortcut window. Closes
+ - #910 Add 'exec' to node-red-pi launch script. Closes
#### 0.14.0: Milestone Release
@@ -1609,9 +1663,9 @@ Editor
Runtime
- Always log node warnings on start without requiring -v
- - Add support for loading scoped node modules. Closes #885
+ - #885 Add support for loading scoped node modules. Closes
- Add process.env.PORT to settings.js
- - Clear node context on deploy. Closes #870
+ - #870 Clear node context on deploy. Closes
- Enable finer grained permissions in adminAuth
Nodes
@@ -1619,9 +1673,9 @@ Nodes
- Enable config nodes to reference other config nodes
- Add Split/Join nodes
- Add Link nodes
- - Add support to HTTP In node for PATCH requests. Closes #904
+ - #904 Add support to HTTP In node for PATCH requests. Closes
- Add cookie handling to HTTP In and HTTP Response nodes
- - Add repeat indicator to inject node label. Closes #887
+ - #887 Add repeat indicator to inject node label. Closes
- Add javascript highlighter to template node
- Add optional timeout to exec node
- Add TLS node and update MQTT/HTTP nodes to use it
@@ -1633,19 +1687,19 @@ Nodes
- Update Serial node to support custom baud rates
- Add support for array-syntax in typedInput msg properties
- Add RED.util to Function node sandbox
- - Capture error stack on node.error. Closes #879
+ - #879 Capture error stack on node.error. Closes
Fixes
- Add error handling to all node definition api calls
- Handle null return from Function node in array of messages
- - Defer loading of token sessions until they are accessed. Fixes #895
+ - #895 Defer loading of token sessions until they are accessed. Fixes
- set pi gpio pin status correctly if set on start
- - Prevent parent window scrolling when view is focused. Fixes #635
+ - #635 Prevent parent window scrolling when view is focused. Fixes
- Handle missing tab nodes in a loaded flow config
- Ensure typedInput dropdown doesn't fall off the page
- - Protect against node types with reserved names such as toString. Fixes #880
+ - #880 Protect against node types with reserved names such as toString. Fixes
- Do not rely on the HTML file to identify where nodes are registered from
- Preserve node properties on import
- Fix regression in delay node. topic based queue was emptying all the time instead of spreading out messages.
@@ -1661,22 +1715,22 @@ Fixes
#### 0.13.4: Maintenance Release
- Add timed release mode to delay node
- - Enable link splicing for when import_dragging nodes. Closes #811
+ - #811 Enable link splicing for when import_dragging nodes. Closes
- Fix uncaught exception on deploy whilst node sending messages
- Deprecate old mqtt client and connection pool modules
- - Change node: add bool/num types to change mode Closes #835
- - Validate fields that are `$(env-vars)` Closes #825
+ - #835 Change node: add bool/num types to change mode Closes
+ - #825 Validate fields that are `$(env-vars)` Closes
- Handle missing config nodes when validating node properties
- Pi node - don't try to send data if closing
- Load node message catalog when added dynamically
- Split palette labels on spaces and hyphens when laying out
- - Warn if editor routes are accessed but runtime not started Closes #816
- - Better handling of zero-length flow files Closes #819
+ - #816 Warn if editor routes are accessed but runtime not started Closes
+ - #819 Better handling of zero-length flow files Closes
- Allow runtime calls to RED._ to specify other namespace
- Better right alignment of numerics in delay and trigger nodes
- Allow node modules to include example flows
- Create node_modules in userDir
- - Ensure errors in node def functions don't break view rendering Fixes #815
+ - #815 Ensure errors in node def functions don't break view rendering Fixes
- Updated Inject node info with instructions for flow and global options
@@ -1700,13 +1754,13 @@ Fixes
- Make jquery spinner element css consistent with other inputs
- tcp node add reply (to all) capability
- Allow the template node to be treated as plain text
- - Validate MQTT In topics Fixes #792
- - httpNodeAuth should not block http options requests Fixes #793
+ - #792 Validate MQTT In topics Fixes
+ - #793 httpNodeAuth should not block http options requests Fixes
- Disable perMessageDeflate on WS servers - fixes 'zlib binding closed' error
- Clear trigger status icon on re-deploy
- Don't default inject payload to blank string
- Trigger node, add configurable reset
- - Allow function properties in settings Fixes #790 - fixes use of httpNodeMiddleware
+ - #790 - fixes use of httpNodeMiddleware Allow function properties in settings Fixes
- Fix order of config dialog calls to save/creds/validate
- Add debounce to Pi GPIO node
@@ -1722,7 +1776,7 @@ Fixes
- Add 'previous value' option to Switch node
- Allow existing nodes to splice into links on drag
- - CORS not properly configured on multiple http routes Fixes #783
+ - #783 CORS not properly configured on multiple http routes Fixes
- Restore shift-drag to snap/unsnap to grid
- Moving nodes with keyboard should flag workspace dirty
- Notifications flagged as fixed should not be click-closable
From 32aa4c41ce7e938878accebe17bdc4f9eb3ab609 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Thu, 27 Feb 2020 14:37:25 +0000
Subject: [PATCH 36/67] Bump for 1.0.4
---
package.json | 2 +-
.../node_modules/@node-red/editor-api/package.json | 6 +++---
.../node_modules/@node-red/editor-client/package.json | 2 +-
packages/node_modules/@node-red/nodes/package.json | 2 +-
packages/node_modules/@node-red/registry/package.json | 4 ++--
packages/node_modules/@node-red/runtime/package.json | 6 +++---
packages/node_modules/@node-red/util/package.json | 2 +-
packages/node_modules/node-red/package.json | 10 +++++-----
8 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/package.json b/package.json
index 335dddbb3..ca61f0e49 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red",
- "version": "1.0.3",
+ "version": "1.0.4",
"description": "Low-code programming for event-driven applications",
"homepage": "http://nodered.org",
"license": "Apache-2.0",
diff --git a/packages/node_modules/@node-red/editor-api/package.json b/packages/node_modules/@node-red/editor-api/package.json
index 81be91b6d..9866a81ad 100644
--- a/packages/node_modules/@node-red/editor-api/package.json
+++ b/packages/node_modules/@node-red/editor-api/package.json
@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-api",
- "version": "1.0.3",
+ "version": "1.0.4",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,8 +16,8 @@
}
],
"dependencies": {
- "@node-red/util": "1.0.3",
- "@node-red/editor-client": "1.0.3",
+ "@node-red/util": "1.0.4",
+ "@node-red/editor-client": "1.0.4",
"bcryptjs": "2.4.3",
"body-parser": "1.19.0",
"clone": "2.1.2",
diff --git a/packages/node_modules/@node-red/editor-client/package.json b/packages/node_modules/@node-red/editor-client/package.json
index 7f8061c6d..0b3e16e7f 100644
--- a/packages/node_modules/@node-red/editor-client/package.json
+++ b/packages/node_modules/@node-red/editor-client/package.json
@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-client",
- "version": "1.0.3",
+ "version": "1.0.4",
"license": "Apache-2.0",
"repository": {
"type": "git",
diff --git a/packages/node_modules/@node-red/nodes/package.json b/packages/node_modules/@node-red/nodes/package.json
index 1b707b95b..cf897dbb0 100644
--- a/packages/node_modules/@node-red/nodes/package.json
+++ b/packages/node_modules/@node-red/nodes/package.json
@@ -1,6 +1,6 @@
{
"name": "@node-red/nodes",
- "version": "1.0.3",
+ "version": "1.0.4",
"license": "Apache-2.0",
"repository": {
"type": "git",
diff --git a/packages/node_modules/@node-red/registry/package.json b/packages/node_modules/@node-red/registry/package.json
index c1ee06050..448c46861 100644
--- a/packages/node_modules/@node-red/registry/package.json
+++ b/packages/node_modules/@node-red/registry/package.json
@@ -1,6 +1,6 @@
{
"name": "@node-red/registry",
- "version": "1.0.3",
+ "version": "1.0.4",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,7 +16,7 @@
}
],
"dependencies": {
- "@node-red/util": "1.0.3",
+ "@node-red/util": "1.0.4",
"semver": "6.3.0",
"uglify-js": "3.8.0",
"when": "3.7.8"
diff --git a/packages/node_modules/@node-red/runtime/package.json b/packages/node_modules/@node-red/runtime/package.json
index 0d03b355b..50f9fb264 100644
--- a/packages/node_modules/@node-red/runtime/package.json
+++ b/packages/node_modules/@node-red/runtime/package.json
@@ -1,6 +1,6 @@
{
"name": "@node-red/runtime",
- "version": "1.0.3",
+ "version": "1.0.4",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,8 +16,8 @@
}
],
"dependencies": {
- "@node-red/registry": "1.0.3",
- "@node-red/util": "1.0.3",
+ "@node-red/registry": "1.0.4",
+ "@node-red/util": "1.0.4",
"clone": "2.1.2",
"express": "4.17.1",
"fs-extra": "8.1.0",
diff --git a/packages/node_modules/@node-red/util/package.json b/packages/node_modules/@node-red/util/package.json
index 9ad86f6c9..9beb6189b 100644
--- a/packages/node_modules/@node-red/util/package.json
+++ b/packages/node_modules/@node-red/util/package.json
@@ -1,6 +1,6 @@
{
"name": "@node-red/util",
- "version": "1.0.3",
+ "version": "1.0.4",
"license": "Apache-2.0",
"repository": {
"type": "git",
diff --git a/packages/node_modules/node-red/package.json b/packages/node_modules/node-red/package.json
index 618480400..2b7116f64 100644
--- a/packages/node_modules/node-red/package.json
+++ b/packages/node_modules/node-red/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red",
- "version": "1.0.3",
+ "version": "1.0.4",
"description": "Low-code programming for event-driven applications",
"homepage": "http://nodered.org",
"license": "Apache-2.0",
@@ -31,10 +31,10 @@
"flow"
],
"dependencies": {
- "@node-red/editor-api": "1.0.3",
- "@node-red/runtime": "1.0.3",
- "@node-red/util": "1.0.3",
- "@node-red/nodes": "1.0.3",
+ "@node-red/editor-api": "1.0.4",
+ "@node-red/runtime": "1.0.4",
+ "@node-red/util": "1.0.4",
+ "@node-red/nodes": "1.0.4",
"basic-auth": "2.0.1",
"bcryptjs": "2.4.3",
"express": "4.17.1",
From bd4fc2e5cc4337eded1913df390c1caed9721f35 Mon Sep 17 00:00:00 2001
From: Mauricio Bonani
Date: Sat, 29 Feb 2020 09:15:42 -0500
Subject: [PATCH 37/67] Fix workspace CSS properties syntax
---
.../@node-red/editor-client/src/sass/workspace.scss | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/workspace.scss b/packages/node_modules/@node-red/editor-client/src/sass/workspace.scss
index f6255eacf..2162cad8a 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/workspace.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/workspace.scss
@@ -112,7 +112,7 @@
position: absolute;
bottom: 0;
right:0;
- zIndex: 101;
+ z-index: 101;
border-left: 1px solid $primary-border-color;
border-top: 1px solid $primary-border-color;
background: $view-navigator-background;
@@ -122,7 +122,7 @@
stroke-dasharray: 5,5;
pointer-events: none;
stroke: $secondary-border-color;
- strokeWidth: 1;
+ stroke-width: 1;
fill: $view-background;
}
From 8a82552bdcdac22329763cf9a099523a3747b49c Mon Sep 17 00:00:00 2001
From: Mauricio Bonani
Date: Sat, 29 Feb 2020 15:14:57 -0500
Subject: [PATCH 38/67] Consolidate duplicates
---
.../@node-red/editor-client/src/sass/ace.scss | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/ace.scss b/packages/node_modules/@node-red/editor-client/src/sass/ace.scss
index fb6eaf8eb..adcaa3458 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/ace.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/ace.scss
@@ -9,19 +9,15 @@
color: transparent !important;
}
}
-
-
.ace_gutter {
+ background: $text-editor-gutter-background;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
.ace_scroller {
+ background: $text-editor-background;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
- }
-
- .ace_scroller {
- background: $text-editor-background;
color: $text-editor-color;
}
.ace_marker-layer .ace_active-line {
@@ -37,9 +33,6 @@
.ace_gutter-active-line {
background: $text-editor-gutter-active-line-background;
}
- .ace_gutter {
- background: $text-editor-gutter-background;
- }
.ace_tooltip {
font-family: $primary-font;
line-height: 1.4em;
From 491812fac5d524692bcb489b6e20890eb533f1ce Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Mon, 2 Mar 2020 05:07:48 +0000
Subject: [PATCH 39/67] Fix XPath in UI tests
---
test/editor/pageobjects/nodes/core/function/15-change_page.js | 2 +-
test/editor/pageobjects/nodes/core/parsers/70-JSON_page.js | 2 +-
test/editor/pageobjects/nodes/core/parsers/70-XML_page.js | 2 +-
test/editor/pageobjects/nodes/core/parsers/70-YAML_page.js | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/test/editor/pageobjects/nodes/core/function/15-change_page.js b/test/editor/pageobjects/nodes/core/function/15-change_page.js
index 59ac4f2f1..fab408718 100644
--- a/test/editor/pageobjects/nodes/core/function/15-change_page.js
+++ b/test/editor/pageobjects/nodes/core/function/15-change_page.js
@@ -85,7 +85,7 @@ changeNode.prototype.ruleMove = function (p, to, index) {
}
changeNode.prototype.addRule = function () {
- browser.clickWithWait('//*[@id="dialog-form"]/div[5]/div/a');
+ browser.clickWithWait('//div[contains(@class, "red-ui-editableList")]/a');
}
module.exports = changeNode;
diff --git a/test/editor/pageobjects/nodes/core/parsers/70-JSON_page.js b/test/editor/pageobjects/nodes/core/parsers/70-JSON_page.js
index 875c3b013..e0b31dd36 100644
--- a/test/editor/pageobjects/nodes/core/parsers/70-JSON_page.js
+++ b/test/editor/pageobjects/nodes/core/parsers/70-JSON_page.js
@@ -29,7 +29,7 @@ jsonNode.prototype.setAction = function (action) {
}
jsonNode.prototype.setProperty = function (property) {
- browser.setValue('//*[@id="dialog-form"]/div[4]/div/div[1]/input', property);
+ browser.setValue('//*[contains(@class, "red-ui-typedInput-container")]/div[1]/input', property);
}
module.exports = jsonNode;
diff --git a/test/editor/pageobjects/nodes/core/parsers/70-XML_page.js b/test/editor/pageobjects/nodes/core/parsers/70-XML_page.js
index 2a8be7d95..696ec59cb 100644
--- a/test/editor/pageobjects/nodes/core/parsers/70-XML_page.js
+++ b/test/editor/pageobjects/nodes/core/parsers/70-XML_page.js
@@ -29,7 +29,7 @@ xmlNode.prototype.setAction = function (action) {
}
xmlNode.prototype.setProperty = function (property) {
- browser.setValue('//*[@id="dialog-form"]/div[3]/div/div[1]/input', property);
+ browser.setValue('//*[contains(@class, "red-ui-typedInput-container")]/div[1]/input', property);
}
module.exports = xmlNode;
diff --git a/test/editor/pageobjects/nodes/core/parsers/70-YAML_page.js b/test/editor/pageobjects/nodes/core/parsers/70-YAML_page.js
index 16e4a678d..1002f3eb4 100644
--- a/test/editor/pageobjects/nodes/core/parsers/70-YAML_page.js
+++ b/test/editor/pageobjects/nodes/core/parsers/70-YAML_page.js
@@ -29,7 +29,7 @@ yamlNode.prototype.setAction = function (action) {
}
yamlNode.prototype.setProperty = function (property) {
- browser.setValue('//*[@id="dialog-form"]/div[3]/div/div[1]/input', property);
+ browser.setValue('//*[contains(@class, "red-ui-typedInput-container")]/div[1]/input', property);
}
module.exports = yamlNode;
From 5090b01b8e30093c8cab6d0c741034564d5e96b8 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Mon, 2 Mar 2020 19:50:39 +0000
Subject: [PATCH 40/67] Ensure join node handles missing buffer joiner when not
in string mode
and add tests
to close #2491
---
.../nodes/core/sequence/17-split.html | 4 +-
.../@node-red/nodes/core/sequence/17-split.js | 9 ++--
test/nodes/core/sequence/17-split_spec.js | 43 +++++++++++++++++++
3 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/sequence/17-split.html b/packages/node_modules/@node-red/nodes/core/sequence/17-split.html
index d730bb221..eccd33647 100644
--- a/packages/node_modules/@node-red/nodes/core/sequence/17-split.html
+++ b/packages/node_modules/@node-red/nodes/core/sequence/17-split.html
@@ -14,7 +14,7 @@
limitations under the License.
-->
-
-
diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
index e1d7c6368..bf476ab44 100755
--- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
@@ -455,7 +455,7 @@
"message": "entire message",
"tip": {
"path1": "By default, payload
will contain the data to be sent over, or received from a websocket. The listener can be configured to send or receive the entire message object as a JSON formatted string.",
- "path2": "This path will be relative to ",
+ "path2": "This path will be relative to __path__
.",
"url1": "URL should use ws:// or wss:// scheme and point to an existing websocket listener.",
"url2": "By default, payload
will contain the data to be sent over, or received from a websocket. The client can be configured to send or receive the entire message object as a JSON formatted string."
},
diff --git a/packages/node_modules/@node-red/nodes/locales/ja/messages.json b/packages/node_modules/@node-red/nodes/locales/ja/messages.json
index adc033390..4e728690b 100755
--- a/packages/node_modules/@node-red/nodes/locales/ja/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/ja/messages.json
@@ -455,7 +455,7 @@
"message": "メッセージ全体を送信/受信",
"tip": {
"path1": "標準では payload
がwebsocketから送信、受信されるデータを持ちます。クライアントはJSON形式の文字列としてメッセージ全体を送信、受信するよう設定できます。",
- "path2": "This path will be relative to ",
+ "path2": "このパスは __path__
の相対パスになります。",
"url1": "URLには ws:// または wss:// スキーマを使用して、存在するwebsocketリスナを設定してください。",
"url2": "標準では payload
がwebsocketから送信、受信されるデータを持ちます。クライアントはJSON形式の文字列としてメッセージ全体を送信、受信するよう設定できます。"
},
From fd2213232c936f93cdec17fabde6c33dd527f5c0 Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Fri, 13 Mar 2020 16:29:16 +0900
Subject: [PATCH 43/67] Update message catalogs for other languages
---
packages/node_modules/@node-red/nodes/locales/de/messages.json | 2 +-
packages/node_modules/@node-red/nodes/locales/ko/messages.json | 2 +-
.../node_modules/@node-red/nodes/locales/zh-CN/messages.json | 2 +-
.../node_modules/@node-red/nodes/locales/zh-TW/messages.json | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/locales/de/messages.json b/packages/node_modules/@node-red/nodes/locales/de/messages.json
index c36c309f3..58fce3a92 100755
--- a/packages/node_modules/@node-red/nodes/locales/de/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/de/messages.json
@@ -397,7 +397,7 @@
"message" : "gesamte Nachricht",
"tip" : {
"path1" : "Standardmäßig enthält Nutzdaten
die Daten, die über einen Websocket gesendet oder von einem Websocket empfangen werden. Der Listener kann so konfiguriert werden, dass er das gesamte Nachrichtenobjekt als eine JSON-formatierte Zeichenfolge sendet oder empfängt.",
- "path2" : "Dieser Pfad ist relativ zu ",
+ "path2" : "Dieser Pfad ist relativ zu __path__
.",
"url1" : "URL sollte ws: / & #47; oder wss: / & #47; Schema verwenden und auf einen vorhandenen Websocket-Listener verweisen.",
"url2" : "Standardmäßig enthält Nutzdaten
die Daten, die über einen Websocket gesendet oder von einem Websocket empfangen werden. Der Client kann so konfiguriert werden, dass er das gesamte Nachrichtenobjekt als eine JSON-formatierte Zeichenfolge sendet oder empfängt."
},
diff --git a/packages/node_modules/@node-red/nodes/locales/ko/messages.json b/packages/node_modules/@node-red/nodes/locales/ko/messages.json
index d87b2c0f5..8e3a4f325 100755
--- a/packages/node_modules/@node-red/nodes/locales/ko/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/ko/messages.json
@@ -446,7 +446,7 @@
"message": "메세지 전체를 송신/수신",
"tip": {
"path1": "표준으로는 payload
가 websocket에서 송신, 수신된 데이터를 기다립니다. 클라이언트는 JSON형식의 문자열로 메세지전체를 송신, 수신하도록 설정할 수 있습니다.",
- "path2": "This path will be relative to ",
+ "path2": "This path will be relative to __path__
.",
"url1": "URL에는 ws:// 또는 wss:// 스키마를 사용하여, 존재하는 websocket리스너를 설정해 주세요.",
"url2": "표준으로는 payload
가 websocket에서 송신,수신될 데이터를 기다립니다.클라이언트는 JSON형식의 문자열로 메세지전체를 송신, 수신하도록 설정할 수 있습니다."
},
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json b/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json
index 4fc5dc4d4..934cc734d 100644
--- a/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json
@@ -455,7 +455,7 @@
"message": "完整信息",
"tip": {
"path1": "默认情况下,payload
将包含要发送或从Websocket接收的数据。侦听器可以配置为以JSON格式的字符串发送或接收整个消息对象.",
- "path2": "这条路径将相对于 ",
+ "path2": "这条路径将相对于 __path__
.",
"url1": "URL 应该使用ws://或者wss://方案并指向现有的websocket侦听器.",
"url2": "默认情况下,payload
将包含要发送或从Websocket接收的数据。可以将客户端配置为以JSON格式的字符串发送或接收整个消息对象."
},
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json b/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json
index 7ece3333d..5368bb993 100644
--- a/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json
@@ -455,7 +455,7 @@
"message": "完整資訊",
"tip": {
"path1": "預設情況下,payload
將包含要發送或從Websocket接收的資料。偵聽器可以配置為以JSON格式的字串發送或接收整個消息物件.",
- "path2": "這條路徑將相對於 ",
+ "path2": "這條路徑將相對於 __path__
.",
"url1": "URL 應該使用ws://或者wss://方案並指向現有的websocket監聽器.",
"url2": "預設情況下,payload
將包含要發送或從Websocket接收的資料。可以將使用者端配置為以JSON格式的字串發送或接收整個消息物件."
},
From 72126730efb4439d474f61d6077903f9989bfc0e Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Fri, 13 Mar 2020 16:32:00 +0900
Subject: [PATCH 44/67] Remove unnecessary code for node property of websocket
node in the German language
---
.../locales/de/network/22-websocket.html | 24 -------------------
1 file changed, 24 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/locales/de/network/22-websocket.html b/packages/node_modules/@node-red/nodes/locales/de/network/22-websocket.html
index 5aa5cf884..26cc078ae 100755
--- a/packages/node_modules/@node-red/nodes/locales/de/network/22-websocket.html
+++ b/packages/node_modules/@node-red/nodes/locales/de/network/22-websocket.html
@@ -37,30 +37,6 @@
Dieser Konfigurations-Node erstellt einen WebSocket Server-Endpunkt unter Verwendung des angegebenen Pfades.
-
-
-
From 9ba9998bd6fd87443d849a17fddb6df8cff66275 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 13 Mar 2020 11:26:49 +0000
Subject: [PATCH 45/67] make exec node logging consistent with itself. (only be
verbose when in verbose mode)
---
packages/node_modules/@node-red/nodes/core/function/90-exec.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/node_modules/@node-red/nodes/core/function/90-exec.js b/packages/node_modules/@node-red/nodes/core/function/90-exec.js
index a5132230e..f5e7edd87 100644
--- a/packages/node_modules/@node-red/nodes/core/function/90-exec.js
+++ b/packages/node_modules/@node-red/nodes/core/function/90-exec.js
@@ -145,7 +145,7 @@ module.exports = function(RED) {
if (error.signal) { msg3.payload.signal = error.signal; }
if (error.code === null) { node.status({fill:"red",shape:"dot",text:"killed"}); }
else { node.status({fill:"red",shape:"dot",text:"error:"+error.code}); }
- node.log('error:' + error);
+ if (RED.settings.verbose) { node.log('error:' + error); }
}
else if (node.oldrc === "false") {
msg3 = RED.util.cloneMessage(msg);
From b165129388f37f2f8b873016c1cc346b9aaf0185 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 13 Mar 2020 11:28:19 +0000
Subject: [PATCH 46/67] Remove old leagcy wording from file node info to stop
confusing users.
---
.../@node-red/nodes/core/storage/10-file.html | 4 ++--
.../nodes/locales/en-US/storage/10-file.html | 15 ++-------------
2 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/storage/10-file.html b/packages/node_modules/@node-red/nodes/core/storage/10-file.html
index d20ad75c5..5487920b8 100755
--- a/packages/node_modules/@node-red/nodes/core/storage/10-file.html
+++ b/packages/node_modules/@node-red/nodes/core/storage/10-file.html
@@ -1,5 +1,5 @@
-
-
-
From 09d55a0cbdff545f59138c232163283dfe0fde65 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 13 Mar 2020 11:33:37 +0000
Subject: [PATCH 47/67] remove unneeded title line from file info text
---
.../@node-red/nodes/locales/en-US/storage/10-file.html | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/storage/10-file.html b/packages/node_modules/@node-red/nodes/locales/en-US/storage/10-file.html
index f25ce0292..fe2bbc324 100644
--- a/packages/node_modules/@node-red/nodes/locales/en-US/storage/10-file.html
+++ b/packages/node_modules/@node-red/nodes/locales/en-US/storage/10-file.html
@@ -49,7 +49,6 @@
The contents of the file as either a string or binary buffer.
filename string
If not configured in the node, this optional property sets the name of the file to be read.
- error object
Details
The filename should be an absolute path, otherwise it will be relative to
From a9508a2c0402e055011d48d28e5df3bb353269eb Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Fri, 13 Mar 2020 21:31:16 +0900
Subject: [PATCH 48/67] Remove old leagcy wording from file node info
(Japanese)
---
.../@node-red/nodes/locales/ja/storage/10-file.html | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/locales/ja/storage/10-file.html b/packages/node_modules/@node-red/nodes/locales/ja/storage/10-file.html
index 2df174104..21d4af9be 100644
--- a/packages/node_modules/@node-red/nodes/locales/ja/storage/10-file.html
+++ b/packages/node_modules/@node-red/nodes/locales/ja/storage/10-file.html
@@ -14,7 +14,7 @@
limitations under the License.
-->
-
-
From c700d5c922af369680c27248c8da2863c2c75e63 Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Fri, 13 Mar 2020 21:38:23 +0900
Subject: [PATCH 49/67] Remove old leagcy wording from file node info (Chinese)
---
.../@node-red/nodes/locales/zh-CN/storage/10-file.html | 8 ++------
.../@node-red/nodes/locales/zh-TW/storage/10-file.html | 8 ++------
2 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-CN/storage/10-file.html b/packages/node_modules/@node-red/nodes/locales/zh-CN/storage/10-file.html
index 4ec78cdb4..eb38a5235 100644
--- a/packages/node_modules/@node-red/nodes/locales/zh-CN/storage/10-file.html
+++ b/packages/node_modules/@node-red/nodes/locales/zh-CN/storage/10-file.html
@@ -14,7 +14,7 @@
limitations under the License.
-->
-
-
diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/10-file.html b/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/10-file.html
index 03705ea5c..ce2531137 100644
--- a/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/10-file.html
+++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/storage/10-file.html
@@ -14,7 +14,7 @@
limitations under the License.
-->
-
-
From 4c78f06c2b639f8f7eb9edcfe3f31a7d296cce2b Mon Sep 17 00:00:00 2001
From: Mauricio Bonani
Date: Fri, 13 Mar 2020 08:44:56 -0400
Subject: [PATCH 50/67] Fix paletteCategories order
---
packages/node_modules/node-red/settings.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/node_modules/node-red/settings.js b/packages/node_modules/node-red/settings.js
index 960cb6d17..c5e4355e1 100644
--- a/packages/node_modules/node-red/settings.js
+++ b/packages/node_modules/node-red/settings.js
@@ -243,7 +243,7 @@ module.exports = {
// palette. If a node's category is not in the list, the category will get
// added to the end of the palette.
// If not set, the following default order is used:
- //paletteCategories: ['subflows','flow','input','output','function','parser','social','mobile','storage','analysis','advanced'],
+ //paletteCategories: ['subflows', 'common', 'function', 'network', 'sequence', 'parser', 'storage'],
// Configure the logging output
logging: {
From 20f97d0d136310a994b185b0de13ea6da88b9904 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Fri, 13 Mar 2020 13:09:47 +0000
Subject: [PATCH 51/67] Add better handling of host-key-verify error with
projects
---
.../editor-client/locales/en-US/editor.json | 3 +-
.../src/js/ui/projects/projects.js | 171 ++++++++++--------
.../localfilesystem/projects/git/index.js | 6 +-
3 files changed, 101 insertions(+), 79 deletions(-)
diff --git a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json
index a5f232aa6..ed4d4f9a6 100755
--- a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json
+++ b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json
@@ -977,7 +977,8 @@
"passphrase": "Passphrase",
"retry": "Retry",
"update-failed": "Failed to update auth",
- "unhandled": "Unhandled error response"
+ "unhandled": "Unhandled error response",
+ "host-key-verify-failed": "Host key verification failed.
The repository host key could not be verified. Please update your known_hosts
file and try again."
},
"create-branch-list": {
"invalid": "Invalid branch",
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js b/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js
index 0c297c82a..da54a81c8 100755
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js
@@ -1939,100 +1939,121 @@ RED.projects = (function() {
}
}).fail(function(xhr,textStatus,err) {
var responses;
+
if (options.responses && options.responses[xhr.status]) {
responses = options.responses[xhr.status];
if (typeof responses === 'function') {
resultCallback = responses;
resultCallbackArgs = {error:responses.statusText};
return;
- } else if (options.handleAuthFail !== false && xhr.responseJSON.code === 'git_auth_failed') {
- var url = activeProject.git.remotes[xhr.responseJSON.remote||options.remote||'origin'].fetch;
+ } else if (options.handleAuthFail !== false && (xhr.responseJSON.code === 'git_auth_failed' || xhr.responseJSON.code === 'git_host_key_verification_failed')) {
+ if (xhr.responseJSON.code === 'git_auth_failed') {
+ var url = activeProject.git.remotes[xhr.responseJSON.remote||options.remote||'origin'].fetch;
- var message = $('
'+
+ var message = $('
'+
'
'+RED._("projects.send-req.auth-req")+':
'+
'
'+
'
');
- var isSSH = false;
- if (/^https?:\/\//.test(url)) {
- $('
'+RED._("projects.send-req.username")+'
'+
- '
'+RED._("projects.send-req.password")+'
').appendTo(message);
- } else if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(url)) {
- isSSH = true;
- var row = $('
').appendTo(message);
- $('
SSH Key ').appendTo(row);
- var projectRepoSSHKeySelect = $('
').width('70%').appendTo(row);
- $.getJSON("settings/user/keys", function(data) {
- var count = 0;
- data.keys.forEach(function(key) {
- projectRepoSSHKeySelect.append($(" ").val(key.name).text(key.name));
- count++;
+ var isSSH = false;
+ if (/^https?:\/\//.test(url)) {
+ $(''+RED._("projects.send-req.username")+'
'+
+ ''+RED._("projects.send-req.password")+'
').appendTo(message);
+ } else if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(url)) {
+ isSSH = true;
+ var row = $('
').appendTo(message);
+ $('SSH Key ').appendTo(row);
+ var projectRepoSSHKeySelect = $('').width('70%').appendTo(row);
+ $.getJSON("settings/user/keys", function(data) {
+ var count = 0;
+ data.keys.forEach(function(key) {
+ projectRepoSSHKeySelect.append($(" ").val(key.name).text(key.name));
+ count++;
+ });
+ if (count === 0) {
+ //TODO: handle no keys yet setup
+ }
});
- if (count === 0) {
- //TODO: handle no keys yet setup
- }
- });
- row = $('
').appendTo(message);
- $(''+RED._("projects.send-req.passphrase")+' ').appendTo(row);
- $(' ').appendTo(row);
- }
+ row = $('
').appendTo(message);
+ $(''+RED._("projects.send-req.passphrase")+' ').appendTo(row);
+ $(' ').appendTo(row);
+ }
- var notification = RED.notify(message,{
- type:"error",
- fixed: true,
- modal: true,
- buttons: [
- {
- //id: "node-dialog-delete",
- //class: 'leftButton',
- text: RED._("common.label.cancel"),
- click: function() {
- notification.close();
- }
- },{
- text: ' ' +RED._("projects.send-req.retry") +' ',
- click: function() {
- body = body || {};
- var authBody = {};
- if (isSSH) {
- authBody.keyFile = $('#projects-user-auth-key').val();
- authBody.passphrase = $('#projects-user-auth-passphrase').val();
- } else {
- authBody.username = $('#projects-user-auth-username').val();
- authBody.password = $('#projects-user-auth-password').val();
+ var notification = RED.notify(message,{
+ type:"error",
+ fixed: true,
+ modal: true,
+ buttons: [
+ {
+ //id: "node-dialog-delete",
+ //class: 'leftButton',
+ text: RED._("common.label.cancel"),
+ click: function() {
+ notification.close();
}
- var done = function(err) {
- if (err) {
- console.log(RED._("projects.send-req.update-failed"));
- console.log(err);
+ },{
+ text: ' ' +RED._("projects.send-req.retry") +' ',
+ click: function() {
+ body = body || {};
+ var authBody = {};
+ if (isSSH) {
+ authBody.keyFile = $('#projects-user-auth-key').val();
+ authBody.passphrase = $('#projects-user-auth-passphrase').val();
} else {
- sendRequest(options,body);
- notification.close();
+ authBody.username = $('#projects-user-auth-username').val();
+ authBody.password = $('#projects-user-auth-password').val();
}
+ var done = function(err) {
+ if (err) {
+ console.log(RED._("projects.send-req.update-failed"));
+ console.log(err);
+ } else {
+ sendRequest(options,body);
+ notification.close();
+ }
- }
- sendRequest({
- url: "projects/"+activeProject.name+"/remotes/"+(xhr.responseJSON.remote||options.remote||'origin'),
- type: "PUT",
- responses: {
- 0: function(error) {
- done(error,null);
- },
- 200: function(data) {
- done(null,data);
- },
- 400: {
- 'unexpected_error': function(error) {
- done(error,null);
- }
- },
}
- },{auth:authBody});
+ sendRequest({
+ url: "projects/"+activeProject.name+"/remotes/"+(xhr.responseJSON.remote||options.remote||'origin'),
+ type: "PUT",
+ responses: {
+ 0: function(error) {
+ done(error,null);
+ },
+ 200: function(data) {
+ done(null,data);
+ },
+ 400: {
+ 'unexpected_error': function(error) {
+ done(error,null);
+ }
+ },
+ }
+ },{auth:authBody});
+ }
}
- }
- ]
- });
- return;
+ ]
+ });
+ return;
+ } else if (xhr.responseJSON.code === 'git_host_key_verification_failed') {
+ var message = $(''+
+ '
'+RED._("projects.send-req.host-key-verify-failed")+'
'+
+ '
');
+ var notification = RED.notify(message,{
+ type:"error",
+ fixed: true,
+ modal: true,
+ buttons: [
+ {
+ text: RED._("common.label.close"),
+ click: function() {
+ notification.close();
+ }
+ }
+ ]
+ });
+ return;
+ }
} else if (responses[xhr.responseJSON.code]) {
resultCallback = responses[xhr.responseJSON.code];
resultCallbackArgs = xhr.responseJSON;
diff --git a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/index.js b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/index.js
index b9f114698..d812c05f2 100644
--- a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/index.js
+++ b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/index.js
@@ -41,6 +41,9 @@ function runGitCommand(args,cwd,env,emit) {
err.code = "git_connection_failed";
} else if (/Connection timed out/i.test(stderr)) {
err.code = "git_connection_failed";
+ } else if(/Host key verification failed/i.test(stderr)) {
+ // TODO: handle host key verification errors separately
+ err.code = "git_host_key_verification_failed";
} else if (/fatal: could not read/i.test(stderr)) {
// Username/Password
err.code = "git_auth_failed";
@@ -48,9 +51,6 @@ function runGitCommand(args,cwd,env,emit) {
err.code = "git_auth_failed";
} else if(/Permission denied \(publickey\)/i.test(stderr)) {
err.code = "git_auth_failed";
- } else if(/Host key verification failed/i.test(stderr)) {
- // TODO: handle host key verification errors separately
- err.code = "git_auth_failed";
} else if (/commit your changes or stash/i.test(stderr)) {
err.code = "git_local_overwrite";
} else if (/CONFLICT/.test(err.stdout)) {
From 421b5846f2f93b24699e86d001d93b4520e89f17 Mon Sep 17 00:00:00 2001
From: Kazuhito Yokoi
Date: Fri, 13 Mar 2020 22:20:16 +0900
Subject: [PATCH 52/67] Add page objects for UI testing (#2501)
* Update page object of change node
* Support multiple node outputs in UI testing
* Add page object of switch node
* Add page objects of trigger and exec nodes
* Remove unnecessary code
* Update page object of trigger node to select time unit
* Add page objects of websocket nodes
* Support boolean as value in selectWithWait()
* Update page object of split node
* Merge page objects of mqtt nodes to make them same as original mqtt node file path
---
.../editor/pageobjects/editor/palette_page.js | 5 +
.../nodes/core/common/21-debug_page.js | 2 -
.../nodes/core/function/10-switch_page.js | 234 ++++++++++++++++++
.../nodes/core/function/15-change_page.js | 67 ++++-
.../nodes/core/function/89-delay_page.js | 2 -
.../nodes/core/function/89-trigger_page.js | 83 +++++++
.../90-exec_page.js} | 16 +-
...{10-mqttconfig_page.js => 10-mqtt_page.js} | 52 +++-
.../nodes/core/network/10-mqttout_page.js | 35 ---
.../nodes/core/network/22-websocket_page.js | 93 +++++++
.../nodes/core/sequence/17-split_page.js | 16 +-
test/editor/pageobjects/nodes/node_page.js | 7 +-
.../pageobjects/nodes/nodefactory_page.js | 18 +-
test/editor/pageobjects/util/util_page.js | 2 +-
.../scenario/cookbook_messages_uispec.js | 2 +-
.../specs/scenario/cookbook_mqtt_uispec.js | 7 +-
16 files changed, 558 insertions(+), 83 deletions(-)
create mode 100644 test/editor/pageobjects/nodes/core/function/10-switch_page.js
create mode 100644 test/editor/pageobjects/nodes/core/function/89-trigger_page.js
rename test/editor/pageobjects/nodes/core/{network/10-mqttin_page.js => function/90-exec_page.js} (66%)
rename test/editor/pageobjects/nodes/core/network/{10-mqttconfig_page.js => 10-mqtt_page.js} (52%)
delete mode 100644 test/editor/pageobjects/nodes/core/network/10-mqttout_page.js
create mode 100644 test/editor/pageobjects/nodes/core/network/22-websocket_page.js
diff --git a/test/editor/pageobjects/editor/palette_page.js b/test/editor/pageobjects/editor/palette_page.js
index 6af0b5271..3b484a58c 100644
--- a/test/editor/pageobjects/editor/palette_page.js
+++ b/test/editor/pageobjects/editor/palette_page.js
@@ -24,16 +24,21 @@ var idMap = {
"comment": ".red-ui-palette-node[data-palette-type='comment']",
// function
"function": ".red-ui-palette-node[data-palette-type='function']",
+ "switch": ".red-ui-palette-node[data-palette-type='switch']",
"change": ".red-ui-palette-node[data-palette-type='change']",
"range": ".red-ui-palette-node[data-palette-type='range']",
"template": ".red-ui-palette-node[data-palette-type='template']",
"delay": ".red-ui-palette-node[data-palette-type='delay']",
+ "trigger": ".red-ui-palette-node[data-palette-type='trigger']",
+ "exec": ".red-ui-palette-node[data-palette-type='exec']",
// network
"mqttIn": ".red-ui-palette-node[data-palette-type='mqtt in']",
"mqttOut": ".red-ui-palette-node[data-palette-type='mqtt out']",
"httpIn": ".red-ui-palette-node[data-palette-type='http in']",
"httpResponse": ".red-ui-palette-node[data-palette-type='http response']",
"httpRequest": ".red-ui-palette-node[data-palette-type='http request']",
+ "websocketIn": ".red-ui-palette-node[data-palette-type='websocket in']",
+ "websocketOut": ".red-ui-palette-node[data-palette-type='websocket out']",
// sequence
"split": ".red-ui-palette-node[data-palette-type='split']",
"join": ".red-ui-palette-node[data-palette-type='join']",
diff --git a/test/editor/pageobjects/nodes/core/common/21-debug_page.js b/test/editor/pageobjects/nodes/core/common/21-debug_page.js
index 56854b195..990ed6cd9 100644
--- a/test/editor/pageobjects/nodes/core/common/21-debug_page.js
+++ b/test/editor/pageobjects/nodes/core/common/21-debug_page.js
@@ -18,8 +18,6 @@ var util = require("util");
var nodePage = require("../../node_page");
-var keyPage = require("../../../util/key_page");
-
function debugNode(id) {
nodePage.call(this, id);
}
diff --git a/test/editor/pageobjects/nodes/core/function/10-switch_page.js b/test/editor/pageobjects/nodes/core/function/10-switch_page.js
new file mode 100644
index 000000000..a04014063
--- /dev/null
+++ b/test/editor/pageobjects/nodes/core/function/10-switch_page.js
@@ -0,0 +1,234 @@
+/**
+ * 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 nodePage = require('../../node_page');
+
+function switchNode(id) {
+ nodePage.call(this, id);
+}
+
+util.inherits(switchNode, nodePage);
+
+var vtType = {
+ "msg": 1,
+ "flow": 2,
+ "global": 3,
+ "str": 4,
+ "num": 5,
+ "jsonata": 6,
+ "env": 7,
+ "prev": 8
+};
+
+function setT(t, index) {
+ browser.selectWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/select', t);
+}
+
+function setV(v, vt, index) {
+ if (vt) {
+ browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + vtType[vt] + ']');
+ }
+ if (v) {
+ browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', v);
+ }
+}
+
+function setBetweenV(v, vt, v2, v2t, index) {
+ if (vt) {
+ browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + vtType[vt] + ']');
+ }
+ if (v) {
+ browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/div[1]/input', v);
+ }
+ if (v2t) {
+ browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + vtType[v2t] + ']');
+ }
+ if (v2) {
+ browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div/div[1]/input', v2);
+ }
+}
+
+function setSequenceV(v, vt, index) {
+ var sType = {
+ "flow": 1,
+ "global": 2,
+ "num": 3,
+ "jsonata": 4,
+ "env": 5,
+ };
+
+ if (vt) {
+ browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + sType[vt] + ']');
+ }
+ if (v) {
+ browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/div[1]/input', v);
+ }
+}
+
+switchNode.prototype.ruleEqual = function (v, vt, index) {
+ index = index || 1;
+ setT('eq', index);
+ setV(v, vt, index);
+}
+
+switchNode.prototype.ruleNotEqual = function (v, vt, index) {
+ index = index || 1;
+ setT('neq', index);
+ setV(v, vt, index);
+}
+
+switchNode.prototype.ruleLessThan = function (v, vt, index) {
+ index = index || 1;
+ setT('lt', index);
+ setV(v, vt, index);
+}
+
+switchNode.prototype.ruleLessThanOrEqual = function (v, vt, index) {
+ index = index || 1;
+ setT('lte', index);
+ setV(v, vt, index);
+}
+
+switchNode.prototype.ruleGreaterThan = function (v, vt, index) {
+ index = index || 1;
+ setT('gt', index);
+ setV(v, vt, index);
+}
+
+switchNode.prototype.ruleGreaterThanOrEqual = function (v, vt, index) {
+ index = index || 1;
+ setT('gte', index);
+ setV(v, vt, index);
+}
+
+switchNode.prototype.ruleHasKey = function (v, vt, index) {
+ index = index || 1;
+ setT('hask', index);
+ setV(v, vt, index);
+}
+
+switchNode.prototype.ruleIsBetween = function (v, vt, v2, v2t, index) {
+ index = index || 1;
+ setT('btwn', index);
+ setBetweenV(v, vt, v2, v2t, index);
+}
+
+switchNode.prototype.ruleContains = function (v, vt, index) {
+ index = index || 1;
+ setT('cont', index);
+ setV(v, vt, index);
+}
+
+switchNode.prototype.ruleMatchesRegex = function (v, vt, index) {
+ index = index || 1;
+ setT('regex', index);
+ setV(v, vt, index);
+}
+
+switchNode.prototype.ruleIsTrue = function (index) {
+ index = index || 1;
+ setT('true', index);
+}
+
+switchNode.prototype.ruleIsFalse = function (index) {
+ index = index || 1;
+ setT('false', index);
+}
+
+switchNode.prototype.ruleIsNull = function (index) {
+ index = index || 1;
+ setT('null', index);
+}
+
+switchNode.prototype.ruleIsNotNull = function (index) {
+ index = index || 1;
+ setT('nnull', index);
+}
+
+switchNode.prototype.ruleIsOfType = function (t, index) {
+ index = index || 1;
+ setT('istype', index);
+
+ var tType = {
+ "str": 1,
+ "num": 2,
+ "boolean": 3,
+ "array": 4,
+ "buffer": 5,
+ "object": 6,
+ "json": 7,
+ "undefined": 8,
+ "null": 9
+ };
+
+ if (t) {
+ browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + tType[t] + ']');
+ }
+}
+
+switchNode.prototype.ruleIsEmpty = function (index) {
+ index = index || 1;
+ setT('empty', index);
+}
+
+switchNode.prototype.ruleIsNotEmpty = function (index) {
+ index = index || 1;
+ setT('nempty', index);
+}
+
+switchNode.prototype.ruleHead = function (v, vt, index) {
+ index = index || 1;
+ setT('head', index);
+ setSequenceV(v, vt, index);
+}
+
+switchNode.prototype.ruleIndexBetween = function (v, vt, v2, v2t, index) {
+ index = index || 1;
+ setT('index', index);
+ setBetweenV(v, vt, v2, v2t, index);
+}
+
+switchNode.prototype.ruleTail = function (v, vt, index) {
+ index = index || 1;
+ setT('tail', index);
+ setSequenceV(v, vt, index);
+}
+
+switchNode.prototype.ruleJSONataExp = function (v, index) {
+ index = index || 1;
+ setT('jsonata_exp', index);
+ if (v) {
+ browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div[2]/div[1]/input', v);
+ }
+}
+
+switchNode.prototype.ruleOtherwise = function (index) {
+ index = index || 1;
+ setT('else', index);
+}
+
+switchNode.prototype.addRule = function () {
+ browser.clickWithWait('//div[contains(@class, "red-ui-editableList")]/a');
+}
+
+module.exports = switchNode;
diff --git a/test/editor/pageobjects/nodes/core/function/15-change_page.js b/test/editor/pageobjects/nodes/core/function/15-change_page.js
index fab408718..eb26f48aa 100644
--- a/test/editor/pageobjects/nodes/core/function/15-change_page.js
+++ b/test/editor/pageobjects/nodes/core/function/15-change_page.js
@@ -51,37 +51,78 @@ function setT(t, index) {
// It is better to create a function whose input value is the object type in the future,
changeNode.prototype.ruleSet = function (p, pt, to, tot, index) {
index = index || 1;
- setT("set", index);
+ setT('set', index);
if (pt) {
browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/button[1]');
- var num = 5 * (index - 1) + 1;
- var ptXPath = '//div[contains(@class, "red-ui-typedInput-options")][' + num + ']/a[' + ptType[pt] + ']';
- browser.clickWithWait(ptXPath);
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + ptType[pt] + ']');
}
if (p) {
browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', p);
}
if (tot) {
browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[2]/div[2]/button[1]');
- var num = 5 * (index - 1) + 2;
- var totXPath = '//div[contains(@class, "red-ui-typedInput-options")][' + num + ']/a[' + totType[tot] + ']';
- browser.clickWithWait(totXPath);
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + totType[tot] + ']');
}
if (to) {
browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[2]/div[2]/div/input', to);
}
}
-changeNode.prototype.ruleDelete = function (index) {
+changeNode.prototype.ruleChange = function (p, pt, from, fromt, to, tot, index) {
index = index || 1;
- setT("delete", index);
+ setT('change', index);
+ if (pt) {
+ browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + ptType[pt] + ']');
+ }
+ if (p) {
+ browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', p);
+ }
+ if (fromt) {
+ browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div[1]/div[2]/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + totType[pt] + ']');
+ }
+ if (from) {
+ browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div[1]/div[2]/div[1]/input', from);
+ }
+ if (tot) {
+ browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div[2]/div[2]/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + totType[pt] + ']');
+ }
+ if (to) {
+ browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[3]/div[2]/div[2]/div[1]/input', to);
+ }
}
-changeNode.prototype.ruleMove = function (p, to, index) {
+changeNode.prototype.ruleDelete = function (p, pt, index) {
index = index || 1;
- setT("move", index);
- browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', p);
- browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[4]/div[2]/div/input', to);
+ setT('delete', index);
+ if (pt) {
+ browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + ptType[pt] + ']');
+ }
+ if (p) {
+ browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', p);
+ }
+}
+
+changeNode.prototype.ruleMove = function (p, pt, to, tot, index) {
+ index = index || 1;
+ setT('move', index);
+ if (pt) {
+ browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + ptType[pt] + ']');
+ }
+ if (p) {
+ browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[1]/div/div/input', p);
+ }
+ if (tot) {
+ browser.clickWithWait('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[4]/div[2]/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + totType[pt] + ']');
+ }
+ if (to) {
+ browser.setValue('//*[@id="node-input-rule-container"]/li[' + index + ']/div/div[4]/div[2]/div/input', to);
+ }
}
changeNode.prototype.addRule = function () {
diff --git a/test/editor/pageobjects/nodes/core/function/89-delay_page.js b/test/editor/pageobjects/nodes/core/function/89-delay_page.js
index a4e2197e4..3604beb67 100644
--- a/test/editor/pageobjects/nodes/core/function/89-delay_page.js
+++ b/test/editor/pageobjects/nodes/core/function/89-delay_page.js
@@ -18,8 +18,6 @@ var util = require("util");
var nodePage = require("../../node_page");
-var keyPage = require("../../../util/key_page");
-
function delayNode(id) {
nodePage.call(this, id);
}
diff --git a/test/editor/pageobjects/nodes/core/function/89-trigger_page.js b/test/editor/pageobjects/nodes/core/function/89-trigger_page.js
new file mode 100644
index 000000000..5d24de380
--- /dev/null
+++ b/test/editor/pageobjects/nodes/core/function/89-trigger_page.js
@@ -0,0 +1,83 @@
+/**
+ * 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 nodePage = require("../../node_page");
+
+function triggerNode(id) {
+ nodePage.call(this, id);
+}
+
+util.inherits(triggerNode, nodePage);
+
+triggerNode.prototype.setSend = function (send, sendt) {
+ var sendType = {
+ "flow": 1,
+ "global": 2,
+ "str": 3,
+ "num": 4,
+ "bool": 5,
+ "json": 6,
+ "bin": 7,
+ "date": 8,
+ "env": 9,
+ "pay": 10,
+ "nul": 11
+ };
+
+ if (sendt) {
+ browser.clickWithWait('//*[@id="dialog-form"]/div[1]/div/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + sendType[sendt] + ']');
+ }
+ if (send) {
+ browser.setValue('//*[@id="dialog-form"]/div[1]/div/div[1]/input', send);
+ }
+}
+
+triggerNode.prototype.setDuration = function (duration, units) {
+ browser.setValue('//*[@id="node-input-duration"]', duration);
+ if (units) {
+ browser.selectWithWait('//*[@id="node-input-units"]', units);
+ }
+}
+
+triggerNode.prototype.setThenSend = function (thenSend, thenSendt) {
+ var thenSendType = {
+ "flow": 1,
+ "global": 2,
+ "str": 3,
+ "num": 4,
+ "bool": 5,
+ "json": 6,
+ "bin": 7,
+ "date": 8,
+ "env": 9,
+ "pay": 10,
+ "payl": 11,
+ "nul": 12
+ };
+
+ if (thenSendt) {
+ browser.clickWithWait('//*[@id="dialog-form"]/div[5]/div/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + thenSendType[thenSendt] + ']');
+ }
+ if (thenSend) {
+ browser.setValue('//*[@id="dialog-form"]/div[5]/div/div[1]/input', thenSend);
+ }
+}
+
+module.exports = triggerNode;
diff --git a/test/editor/pageobjects/nodes/core/network/10-mqttin_page.js b/test/editor/pageobjects/nodes/core/function/90-exec_page.js
similarity index 66%
rename from test/editor/pageobjects/nodes/core/network/10-mqttin_page.js
rename to test/editor/pageobjects/nodes/core/function/90-exec_page.js
index 31b909116..69b8b6c9a 100644
--- a/test/editor/pageobjects/nodes/core/network/10-mqttin_page.js
+++ b/test/editor/pageobjects/nodes/core/function/90-exec_page.js
@@ -18,18 +18,20 @@ var util = require("util");
var nodePage = require("../../node_page");
-function mqttInNode(id) {
+function execNode(id) {
nodePage.call(this, id);
}
-util.inherits(mqttInNode, nodePage);
+util.inherits(execNode, nodePage);
-mqttInNode.prototype.setTopic = function (topic) {
- browser.setValue('#node-input-topic', topic);
+execNode.prototype.setCommand = function (command) {
+ browser.setValue('//*[@id="node-input-command"]', command);
}
-mqttInNode.prototype.setQoS = function (qos) {
- browser.selectWithWait('#node-input-qos', qos);
+execNode.prototype.setAppend = function (checkbox) {
+ if (browser.isSelected('#node-input-addpay') !== checkbox) {
+ browser.click('#node-input-addpay');
+ }
}
-module.exports = mqttInNode;
+module.exports = execNode;
diff --git a/test/editor/pageobjects/nodes/core/network/10-mqttconfig_page.js b/test/editor/pageobjects/nodes/core/network/10-mqtt_page.js
similarity index 52%
rename from test/editor/pageobjects/nodes/core/network/10-mqttconfig_page.js
rename to test/editor/pageobjects/nodes/core/network/10-mqtt_page.js
index c7cdc90c5..4bdd92336 100644
--- a/test/editor/pageobjects/nodes/core/network/10-mqttconfig_page.js
+++ b/test/editor/pageobjects/nodes/core/network/10-mqtt_page.js
@@ -14,27 +14,61 @@
* limitations under the License.
**/
-function setServer(broker, port) {
+var util = require("util");
+
+var nodePage = require("../../node_page");
+
+var mqttBrokerNode = {};
+
+mqttBrokerNode.setServer = function (broker, port) {
browser.setValue('#node-config-input-broker', broker);
port = port ? port : 1883;
browser.setValue('#node-config-input-port', port);
-}
+};
-function clickOk() {
+mqttBrokerNode.clickOk = function () {
browser.clickWithWait('#node-config-dialog-ok');
// Wait until an config dialog closes.
browser.waitForVisible('#node-config-dialog-ok', 10000, true);
-}
+};
-function edit() {
+mqttBrokerNode.edit = function () {
browser.waitForVisible('#node-input-lookup-broker');
browser.click('#node-input-lookup-broker');
// Wait until a config dialog opens.
browser.waitForVisible('#node-config-dialog-ok', 10000);
+};
+
+function mqttInNode(id) {
+ nodePage.call(this, id);
}
-module.exports = {
- setServer: setServer,
- clickOk: clickOk,
- edit: edit
+util.inherits(mqttInNode, nodePage);
+
+mqttInNode.prototype.setTopic = function (topic) {
+ browser.setValue('#node-input-topic', topic);
};
+
+mqttInNode.prototype.setQoS = function (qos) {
+ browser.selectWithWait('#node-input-qos', qos);
+};
+
+mqttInNode.prototype.mqttBrokerNode = mqttBrokerNode;
+module.exports.mqttInNode = mqttInNode;
+
+function mqttOutNode(id) {
+ nodePage.call(this, id);
+}
+
+util.inherits(mqttOutNode, nodePage);
+
+mqttOutNode.prototype.setTopic = function (topic) {
+ browser.setValue('#node-input-topic', topic);
+};
+
+mqttOutNode.prototype.setRetain = function (retain) {
+ browser.selectWithWait('#node-input-retain', retain);
+};
+
+mqttOutNode.prototype.mqttBrokerNode = mqttBrokerNode;
+module.exports.mqttOutNode = mqttOutNode;
diff --git a/test/editor/pageobjects/nodes/core/network/10-mqttout_page.js b/test/editor/pageobjects/nodes/core/network/10-mqttout_page.js
deleted file mode 100644
index 783d87b55..000000000
--- a/test/editor/pageobjects/nodes/core/network/10-mqttout_page.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * 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 nodePage = require("../../node_page");
-
-function mqttOutNode(id) {
- nodePage.call(this, id);
-}
-
-util.inherits(mqttOutNode, nodePage);
-
-mqttOutNode.prototype.setTopic = function(topic) {
- browser.setValue('#node-input-topic', topic);
-}
-
-mqttOutNode.prototype.setRetain = function (retain) {
- browser.selectWithWait('#node-input-retain', retain);
-}
-
-module.exports = mqttOutNode;
\ No newline at end of file
diff --git a/test/editor/pageobjects/nodes/core/network/22-websocket_page.js b/test/editor/pageobjects/nodes/core/network/22-websocket_page.js
new file mode 100644
index 000000000..8f7dc261e
--- /dev/null
+++ b/test/editor/pageobjects/nodes/core/network/22-websocket_page.js
@@ -0,0 +1,93 @@
+/**
+ * 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 nodePage = require("../../node_page");
+
+var websocketListenerNode = {};
+
+websocketListenerNode.setPath = function (path) {
+ browser.setValue('#node-config-input-path', path);
+};
+
+websocketListenerNode.setSendReceive = function (wholemsg) {
+ browser.selectWithWait('#node-config-input-wholemsg', wholemsg);
+};
+
+websocketListenerNode.clickOk = function () {
+ browser.clickWithWait('#node-config-dialog-ok');
+ // Wait until an config dialog closes.
+ browser.waitForVisible('#node-config-dialog-ok', 10000, true);
+};
+
+websocketListenerNode.edit = function () {
+ browser.waitForVisible('#node-input-lookup-server');
+ browser.click('#node-input-lookup-server');
+ // Wait until a config dialog opens.
+ browser.waitForVisible('#node-config-dialog-ok', 10000);
+};
+
+var websocketClientNode = {};
+
+websocketClientNode.setPath = function (path) {
+ browser.setValue('#node-config-input-path', path);
+};
+
+websocketClientNode.setSendReceive = function (wholemsg) {
+ browser.selectWithWait('#node-config-input-wholemsg', wholemsg);
+};
+
+websocketClientNode.clickOk = function () {
+ browser.clickWithWait('#node-config-dialog-ok');
+ // Wait until an config dialog closes.
+ browser.waitForVisible('#node-config-dialog-ok', 10000, true);
+};
+
+websocketClientNode.edit = function () {
+ browser.waitForVisible('#node-input-lookup-client');
+ browser.click('#node-input-lookup-client');
+ // Wait until a config dialog opens.
+ browser.waitForVisible('#node-config-dialog-ok', 10000);
+};
+
+function websocketInNode(id) {
+ nodePage.call(this, id);
+}
+
+util.inherits(websocketInNode, nodePage);
+
+websocketInNode.prototype.setType = function (type) {
+ browser.selectWithWait('#node-input-mode', type);
+};
+
+websocketInNode.prototype.websocketListenerNode = websocketListenerNode;
+websocketInNode.prototype.websocketClientNode = websocketClientNode;
+module.exports.websocketInNode = websocketInNode;
+
+function websocketOutNode(id) {
+ nodePage.call(this, id);
+}
+
+util.inherits(websocketOutNode, nodePage);
+
+websocketOutNode.prototype.setType = function (type) {
+ browser.selectWithWait('#node-input-mode', type);
+};
+
+websocketOutNode.prototype.websocketListenerNode = websocketListenerNode;
+websocketOutNode.prototype.websocketClientNode = websocketClientNode;
+module.exports.websocketOutNode = websocketOutNode;
diff --git a/test/editor/pageobjects/nodes/core/sequence/17-split_page.js b/test/editor/pageobjects/nodes/core/sequence/17-split_page.js
index 3c8c70aa5..8fc32ab1e 100644
--- a/test/editor/pageobjects/nodes/core/sequence/17-split_page.js
+++ b/test/editor/pageobjects/nodes/core/sequence/17-split_page.js
@@ -24,7 +24,19 @@ function splitNode(id) {
util.inherits(splitNode, nodePage);
-module.exports = splitNode;
+splitNode.prototype.setSplitUsing = function (splt, spltt) {
+ var spltType = {
+ "str": 1,
+ "bin": 2,
+ "len": 3
+ };
+
+ browser.clickWithWait('//*[@id="dialog-form"]/div[3]/div/button[1]');
+ browser.clickWithWait('//div[contains(@class, "red-ui-typedInput-options") and not(contains(@style, "display: none"))]/a[' + spltType[spltt] + ']');
+ browser.setValue('//*[@id="dialog-form"]/div[3]/div/div[1]/input', splt);
+};
+
+module.exports.splitNode = splitNode;
function joinNode(id) {
nodePage.call(this, id);
@@ -32,4 +44,4 @@ function joinNode(id) {
util.inherits(joinNode, nodePage);
-module.exports = joinNode;
+module.exports.joinNode = joinNode;
diff --git a/test/editor/pageobjects/nodes/node_page.js b/test/editor/pageobjects/nodes/node_page.js
index 5250250e7..03e734cab 100644
--- a/test/editor/pageobjects/nodes/node_page.js
+++ b/test/editor/pageobjects/nodes/node_page.js
@@ -35,10 +35,11 @@ Node.prototype.clickOk = function () {
browser.pause(50);
}
-Node.prototype.connect = function (targetNode) {
- var outputPort = this.id + '/*[@class="red-ui-flow-port-output"]';
+Node.prototype.connect = function (targetNode, port) {
+ port = port || 1;
+ var outputPort = this.id + '/*[@class="red-ui-flow-port-output"][' + port + ']';
var inputPort = targetNode.id + '/*[@class="red-ui-flow-port-input"]';
- browser.dragAndDrop(outputPort, inputPort)
+ browser.dragAndDrop(outputPort, inputPort);
}
Node.prototype.clickLeftButton = function () {
diff --git a/test/editor/pageobjects/nodes/nodefactory_page.js b/test/editor/pageobjects/nodes/nodefactory_page.js
index 17949e313..008ecc625 100644
--- a/test/editor/pageobjects/nodes/nodefactory_page.js
+++ b/test/editor/pageobjects/nodes/nodefactory_page.js
@@ -21,17 +21,22 @@ var catchNode = require('./core/common/25-catch_page');
var statusNode = require('./core/common/25-status_page');
var commentNode = require('./core/common/90-comment_page');
var functionNode = require('./core/function/10-function_page');
+var switchNode = require('./core/function/10-switch_page');
var changeNode = require('./core/function/15-change_page');
var rangeNode = require('./core/function/16-range_page');
var templateNode = require('./core/function/80-template_page');
var delayNode = require('./core/function/89-delay_page');
-var mqttInNode = require('./core/network/10-mqttin_page');
-var mqttOutNode = require('./core/network/10-mqttout_page');
+var triggerNode = require('./core/function/89-trigger_page');
+var execNode = require('./core/function/90-exec_page');
+var mqttInNode = require('./core/network/10-mqtt_page').mqttInNode;
+var mqttOutNode = require('./core/network/10-mqtt_page').mqttOutNode;
var httpInNode = require('./core/network/21-httpin_page');
var httpResponseNode = require('./core/network/21-httpresponse_page');
var httpRequestNode = require('./core/network/21-httprequest_page');
-var splitNode = require('./core/sequence/17-split_page');
-var joinNode = require('./core/sequence/17-split_page');
+var websocketInNode = require('./core/network/22-websocket_page').websocketInNode;
+var websocketOutNode = require('./core/network/22-websocket_page').websocketOutNode;
+var splitNode = require('./core/sequence/17-split_page').splitNode;
+var joinNode = require('./core/sequence/17-split_page').joinNode;
var batchNode = require('./core/sequence/19-batch_page');
var csvNode = require('./core/parsers/70-CSV_page');
var htmlNode = require('./core/parsers/70-HTML_page');
@@ -50,16 +55,21 @@ var nodeCatalog = {
"comment": commentNode,
// function
"function": functionNode,
+ "switch": switchNode,
"change": changeNode,
"range": rangeNode,
"template": templateNode,
"delay": delayNode,
+ "trigger": triggerNode,
+ "exec": execNode,
// network
"mqttIn": mqttInNode,
"mqttOut": mqttOutNode,
"httpIn": httpInNode,
"httpResponse": httpResponseNode,
"httpRequest": httpRequestNode,
+ "websocketIn": websocketInNode,
+ "websocketOut": websocketOutNode,
// sequence
"split": splitNode,
"join": joinNode,
diff --git a/test/editor/pageobjects/util/util_page.js b/test/editor/pageobjects/util/util_page.js
index 02508c831..3a764eb93 100644
--- a/test/editor/pageobjects/util/util_page.js
+++ b/test/editor/pageobjects/util/util_page.js
@@ -70,7 +70,7 @@ function init() {
var ret = repeatUntilSuccess(function(args) {
return browser.selectByValue(args[0], args[1]);
- }, [selector, value]);
+ }, [selector, value.toString()]);
return ret;
} catch (e) {
console.trace();
diff --git a/test/editor/specs/scenario/cookbook_messages_uispec.js b/test/editor/specs/scenario/cookbook_messages_uispec.js
index a9465e5d8..78facbcda 100644
--- a/test/editor/specs/scenario/cookbook_messages_uispec.js
+++ b/test/editor/specs/scenario/cookbook_messages_uispec.js
@@ -88,7 +88,7 @@ describe('cookbook', function () {
injectNode.clickOk();
changeNode.edit();
- changeNode.ruleMove('topic', 'payload');
+ changeNode.ruleMove('topic', 'msg', 'payload', 'msg');
changeNode.clickOk();
injectNode.connect(changeNode);
diff --git a/test/editor/specs/scenario/cookbook_mqtt_uispec.js b/test/editor/specs/scenario/cookbook_mqtt_uispec.js
index 655074750..b68170eb5 100644
--- a/test/editor/specs/scenario/cookbook_mqtt_uispec.js
+++ b/test/editor/specs/scenario/cookbook_mqtt_uispec.js
@@ -22,7 +22,6 @@ var helper = require("../../editor_helper");
var debugTab = require('../../pageobjects/editor/debugTab_page');
var workspace = require('../../pageobjects/editor/workspace_page');
var specUtil = require('../../pageobjects/util/spec_util_page');
-var mqttConfig = require('../../pageobjects/nodes/core/network/10-mqttconfig_page.js');
var httpNodeRoot = "/api";
@@ -73,9 +72,9 @@ describe('cookbook', function () {
var mqttOutNode = workspace.addNode("mqttOut");
mqttOutNode.edit();
- mqttConfig.edit();
- mqttConfig.setServer("localhost", moscaSettings.port);
- mqttConfig.clickOk();
+ mqttOutNode.mqttBrokerNode.edit();
+ mqttOutNode.mqttBrokerNode.setServer("localhost", moscaSettings.port);
+ mqttOutNode.mqttBrokerNode.clickOk();
mqttOutNode.clickOk();
workspace.deploy();
From c4ca0b6e914df395cf9365e0e4c7c5f049919c4c Mon Sep 17 00:00:00 2001
From: Hiroyasu Nishiyama
Date: Sun, 15 Mar 2020 08:02:26 +0900
Subject: [PATCH 53/67] fix tab apperance of subflow template panel
---
.../node_modules/@node-red/editor-client/src/js/ui/editor.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
index 2f5c4fe11..5d4a491b0 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
@@ -2423,15 +2423,16 @@ RED.editor = (function() {
buildAppearanceForm(appearanceTab.content,editing_node);
editorTabs.addTab(appearanceTab);
+ buildEditForm(nodePropertiesTab.content,"dialog-form","subflow-template", undefined, editing_node);
+ trayBody.i18n();
+
$.getJSON(getCredentialsURL("subflow", subflow.id), function (data) {
subflow.credentials = data;
subflow.credentials._ = $.extend(true,{},data);
- buildEditForm(nodePropertiesTab.content,"dialog-form","subflow-template", undefined, editing_node);
$("#subflow-input-name").val(subflow.name);
RED.text.bidi.prepareInput($("#subflow-input-name"));
- trayBody.i18n();
finishedBuilding = true;
done();
});
From 43258ee816f1cf354eb2db75c215bb9e05245f49 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Sun, 15 Mar 2020 15:11:19 +0000
Subject: [PATCH 54/67] Trigger node - reset default timeout value when
switcing away from wait for reset
---
.../@node-red/nodes/core/function/89-trigger.html | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/function/89-trigger.html b/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
index 28bf0cdeb..d20391b59 100644
--- a/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
+++ b/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
@@ -14,11 +14,11 @@
limitations under the License.
-->
-
From 85a1f59a93664e317934b3beac7f9de60f00b1c9 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Sun, 15 Mar 2020 16:43:32 +0000
Subject: [PATCH 55/67] Fix join to not crash on appending invalid tyoes to
buffer.
Add extra info to clarify use of complete
to Close #2505
---
.../@node-red/nodes/core/sequence/17-split.js | 8 +++++++-
.../@node-red/nodes/locales/en-US/messages.json | 3 ++-
.../@node-red/nodes/locales/en-US/sequence/17-split.html | 7 ++++---
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/sequence/17-split.js b/packages/node_modules/@node-red/nodes/core/sequence/17-split.js
index fc6042625..ced637555 100644
--- a/packages/node_modules/@node-red/nodes/core/sequence/17-split.js
+++ b/packages/node_modules/@node-red/nodes/core/sequence/17-split.js
@@ -630,7 +630,13 @@ module.exports = function(RED) {
var group = inflight[partId];
if (payloadType === 'buffer') {
if (property !== undefined) {
- inflight[partId].bufferLen += property.length;
+ if (Buffer.isBuffer(property) || (typeof property === "string") || Array.isArray(property)) {
+ inflight[partId].bufferLen += property.length;
+ }
+ else {
+ node.error(RED._("join.errors.invalid-type",{error:(typeof property)}),msg);
+ return;
+ }
}
}
if (payloadType === 'object') {
diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
index e1d7c6368..24c80003b 100755
--- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
@@ -894,7 +894,8 @@
"fixup": "Fix-up exp"
},
"errors": {
- "invalid-expr": "Invalid JSONata expression: __error__"
+ "invalid-expr": "Invalid JSONata expression: __error__",
+ "invalid-type": "Cannot join __error__ to buffer"
}
},
"sort" : {
diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/sequence/17-split.html b/packages/node_modules/@node-red/nodes/locales/en-US/sequence/17-split.html
index 5d460f8ee..c9c3e3070 100644
--- a/packages/node_modules/@node-red/nodes/locales/en-US/sequence/17-split.html
+++ b/packages/node_modules/@node-red/nodes/locales/en-US/sequence/17-split.html
@@ -14,7 +14,7 @@
limitations under the License.
-->
-
-
-
-