Compare commits

..

2 Commits

Author SHA1 Message Date
Dave Conway-Jones
495a81768d Delay node - add example for simple queue with release 2022-06-26 16:27:11 +01:00
Dave Conway-Jones
cb2efb14f7 Fix delay rate limit last timing when empty 2022-06-26 10:17:16 +01:00
31 changed files with 395 additions and 390 deletions

View File

@@ -26,7 +26,7 @@ jobs:
path: 'node-red.github.io'
- uses: actions/setup-node@v1
with:
node-version: '16'
node-version: '12'
- run: node ./node-red/.github/scripts/update-node-red-docker.js
- name: Create Docker Pull Request
uses: peter-evans/create-pull-request@v2

View File

@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14, 16]
node-version: [12, 14, 16]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}

View File

@@ -1,11 +1,5 @@
#### 3.0.0-beta.1: Beta Release
**Migration from 2.x**
- Node-RED now requires Node.js 14.x or later.
- New installs of Node-RED will default to the monaco editor.
Editor
- Add Junctions (#3462) @knolleary

View File

@@ -302,9 +302,9 @@
"successfulRestart": "フローの再起動が成功しました",
"deployFailed": "デプロイが失敗しました: __message__",
"unusedConfigNodes": "使われていない設定ノードがあります。",
"unusedConfigNodesButton": "未使用の構成ノードを検索",
"unknownNodesButton": "不明なノードを検索する",
"invalidNodesButton": "無効なノードを検索する",
"unusedConfigNodesButton":"未使用の構成ノードを検索",
"unknownNodesButton":"不明なノードを検索する",
"invalidNodesButton":"無効なノードを検索する",
"errors": {
"noResponse": "サーバの応答がありません"
},
@@ -1159,9 +1159,6 @@
"start": "開始",
"next": "次へ"
},
"diagnostics": {
"title": "システム情報"
},
"languages": {
"de": "ドイツ語",
"en-US": "英語",
@@ -1171,22 +1168,6 @@
"zh-CN": "中国語(簡体)",
"zh-TW": "中国語(繁体)"
},
"validator": {
"errors": {
"invalid-json": "JSONデータが不正: __error__",
"invalid-json-prop": "__prop__: JSONデータが不正: __error__",
"invalid-prop": "プロパティ式が不正",
"invalid-prop-prop": "__prop__: プロパティ式が不正",
"invalid-num": "数値が不正",
"invalid-num-prop": "__prop__: 数値が不正",
"invalid-regexp": "入力パターンが不正",
"invalid-regex-prop": "__prop__: 入力パターンが不正",
"missing-required-prop": "__prop__: プロパティが未設定",
"invalid-config": "__prop__: 設定ノードが不正",
"missing-config": "__prop__: 設定ノードが存在しません",
"validation-error": "__prop__: チェックエラー: __node__, __id__: __error__"
}
},
"action-list": {
"toggle-show-tips": "ヒント表示切替",
"show-about": "Node-REDの説明を表示",
@@ -1324,5 +1305,21 @@
"zoom-reset": "ズームリセット",
"toggle-navigator": "ナビゲータ表示切替",
"show-system-info": "システムインフォメーション"
},
"validator": {
"errors": {
"invalid-json": "JSONデータが不正: __error__",
"invalid-json-prop": "__prop__: JSONデータが不正: __error__",
"invalid-prop": "プロパティ式が不正",
"invalid-prop-prop": "__prop__: プロパティ式が不正",
"invalid-num": "数値が不正",
"invalid-num-prop": "__prop__: 数値が不正",
"invalid-regexp": "入力パターンが不正",
"invalid-regex-prop": "__prop__: 入力パターンが不正",
"missing-required-prop": "__prop__: プロパティが未設定",
"invalid-config": "__prop__: 設定ノードが不正",
"missing-config": "__prop__: 設定ノードが存在しません",
"validation-error": "__prop__: チェックエラー: __node__, __id__: __error__"
}
}
}

View File

@@ -2462,8 +2462,6 @@ RED.nodes = (function() {
workspacesOrder = [];
groups = {};
groupsByZ = {};
junctions = {};
junctionsByZ = {};
var subflowIds = Object.keys(subflows);
subflowIds.forEach(function(id) {

View File

@@ -1026,7 +1026,10 @@
$(opt.icon).prependTo(this.selectLabel);
}
else if (opt.icon.indexOf("/") !== -1) {
$('<i>',{class:"red-ui-typedInput-icon", style:"mask-image: url("+opt.icon+"); -webkit-mask-image: url("+opt.icon+"); margin-right: 4px;height: 18px;width:13px"}).prependTo(this.selectLabel);
image = new Image();
image.name = opt.icon;
image.src = mapDeprecatedIcon(opt.icon);
$('<img>',{src:mapDeprecatedIcon(opt.icon),style:"margin-right: 4px;height: 18px;"}).prependTo(this.selectLabel);
}
else {
$('<i>',{class:"red-ui-typedInput-icon "+opt.icon,style:"min-width: 13px; margin-right: 4px;"}).prependTo(this.selectLabel);

View File

@@ -311,8 +311,8 @@
types:[
'str','num','bool',
{value:"null",label:RED._("common.type.null"),hasValue:false},
{value:"array",label:RED._("common.type.array"),hasValue:false,icon:"red/images/typedInput/json.svg"},
{value:"object",label:RED._("common.type.object"),hasValue:false,icon:"red/images/typedInput/json.svg"}
{value:"array",label:RED._("common.type.array"),hasValue:false,icon:"red/images/typedInput/json.png"},
{value:"object",label:RED._("common.type.object"),hasValue:false,icon:"red/images/typedInput/json.png"}
],
default: valType
});

View File

@@ -19,6 +19,7 @@
this.tabflowEditor = RED.editor.createEditor({
id: 'node-input-info',
mode: 'ace/mode/markdown',
stateId: options.stateId,
value: ""
});

View File

@@ -323,6 +323,9 @@ RED.group = (function() {
groups: [ ],
dirty: RED.nodes.dirty()
}
RED.history.push(historyEvent);
groups.forEach(function(g) {
newSelection = newSelection.concat(ungroup(g))
historyEvent.groups.push(g);

View File

@@ -148,7 +148,7 @@ RED.search = (function() {
var key = keys[i];
var kpos = keys[i].indexOf(val);
if (kpos > -1) {
var ids = Object.keys(index[key]||{});
var ids = Object.keys(index[key]);
for (j=0;j<ids.length;j++) {
var node = index[key][ids[j]];
var isConfigNode = node.node._def.category === "config" && node.node.type !== 'group';
@@ -264,7 +264,7 @@ RED.search = (function() {
}
currentResults = search(value);
if (currentResults.length > 0) {
for (let i=0;i<Math.min(currentResults.length,25);i++) {
for (i=0;i<Math.min(currentResults.length,25);i++) {
searchResults.editableList('addItem',currentResults[i])
}
if (currentResults.length > 25) {

View File

@@ -172,8 +172,7 @@ RED.view = (function() {
length: function() { return set.length},
get: function(i) { return set[i] },
forEach: function(func) { set.forEach(func) },
nodes: function() { return set.map(function(n) { return n.n })},
has: function(node) { return setIds.has(node.id) }
nodes: function() { return set.map(function(n) { return n.n })}
}
return api;
})();
@@ -205,6 +204,11 @@ RED.view = (function() {
function init() {
// setTimeout(function() {
// function snap(p) { return RED.view.gridSize() * Math.round(p/RED.view.gridSize())}; for (var i = 0;i<10;i++) {
// RED.nodes.addJunction({_def:{defaults:{}}, type:'junction', z:"0ccdc1d81f2729cc",id:RED.nodes.id(),x:snap(Math.floor(Math.random()*600)),y:snap(Math.floor(Math.random()*600)), w:0,h:0})
// } ; RED.view.redraw(true)
// },2000)
chart = $("#red-ui-workspace-chart");
outer = d3.select("#red-ui-workspace-chart")
@@ -1857,7 +1861,7 @@ RED.view = (function() {
slicePath = null;
RED.view.redraw(true);
} else if (mouse_mode == RED.state.SLICING_JUNCTION) {
var removedLinks = new Set()
var removedLinks = []
var addedLinks = []
var addedJunctions = []
@@ -1866,14 +1870,8 @@ RED.view = (function() {
var sourceId = l.source.id+":"+l.sourcePort
groupedLinks[sourceId] = groupedLinks[sourceId] || []
groupedLinks[sourceId].push(l)
groupedLinks[l.target.id] = groupedLinks[l.target.id] || []
groupedLinks[l.target.id].push(l)
});
var linkGroups = Object.keys(groupedLinks)
linkGroups.sort(function(A,B) {
return groupedLinks[B].length - groupedLinks[A].length
})
linkGroups.forEach(function(gid) {
var links = groupedLinks[gid]
var junction = {
@@ -1888,10 +1886,6 @@ RED.view = (function() {
inputs: 1,
dirty: true
}
links = links.filter(function(l) { return !removedLinks.has(l) })
if (links.length === 0) {
return
}
links.forEach(function(l) {
junction.x += l._sliceLocation.x
junction.y += l._sliceLocation.y
@@ -1907,38 +1901,20 @@ RED.view = (function() {
RED.nodes.addJunction(junction)
addedJunctions.push(junction)
let newLink
if (gid === links[0].source.id+":"+links[0].sourcePort) {
newLink = {
source: links[0].source,
sourcePort: links[0].sourcePort,
target: junction
}
} else {
newLink = {
source: junction,
sourcePort: 0,
target: links[0].target
}
var newLink = {
source: links[0].source,
sourcePort: links[0].sourcePort,
target: junction
}
addedLinks.push(newLink)
RED.nodes.addLink(newLink)
links.forEach(function(l) {
removedLinks.add(l)
removedLinks.push(l)
RED.nodes.removeLink(l)
let newLink
if (gid === l.target.id) {
newLink = {
source: l.source,
sourcePort: l.sourcePort,
target: junction
}
} else {
newLink = {
source: junction,
sourcePort: 0,
target: l.target
}
var newLink = {
source: junction,
sourcePort: 0,
target: l.target
}
addedLinks.push(newLink)
RED.nodes.addLink(newLink)
@@ -1960,7 +1936,7 @@ RED.view = (function() {
t: 'add',
links: addedLinks,
junctions: addedJunctions,
removedLinks: Array.from(removedLinks)
removedLinks: removedLinks
})
RED.nodes.dirty(true)
}
@@ -2941,7 +2917,7 @@ RED.view = (function() {
} else if (drag_line.portType === PORT_TYPE_INPUT) {
src = mouseup_node;
dst = drag_line.node;
src_port = portIndex || 0;
src_port = portIndex;
}
var link = {source: src, sourcePort:src_port, target: dst};
if (drag_line.virtualLink) {
@@ -3232,16 +3208,52 @@ RED.view = (function() {
port.classed("red-ui-flow-port-hovered",false);
}
function junctionMouseOver(junction, d, portType) {
var active = (portType === undefined) ||
(mouse_mode !== RED.state.JOINING && mouse_mode !== RED.state.QUICK_JOINING) ||
(drag_lines.length > 0 && drag_lines[0].portType !== portType && !drag_lines[0].virtualLink)
junction.classed("red-ui-flow-junction-hovered", active);
function junctionMouseOver(junction, d) {
junction.classed("red-ui-flow-junction-hovered",true);
}
function junctionMouseOut(junction, d) {
junction.classed("red-ui-flow-junction-hovered",false);
}
function junctionMouseDown(junction, d, evt) {
if (RED.view.DEBUG) { console.warn("junctionMouseDown", d); }
evt = evt || d3.event;
d3.event = evt
if (evt === 1) {
return;
}
if (mouse_mode === RED.state.SELECTING_NODE) {
evt.stopPropagation();
return;
}
if (mouse_mode == RED.state.QUICK_JOINING) {
d3.event.stopPropagation();
return;
}
// mousedown_node = d;
// mousedown_port_type = portType;
// mousedown_port_index = portIndex || 0;
if (mouse_mode !== RED.state.QUICK_JOINING && (evt.ctrlKey || evt.metaKey)) {
mouse_mode = RED.state.QUICK_JOINING;
document.body.style.cursor = "crosshair";
showDragLines([{node:d,port:0,portType: PORT_TYPE_OUTPUT}]);
$(window).on('keyup',disableQuickJoinEventHandler);
} else if (event.button != 2) {
nodeMouseDown.call(junction[0][0],d)
// clearSelection();
// movingSet.add(d);
// mousedown_node = d;
// mouse_mode = RED.state.MOVING;
// var mouse = d3.touches(junction[0][0])[0]||d3.mouse(junction[0][0]);
// mouse[0] += d.x-d.w/2;
// mouse[1] += d.y-d.h/2;
// prepareDrag(mouse);
}
evt.stopPropagation();
evt.preventDefault();
}
function prepareDrag(mouse) {
mouse_mode = RED.state.MOVING;
// Called when movingSet should be prepared to be dragged
@@ -3401,9 +3413,6 @@ RED.view = (function() {
return;
} else if (mouse_mode === RED.state.SELECTING_NODE) {
d3.event.stopPropagation();
if (d.type === 'junction') {
return
}
if (selectNodesOptions.single) {
selectNodesOptions.done(d);
return;
@@ -3430,12 +3439,12 @@ RED.view = (function() {
var now = Date.now();
clickElapsed = now-clickTime;
clickTime = now;
dblClickPrimed = lastClickNode == mousedown_node &&
dblClickPrimed = (lastClickNode == mousedown_node &&
(d3.event.touches || d3.event.button === 0) &&
!d3.event.shiftKey && !d3.event.altKey &&
clickElapsed < dblClickInterval &&
d.type !== 'junction'
lastClickNode = mousedown_node;
clickElapsed < dblClickInterval
)
lastClickNode = mousedown_node;
if (!d.selected && d.g /*&& !RED.nodes.group(d.g).selected*/) {
var nodeGroup = RED.nodes.group(d.g);
@@ -3561,9 +3570,9 @@ RED.view = (function() {
clearSelection();
}
var clickPosition = (d3.event.offsetX/scaleFactor - mousedown_node.x)
var edgeDelta = ((mousedown_node.w||10)/2) - Math.abs(clickPosition);
var edgeDelta = (mousedown_node.w/2) - Math.abs(clickPosition);
var cnodes;
var targetEdgeDelta = mousedown_node.w > 30 ? 25 : (mousedown_node.w > 0 ? 8 : 3);
var targetEdgeDelta = mousedown_node.w > 30 ? 25 : 8;
if (edgeDelta < targetEdgeDelta) {
if (clickPosition < 0) {
cnodes = [mousedown_node].concat(RED.nodes.getAllUpstreamNodes(mousedown_node));
@@ -3708,8 +3717,10 @@ RED.view = (function() {
function portMouseOverProxy(e) { portMouseOver(d3.select(this), this.__data__,this.__portType__,this.__portIndex__, e); }
function portMouseOutProxy(e) { portMouseOut(d3.select(this), this.__data__,this.__portType__,this.__portIndex__, e); }
function junctionMouseOverProxy(e) { junctionMouseOver(d3.select(this), this.__data__, this.__portType__) }
function junctionMouseOverProxy(e) { junctionMouseOver(d3.select(this), this.__data__) }
function junctionMouseOutProxy(e) { junctionMouseOut(d3.select(this), this.__data__) }
function junctionMouseDownProxy(e) { junctionMouseDown(d3.select(this), this.__data__, e) }
function junctionMouseUpProxy(e) { junctionMouseUp(d3.select(this), this.__data__) }
function linkMouseDown(d) {
if (mouse_mode === RED.state.SELECTING_NODE) {
@@ -4860,56 +4871,22 @@ RED.view = (function() {
junctionBack.setAttribute("y",-5);
junctionBack.setAttribute("width",10);
junctionBack.setAttribute("height",10);
junctionBack.setAttribute("rx",3);
junctionBack.setAttribute("ry",3);
junctionBack.setAttribute("rx",5);
junctionBack.setAttribute("ry",5);
junctionBack.__data__ = d;
this.__junctionBack__ = junctionBack;
contents.appendChild(junctionBack);
var junctionInput = document.createElementNS("http://www.w3.org/2000/svg","rect");
junctionInput.setAttribute("class","red-ui-flow-junction-port red-ui-flow-junction-port-input");
junctionInput.setAttribute("x",-5);
junctionInput.setAttribute("y",-5);
junctionInput.setAttribute("width",10);
junctionInput.setAttribute("height",10);
junctionInput.setAttribute("rx",3);
junctionInput.setAttribute("ry",3);
junctionInput.__data__ = d;
junctionInput.__portType__ = PORT_TYPE_INPUT;
junctionInput.__portIndex__ = 0;
this.__junctionInput__ = junctionOutput;
contents.appendChild(junctionInput);
junctionInput.addEventListener("mouseup", portMouseUpProxy);
junctionInput.addEventListener("mousedown", portMouseDownProxy);
this.__junctionInput__ = junctionInput;
contents.appendChild(junctionInput);
var junctionOutput = document.createElementNS("http://www.w3.org/2000/svg","rect");
junctionOutput.setAttribute("class","red-ui-flow-junction-port red-ui-flow-junction-port-output");
junctionOutput.setAttribute("x",-5);
junctionOutput.setAttribute("y",-5);
junctionOutput.setAttribute("width",10);
junctionOutput.setAttribute("height",10);
junctionOutput.setAttribute("rx",3);
junctionOutput.setAttribute("ry",3);
junctionOutput.__data__ = d;
junctionOutput.__portType__ = PORT_TYPE_OUTPUT;
junctionOutput.__portIndex__ = 0;
this.__junctionOutput__ = junctionOutput;
contents.appendChild(junctionOutput);
junctionOutput.addEventListener("mouseup", portMouseUpProxy);
junctionOutput.addEventListener("mousedown", portMouseDownProxy);
junctionOutput.addEventListener("mouseover", junctionMouseOverProxy);
junctionOutput.addEventListener("mouseout", junctionMouseOutProxy);
junctionInput.addEventListener("mouseover", junctionMouseOverProxy);
junctionInput.addEventListener("mouseout", junctionMouseOutProxy);
junctionBack.addEventListener("mouseover", junctionMouseOverProxy);
junctionBack.addEventListener("mouseout", junctionMouseOutProxy);
junctionBack.addEventListener("mouseup", portMouseUpProxy);
junctionBack.addEventListener("mousedown", junctionMouseDownProxy);
// These handlers expect to be registered as d3 events
d3.select(junctionBack).on("mousedown", nodeMouseDown).on("mouseup", nodeMouseUp);
// d3.select(junctionBack).on("mousedown", nodeMouseDown);
this.__portType__ = PORT_TYPE_INPUT
this.__portIndex__ = 0
// function portMouseUpProxy(e) { portMouseUp(this.__data__,this.__portType__,this.__portIndex__, e); }
junction[0][0].appendChild(contents);
})
@@ -4918,7 +4895,6 @@ RED.view = (function() {
var junction = d3.select(this);
this.setAttribute("transform", "translate(" + (d.x) + "," + (d.y) + ")");
if (d.dirty) {
junction.classed("red-ui-flow-junction-dragging", mouse_mode === RED.state.MOVING_ACTIVE && movingSet.has(d))
junction.classed("selected", !!d.selected)
dirtyNodes[d.id] = d;
@@ -4959,11 +4935,10 @@ RED.view = (function() {
.on("touchstart",linkTouchStart)
.on("mousemove", function(d) {
if (mouse_mode === RED.state.SLICING) {
selectedLinks.add(d)
l.classed("red-ui-flow-link-splice",true)
redraw()
} else if (mouse_mode === RED.state.SLICING_JUNCTION && !d.link) {
} else if (mouse_mode === RED.state.SLICING_JUNCTION) {
if (!l.classed("red-ui-flow-link-splice")) {
// Find intersection point
var lineLength = pathLine.getTotalLength();

View File

@@ -379,46 +379,11 @@ g.red-ui-flow-link-unknown path.red-ui-flow-link-line {
white-space: pre;
@include disable-selection;
}
.red-ui-flow-junction-dragging {
.red-ui-flow-junction-background {
background: red !important
}
}
.red-ui-flow-junction:not(.red-ui-flow-junction-dragging):hover {
.red-ui-flow-junction-background {
transform: scale(1.4);
stroke-width: 0.6;
}
.red-ui-flow-junction-port {
opacity: 1;
pointer-events: auto;
}
.red-ui-flow-junction-port-input {
transform: translate(-10px,0)
}
.red-ui-flow-junction-port-output {
transform: translate(10px,0)
}
}
.red-ui-flow-junction-port {
stroke: $node-border;
stroke-width: 1;
fill: $node-port-background;
cursor: crosshair;
transition: transform 0.1s;
opacity: 0;
pointer-events: none;
}
.red-ui-flow-junction-background {
stroke: $node-border;
stroke-width: 1;
fill: $node-port-background;
cursor: crosshair;
transform: scale(1);
transition: transform 0.1s;
&:hover {
}
}
.red-ui-flow-junction-hovered {
stroke: $port-selected-color;

View File

@@ -153,16 +153,6 @@ button.red-ui-typedInput-option-trigger
img {
max-width: none;
}
.red-ui-typedInput-icon:not(.fa) {
display: inline-block;
-webkit-mask-size: cover;
mask-size: cover;
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
background-color: $primary-text-color;
}
}
&:not(.disabled):hover {

View File

@@ -5,17 +5,17 @@ export default {
titleIcon: "fa fa-map-o",
title: {
"en-US": "Welcome to Node-RED 3.0 Beta 1!",
"ja": "Node-RED 3.0 ベータ1へようこそ!"
"ja": "Node-RED 3.0 Beta 1へようこそ!"
},
description: {
"en-US": "<p>This is the first Beta release of Node-RED 3.0. It contains just about everything we have planned for the final release.</p><p>Let's take a moment to discover the new features in this release.</p>",
"ja": "<p>これはNode-RED 3.0の最初のベータリリースです。これには、最終リリースで計画しているほぼ全ての機能が含まれています。</p><p>本リリースの新機能を見つけてみましょう。</p>"
"ja": "本リリースの新機能を見つけてみましょう。"
}
},
{
title: {
"en-US": "Wire Junctions",
"ja": "分岐点をワイヤーに追加"
// "ja": ""
},
image: 'images/junction-slice.gif',
description: {
@@ -23,28 +23,26 @@ export default {
add junction nodes that give you more control.</p>
<p>Junctions can be added to wires by holding the Shift key, then click and drag with
the right-hand mouse button across the wires.</p>`,
"ja": `<p>フローのワイヤーの経路をより制御しやすくするために、分岐点ノードを追加できるようになりました。</p>
<p>シフトキーを押しながら、マウスの右ボタンをクリックし、ワイヤーを横切るようにドラッグすることで、分岐点を追加できます。</p>`
// "ja": ""
},
},
{
title: {
"en-US": "Wire Junctions",
"ja": "分岐点をワイヤーに追加"
// "ja": ""
},
image: 'images/junction-quick-add.png',
description: {
"en-US": `<p>Junctions can also be added using the quick-add dialog.</p>
<p>The dialog is opened by holding the Ctrl (or Cmd) key when
clicking in the workspace.</p>`,
"ja": `<p>クイック追加ダイアログを用いて、分岐点を追加することもできます。</p>
<p>本ダイアログを開くには、Ctrl(またはCmd)キーを押しながら、ワークスペース上でクリックします。</p>`
// "ja": ""
},
},
{
title: {
"en-US": "Debug Path Tooltip",
"ja": "デバッグパスのツールチップ"
// "ja": ""
},
image: 'images/debug-path-tooltip.png',
description: {
@@ -55,22 +53,20 @@ export default {
the message.</p>
<p>Clicking on any item in the list will reveal it in
the workspace.</p>`,
"ja": `<p>デバックサイドバー内のノード名の上にマウスカーソルを乗せると、新たにツールチップが表示され、ノードの場所が分かるようになっています。</p>
<p>これは、サブフローを用いる時に役立つ機能であり、メッセージがどのノードから出力されたかを正確に特定することが遥かに簡単になります。</p>
<p>本リスト内の要素をクリックすると、ワークスペース内にその要素が表示されます。</p>`
// "ja": ""
},
},
{
title: {
"en-US": "Continuous Search",
"ja": "連続した検索"
// "ja": ""
},
image: 'images/continuous-search.png',
description: {
"en-US": `<p>When searching for things in the editor, a new toolbar in
the workspace provides options to quickly jump between
the search results.</p>`,
"ja": `<p>ワークスペース内の新しいツールバーにあるオプションによって、エディタ内を検索する際に、検索結果の間を素早く移動できます。</p>`
// "ja": ""
},
},
{
@@ -85,17 +81,13 @@ export default {
<li><b><code>Split Wire With Link Nodes</code></b></li>
</ul>
<p>Actions can be accessed from the Action List in the main menu.</p>`,
"ja": `<p>ワイヤーを、接続されたLinkードのペアに置き換える動作が新たに追加されました:</p>
<ul>
<li><b><code>ワイヤーをlinkードで分割</code></b></li>
</ul>
<p>本アクションは、メインメニュー内の動作一覧から呼び出せます。</p>`,
// "ja": ``
},
},
{
title: {
"en-US": "Default node names",
"ja": "標準ノードの名前"
// "ja": ""
},
// image: "images/",
description: {
@@ -108,12 +100,7 @@ export default {
<li><b><code>Generate Node Names</code></b></li>
</ul><p>Actions can be accessed from the Action List in the main menu.</p>
`,
"ja": `<p>一部のノードは、ワークスペース上に新インスタンスとして追加した際に、一意の名前を付けるよう変更されました。この変更は、<code>Debug</code>、<code>Function</code>、<code>Link</code>ノードに適用されています。</p>
<p>選択したノードに対して、標準の名前を生成する動作も新たに追加されました:</p>
<ul>
<li><b><code>ノード名を生成</code></b></li>
</ul><p>本アクションは、メインメニュー内の動作一覧から呼び出せます。</p>
`
// "ja": ``
}
},
{
@@ -128,11 +115,7 @@ export default {
<li>The Link Call node can use a message property to dynamically target the link it should call</li>
<li>The HTTP Request node can be preconfigured with HTTP headers</li>
</ul>`,
"ja": `<ul>
<li>Debugードは、受信したメッセージの数をカウントするよう設定できるようになりました。</li>
<li>Link Callードは、メッセージのプロパティによって、呼び出し対象のlinkを動的に指定できるようになりました。</li>
<li>HTTP Requestードは、HTTPヘッダを事前設定できるようになりました。</li>
</ul>`
// "ja": ``
}
}
]

View File

@@ -69,7 +69,7 @@
outputs:1, // set the number of outputs - 0 to n
color: "#ddd", // set icon color
// set the icon (held in icons dir below where you save the node)
icon: "myicon.svg", // saved in icons/myicon.svg
icon: "myicon.png", // saved in icons/myicon.png
label: function() { // sets the default label contents
return this.name||this.topic||"sample";
},

View File

@@ -146,13 +146,13 @@
function createTypeValueField(row, defaultType){
return $('<input/>',{class:"node-input-rule-type-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:defaultType || 'string',types:[
{value:"string",label:RED._("common.type.string"),hasValue:false,icon:"red/images/typedInput/az.svg"},
{value:"number",label:RED._("common.type.number"),hasValue:false,icon:"red/images/typedInput/09.svg"},
{value:"boolean",label:RED._("common.type.boolean"),hasValue:false,icon:"red/images/typedInput/bool.svg"},
{value:"array",label:RED._("common.type.array"),hasValue:false,icon:"red/images/typedInput/json.svg"},
{value:"buffer",label:RED._("common.type.buffer"),hasValue:false,icon:"red/images/typedInput/bin.svg"},
{value:"object",label:RED._("common.type.object"),hasValue:false,icon:"red/images/typedInput/json.svg"},
{value:"json",label:RED._("common.type.jsonString"),hasValue:false,icon:"red/images/typedInput/json.svg"},
{value:"string",label:RED._("common.type.string"),hasValue:false,icon:"red/images/typedInput/az.png"},
{value:"number",label:RED._("common.type.number"),hasValue:false,icon:"red/images/typedInput/09.png"},
{value:"boolean",label:RED._("common.type.boolean"),hasValue:false,icon:"red/images/typedInput/bool.png"},
{value:"array",label:RED._("common.type.array"),hasValue:false,icon:"red/images/typedInput/json.png"},
{value:"buffer",label:RED._("common.type.buffer"),hasValue:false,icon:"red/images/typedInput/bin.png"},
{value:"object",label:RED._("common.type.object"),hasValue:false,icon:"red/images/typedInput/json.png"},
{value:"json",label:RED._("common.type.jsonString"),hasValue:false,icon:"red/images/typedInput/json.png"},
{value:"undefined",label:RED._("common.type.undefined"),hasValue:false},
{value:"null",label:RED._("common.type.null"),hasValue:false}
]});
@@ -247,16 +247,14 @@
var row2 = $('<div/>',{style:"display: flex; padding-top: 5px; padding-left: 175px;"}).appendTo(inputRows);
var row3 = $('<div/>',{style:"display: flex; padding-top: 5px; align-items: center"}).appendTo(inputRows);
var row4 = $('<div/>',{style:"visibility: hidden; height: 0px;"}).appendTo(inputRows);
var textSpan = $("<span/>").appendTo(row4);
var selectField = $('<select/>',{style:"width:120px; text-align: center;"}).appendTo(row);
var group0 = $('<optgroup/>', { label: RED._("node-red:switch.label.value-rules") }).appendTo(selectField);
var group0 = $('<optgroup/>', { label: "value rules" }).appendTo(selectField);
for (var d in operators) {
if(operators[d].kind === 'V') {
group0.append($("<option></option>").val(operators[d].v).text(/^switch/.test(operators[d].t)?node._(operators[d].t):operators[d].t));
}
}
var group1 = $('<optgroup/>', { label: RED._("node-red:switch.label.sequence-rules") }).appendTo(selectField);
var group1 = $('<optgroup/>', { label: "sequence rules" }).appendTo(selectField);
for (var d in operators) {
if(operators[d].kind === 'S') {
group1.append($("<option></option>").val(operators[d].v).text(/^switch/.test(operators[d].t)?node._(operators[d].t):operators[d].t));
@@ -342,12 +340,9 @@
row3.hide();
}
var selectedLabel = selectField.find("option:selected").text();
textSpan.text(selectedLabel);
var width = textSpan.width();
if (width <= 30) {
if (selectedLabel.length <= 5) {
selectField.outerWidth(60);
} else if (width <= 85) {
} else if (selectedLabel.length < 12) {
selectField.outerWidth(120);
} else {
selectField.width("auto")

View File

@@ -275,18 +275,22 @@ module.exports = function(RED) {
if (msg.hasOwnProperty("flush")) {
var len = node.buffer.length;
if (typeof(msg.flush) == 'number') { len = Math.min(Math.floor(msg.flush),len); }
while (len > 0) {
const msgInfo = node.buffer.shift();
if (Object.keys(msgInfo.msg).length > 1) {
node.send(msgInfo.msg);
msgInfo.done();
}
len = len - 1;
}
if (node.buffer.length === 0) {
if (len === 0) {
clearInterval(node.intervalID);
node.intervalID = -1;
}
else {
while (len > 0) {
const msgInfo = node.buffer.shift();
if (Object.keys(msgInfo.msg).length > 1) {
node.send(msgInfo.msg);
msgInfo.done();
}
len = len - 1;
}
clearInterval(node.intervalID);
node.intervalID = setInterval(sendMsgFromBuffer, node.rate);
}
node.status({fill:"blue",shape:"dot",text:node.buffer.length});
done();
}

View File

@@ -453,7 +453,6 @@ module.exports = function(RED) {
node.options = {};
node.queue = [];
node.subscriptions = {};
node.clientListeners = []
/** @type {mqtt.MqttClient}*/ this.client;
node.setOptions = function(opts, init) {
if(!opts || typeof opts !== "object") {
@@ -719,16 +718,11 @@ module.exports = function(RED) {
setStatusConnecting(node, true);
try {
node.serverProperties = {};
if(node.client) {
//belt and braces to avoid left over clients
node.client.end(true);
node._clientRemoveListeners();
}
node.client = mqtt.connect(node.brokerurl, node.options);
node.client.setMaxListeners(0);
let callbackDone = false; //prevent re-connects causing node._clientOn('connect' firing callback multiple times
let callbackDone = false; //prevent re-connects causing node.client.on('connect' firing callback multiple times
// Register successful connect or reconnect handler
node._clientOn('connect', function (connack) {
node.client.on('connect', function (connack) {
node.closing = false;
node.connecting = false;
node.connected = true;
@@ -760,7 +754,7 @@ module.exports = function(RED) {
}
setStatusConnected(node, true);
// Remove any existing listeners before resubscribing to avoid duplicates in the event of a re-connection
node._clientRemoveListeners('message');
node.client.removeAllListeners('message');
// Re-subscribe to stored topics
for (var s in node.subscriptions) {
@@ -772,7 +766,7 @@ module.exports = function(RED) {
if (node.subscriptions[s].hasOwnProperty(r)) {
qos = Math.max(qos,node.subscriptions[s][r].qos);
_options = node.subscriptions[s][r].options;
node._clientOn('message',node.subscriptions[s][r].handler);
node.client.on('message',node.subscriptions[s][r].handler);
}
}
_options.qos = _options.qos || qos;
@@ -785,11 +779,11 @@ module.exports = function(RED) {
node.publish(node.birthMessage);
}
});
node._clientOn("reconnect", function() {
node.client.on("reconnect", function() {
setStatusConnecting(node, true);
});
//Broker Disconnect - V5 event
node._clientOn("disconnect", function(packet) {
node.client.on("disconnect", function(packet) {
//Emitted after receiving disconnect packet from broker. MQTT 5.0 feature.
const rc = (packet && packet.properties && packet.reasonCode) || packet.reasonCode;
const rs = packet && packet.properties && packet.properties.reasonString || "";
@@ -803,7 +797,7 @@ module.exports = function(RED) {
setStatusDisconnected(node, true);
});
// Register disconnect handlers
node._clientOn('close', function () {
node.client.on('close', function () {
if (node.connected) {
node.connected = false;
node.log(RED._("mqtt.state.disconnected",{broker:(node.clientid?node.clientid+"@":"")+node.brokerurl}));
@@ -815,7 +809,7 @@ module.exports = function(RED) {
// Register connect error handler
// The client's own reconnect logic will take care of errors
node._clientOn('error', function (error) {
node.client.on('error', function (error) {
});
}catch(err) {
console.log(err);
@@ -828,7 +822,7 @@ module.exports = function(RED) {
if(node.connected || node.connecting) {
setStatusDisconnected(node, true);
}
if(node.client) { node._clientRemoveListeners(); }
if(node.client) { node.client.removeAllListeners(); }
node.connecting = false;
node.connected = false;
callback && typeof callback == "function" && callback();
@@ -842,12 +836,8 @@ module.exports = function(RED) {
if(!client) {
resolve();
} else {
const t = setTimeout(() => {
//clean end() has exceeded WAIT_END, lets force end!
client && client.end(true);
reject();
}, ms);
client.end(() => {
const t = setTimeout(reject, ms);
client.end(() => {
clearTimeout(t);
resolve()
});
@@ -904,7 +894,7 @@ module.exports = function(RED) {
};
node.subscriptions[topic][ref] = sub;
if (node.connected) {
node._clientOn('message',sub.handler);
node.client.on('message',sub.handler);
node.client.subscribe(topic, options);
}
};
@@ -915,7 +905,7 @@ module.exports = function(RED) {
if (sub) {
if (sub[ref]) {
if(node.client) {
node._clientRemoveListeners('message',sub[ref].handler);
node.client.removeListener('message',sub[ref].handler);
}
delete sub[ref];
}
@@ -1005,40 +995,13 @@ module.exports = function(RED) {
node.on('close', function(done) {
node.disconnect(function() {
if(node.client) {
node.client.removeAllListeners();
}
done();
});
});
/**
* Add event handlers to the MQTT.js client and track them so that
* we do not remove any handlers that the MQTT client uses internally.
* Use {@link node._clientRemoveListeners `node._clientRemoveListeners`} to remove handlers
* @param {string} event The name of the event
* @param {function} handler The handler for this event
*/
node._clientOn = function(event, handler) {
node.clientListeners.push({event, handler})
node.client.on(event, handler)
}
/**
* Remove event handlers from the MQTT.js client & only the events
* that we attached in {@link node._clientOn `node._clientOn`}.
* * If `event` is omitted, then all events matching `handler` are removed
* * If `handler` is omitted, then all events named `event` are removed
* * If both parameters are omitted, then all events are removed
* @param {string} [event] The name of the event (optional)
* @param {function} [handler] The handler for this event (optional)
*/
node._clientRemoveListeners = function(event, handler) {
node.clientListeners = node.clientListeners.filter((l) => {
if (event && event !== l.event) { return true; }
if (handler && handler !== l.handler) { return true; }
node.client.removeListener(l.event, l.handler)
return false; //found and removed, filter out this one
})
}
}
RED.nodes.registerType("mqtt-broker",MQTTBrokerNode,{

View File

@@ -129,7 +129,7 @@
var headerTypes = [
{value:"content-type",label:"Content-Type",hasValue: false},
{value:"location",label:"Location",hasValue: false},
{value:"other",label:RED._("node-red:httpin.label.other"),icon:"red/images/typedInput/az.svg"}
{value:"other",label:RED._("node-red:httpin.label.other"),icon:"red/images/typedInput/az.png"}
]
var contentTypes = [
{value:"application/json",label:"application/json",hasValue: false},
@@ -139,7 +139,7 @@
{value:"text/plain",label:"text/plain",hasValue: false},
{value:"image/gif",label:"image/gif",hasValue: false},
{value:"image/png",label:"image/png",hasValue: false},
{value:"other",label:RED._("node-red:httpin.label.other"),icon:"red/images/typedInput/az.svg"}
{value:"other",label:RED._("node-red:httpin.label.other"),icon:"red/images/typedInput/az.png"}
];
RED.nodes.registerType('http response',{
@@ -180,7 +180,7 @@
var propertyValue = $('<input/>',{class:"node-input-header-value",type:"text",style:"width: 100%"})
.appendTo(propertyValueCell)
.typedInput({types:
header.h === 'content-type'?contentTypes:[{value:"other",label:"other",icon:"red/images/typedInput/az.svg"}]
header.h === 'content-type'?contentTypes:[{value:"other",label:"other",icon:"red/images/typedInput/az.png"}]
});
var matchedType = headerTypes.filter(function(ht) {
@@ -223,7 +223,7 @@
if (type === 'content-type') {
propertyValue.typedInput('types',contentTypes);
} else {
propertyValue.typedInput('types',[{value:"other",label:"other",icon:"red/images/typedInput/az.svg"}]);
propertyValue.typedInput('types',[{value:"other",label:"other",icon:"red/images/typedInput/az.png"}]);
}
});
},

View File

@@ -127,14 +127,12 @@
{ value: "Cache-Control", label: "Cache-Control", hasValue: false },
{ value: "User-Agent", label: "User-Agent", hasValue: false },
{ value: "Location", label: "Location", hasValue: false },
{ value: "other", label: RED._("node-red:httpin.label.other"),
hasValue: true, icon: "red/images/typedInput/az.svg" },
{ value: "other", label: "other", hasValue: true, icon: "red/images/typedInput/az.png" },
{ value: "msg", label: "msg.", hasValue: true },
]
const headerOptions = {};
const defaultOptions = [
{ value: "other", label: RED._("node-red:httpin.label.other"),
hasValue: true, icon: "red/images/typedInput/az.svg" },
{ value: "other", label: "other", hasValue: true, icon: "red/images/typedInput/az.png" },
{ value: "msg", label: "msg.", hasValue: true },
];
headerOptions["accept"] = [

View File

@@ -247,7 +247,7 @@
var jsonata_or_empty = {
value: "jsonata",
label: "expression",
icon: "red/images/typedInput/expr.svg",
icon: "red/images/typedInput/expr.png",
validate: function(v) {
try{
if(v !== "") {

View File

@@ -0,0 +1,149 @@
[
{
"id": "48d660b3a4109400",
"type": "inject",
"z": "9e5f48c16729e4f0",
"name": "inject",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 185,
"y": 795,
"wires": [
[
"e0f9e206681f3504"
]
]
},
{
"id": "e0f9e206681f3504",
"type": "delay",
"z": "9e5f48c16729e4f0",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "30",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 430,
"y": 795,
"wires": [
[
"e470f1d794e1bef9",
"af7cea1dfb797a75"
]
]
},
{
"id": "943543cf7a1958e4",
"type": "change",
"z": "9e5f48c16729e4f0",
"name": "set flush to 1",
"rules": [
{
"t": "set",
"p": "flush",
"pt": "msg",
"to": "1",
"tot": "num"
},
{
"t": "delete",
"p": "payload",
"pt": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 510,
"y": 915,
"wires": [
[
"e0f9e206681f3504"
]
]
},
{
"id": "e470f1d794e1bef9",
"type": "function",
"z": "9e5f48c16729e4f0",
"name": "Do something that takes a few seconds",
"func": "\n//send on the message between 3 and 6 seconds later\nsetTimeout(\n function() { \n node.send(msg) \n }, \n Math.random() * 3000 + 3000\n);\nreturn null;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 760,
"y": 795,
"wires": [
[
"943543cf7a1958e4",
"859258551b8389b7"
]
]
},
{
"id": "af7cea1dfb797a75",
"type": "debug",
"z": "9e5f48c16729e4f0",
"name": "IN",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 710,
"y": 735,
"wires": []
},
{
"id": "859258551b8389b7",
"type": "debug",
"z": "9e5f48c16729e4f0",
"name": "OUT",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 895,
"y": 735,
"wires": []
},
{
"id": "ecaaf26326da10ee",
"type": "comment",
"z": "9e5f48c16729e4f0",
"name": "Simple Queue with release",
"info": "This example shows how to use a delay node set to rate limit mode as a simple queue to feed a\nprocess that may take some time to complete. Once that process completes the feedback is then\nset to flush out the next message - thus running the \"loop\" as fast as possible with no overlaps.\n\n**Note**: only the `msg.flush` property msut be set - otherwise the other properties that are fed \nback will be added as another new message to the queue.",
"x": 235,
"y": 915,
"wires": []
}
]

View File

@@ -54,10 +54,9 @@
<p>If no response is received within the configured timeout, default 30 seconds, the node
will log an error that can be caught using the <code>catch</code> node.</p>
<p>When the option <b>Link Type</b> is set to "Dynamic target" <code>msg.target</code> can be used to call a
<code>link in</code> by name or id.
<code>link in</code> by name. The target <code>link in</code> node must be named.
<ul>
<li>If there is a <code>link in</code> nodes with the same id, it will be called</li>
<li>If there are two or more <code>link in</code> nodes with the same name, an error will be raised</li>
<li>If there are 2 <code>link in</code> nodes with the same name, an error will be raised</li>
<li>A <code>link call</code> cannot call a <code>link in</code> node inside a subflow</li>
</ul>
</p>

View File

@@ -729,9 +729,7 @@
"label": {
"property": "Property",
"rule": "rule",
"repair": "recreate message sequences",
"value-rules": "value rules",
"sequence-rules": "sequence rules"
"repair": "recreate message sequences"
},
"previous": "previous value",
"and": "and",

View File

@@ -42,10 +42,9 @@
<p>本ノードはメッセージを受信するとメッセージを接続した <code>link in</code>
その後応答を待った後にメッセージを送信します</o>
<p>もし設定したタイムアウト(デフォルト30秒)以内に応答がない場合は<code>catch</code> </p>
<p><b>リンクの種類</b>""<code>link in</code>ID<code>msg.target</code>
<p><b>リンクの種類</b>""<code>link in</code><code>msg.target</code><code>link in</code>
<ul>
<li>同じIDの<code>link in</code></li>
<li>もし同じ名前を付けた<code>link in</code>2</li>
<li>もし同じ名前を付けた<code>link in</code>2</li>
<li><code>link call</code><code>link in</code></li>
</ul>
</p>

View File

@@ -86,10 +86,10 @@
"failed": "inject処理が失敗しました。詳細はログを確認してください。",
"toolong": "時間間隔が大き過ぎます",
"invalid-expr": "JSONata式が不正: __error__",
"invalid-jsonata": "__prop__: プロパティ式が不正: __error__",
"invalid-prop": "__prop__: プロパティ式が不正: __error__",
"invalid-json": "__prop__: JSONデータが不正: __error__",
"invalid-repeat": "繰り返し数が不正"
"invalid-jsonata": "__prop__: プロパティ式が不正: __error__",
"invalid-prop": "__prop__: プロパティ式が不正: __error__",
"invalid-json": "__prop__: JSONデータが不正: __error__",
"invalid-repeat": "繰り返し数が不正"
}
},
"catch": {
@@ -129,7 +129,6 @@
"msgprop": "メッセージプロパティ",
"msgobj": "msgオブジェクト全体",
"autostatus": "デバッグ出力と同じ",
"messageCount": "メッセージ数をカウント",
"to": "出力先",
"debtab": "デバッグタブ",
"tabcon": "デバッグタブとコンソール",
@@ -207,8 +206,8 @@
},
"error": {
"missing-file": "証明書と秘密鍵のファイルが設定されていません",
"invalid-cert": "証明書が指定されていません",
"invalid-key": "秘密鍵が指定されていません"
"invalid-cert": "証明書が指定されていません",
"invalid-key": "秘密鍵が指定されていません"
}
},
"exec": {
@@ -264,8 +263,8 @@
"moduleNameReserved": "予約された変数名です: __name__",
"inputListener": "コード内で'input'イベントのリスナを設定できません",
"non-message-returned": "Functionードが __type__ 型のメッセージ送信を試みました",
"invalid-js": "JavaScriptコードのエラー",
"missing-module": "モジュール __module__ が存在しません"
"invalid-js": "JavaScriptコードのエラー",
"missing-module": "モジュール __module__ が存在しません"
}
},
"template": {
@@ -319,9 +318,9 @@
"limit": "limit",
"limitTopic": "limit topic",
"random": "random",
"rate": "流量",
"random-first": "ランダム最小値",
"random-last": "ランダム最大値",
"rate": "流量",
"random-first": "ランダム最小値",
"random-last": "ランダム最大値",
"units": {
"second": {
"plural": "秒",
@@ -343,11 +342,11 @@
},
"errors": {
"too-many": "delayード内で保持しているメッセージが多すぎます",
"invalid-timeout": "遅延時間が不正",
"invalid-rate": "流量値が不正",
"invalid-rate-unit": "流量単位時間が不正",
"invalid-random-first": "ランダム最小値が不正",
"invalid-random-last": "ランダム最大値が不正"
"invalid-timeout": "遅延時間が不正",
"invalid-rate": "流量値が不正",
"invalid-rate-unit": "流量単位時間が不正",
"invalid-random-first": "ランダム最小値が不正",
"invalid-random-last": "ランダム最大値が不正"
}
},
"trigger": {
@@ -385,8 +384,8 @@
"resetMessage": "msg.resetを設定",
"resetPayload": "msg.payloadが次の値",
"resetprompt": "任意",
"duration": "時間間隔",
"topic": "トピック"
"duration": "時間間隔",
"topic": "トピック"
}
},
"comment": {
@@ -444,8 +443,7 @@
"action": "動作",
"staticTopic": "1つのトピックを購読",
"dynamicTopic": "動的な購読",
"auto-connect": "自動接続",
"auto-mode-depreciated": "本オプションは非推奨になりました。新しい自動判定モードを使用してください。"
"auto-connect": "自動接続"
},
"sections-label": {
"birth-message": "接続時の送信メッセージ(Birthメッセージ)",
@@ -492,7 +490,7 @@
"invalid-action-action": "指定された動作が不正です",
"invalid-action-alreadyconnected": "接続する前にブローカから切断してください",
"invalid-action-badsubscription": "msg.topicが存在しないか不正です",
"invalid-client-id": "クライアントIDが未指定"
"invalid-client-id": "クライアントIDが未指定"
}
},
"httpin": {
@@ -583,8 +581,8 @@
"send-error": "送信中にエラーが発生しました: ",
"missing-conf": "サーバ設定が不足しています",
"duplicate-path": "同じパスに対して2つのWebSocketリスナは指定できません: __path__",
"missing-server": "サーバが設定されていません",
"missing-client": "クライアントが設定されていません"
"missing-server": "サーバが設定されていません",
"missing-client": "クライアントが設定されていません"
}
},
"watch": {
@@ -613,8 +611,7 @@
"ms": "ミリ秒",
"chars": "文字",
"close": "終了",
"optional": "(任意)",
"reattach": "区切り文字を再追加"
"optional": "(任意)"
},
"type": {
"listen": "待ち受け",
@@ -655,8 +652,8 @@
"connect-timeout": "接続がタイムアウトしました",
"connect-fail": "接続に失敗しました",
"bad-string": "文字列への変換に失敗しました",
"invalid-host": "ホスト名が不正",
"invalid-port": "ポートが不正"
"invalid-host": "ホスト名が不正",
"invalid-port": "ポートが不正"
}
},
"udp": {
@@ -671,7 +668,7 @@
"toport": "ポート",
"address": "アドレス",
"decode-base64": "Base64形式のペイロードを復号",
"port": "ポート"
"port": "ポート"
},
"placeholder": {
"interface": "(任意) 使用するローカルインターフェイスもしくはアドレス",
@@ -719,7 +716,7 @@
"port-invalid": "udp: ポート番号が不正です",
"alreadyused": "udp: 既に__port__番ポートが使用されています",
"ifnotfound": "udp: インターフェイス __iface__ がありません",
"invalid-group": "マルチキャストグループが不正"
"invalid-group": "マルチキャストグループが不正"
}
},
"switch": {
@@ -727,9 +724,7 @@
"label": {
"property": "プロパティ",
"rule": "条件",
"repair": "メッセージ列の補正",
"value-rules": "値ルール",
"sequence-rules": "列ルール"
"repair": "メッセージ列の補正"
},
"previous": "前回の値",
"and": "",
@@ -737,22 +732,22 @@
"stopfirst": "最初に合致した条件で終了",
"ignorecase": "大文字、小文字を区別しない",
"rules": {
"btwn": "範囲内である",
"cont": "要素に含む",
"regex": "正規表現にマッチ",
"true": "trueである",
"false": "falseである",
"null": "nullである",
"nnull": "nullでない",
"istype": "指定型である",
"empty": "空である",
"nempty": "空でない",
"head": "先頭要素である",
"tail": "末尾要素である",
"index": "指定添字範囲要素である",
"btwn": "is between",
"cont": "contains",
"regex": "matches regex",
"true": "is true",
"false": "is false",
"null": "is null",
"nnull": "is not null",
"istype": "is of type",
"empty": "is empty",
"nempty": "is not empty",
"head": "head",
"tail": "tail",
"index": "index between",
"exp": "JSONata式",
"else": "その他",
"hask": "キーを含む"
"hask": "has key"
},
"errors": {
"invalid-expr": "不正な表現: __error__",
@@ -786,8 +781,8 @@
"invalid-json": "対象の値のJSONプロパティが不正",
"invalid-expr": "JSONata式が不正: __error__",
"no-override": "オブジェクト型でないプロパティを設定できません: __property__",
"invalid-prop": "プロパティ式が不正: __property__",
"invalid-json-data": "JSONデータが不正: __error__"
"invalid-prop": "プロパティ式が不正: __property__",
"invalid-json-data": "JSONデータが不正: __error__"
}
},
"range": {
@@ -799,10 +794,10 @@
"from": "最小値",
"to": "最大値",
"roundresult": "小数値を四捨五入し整数値へ変換",
"minin": "入力最小値",
"maxin": "入力最大値",
"minout": "出力最小値",
"maxout": "出力最大値"
"minin": "入力最小値",
"maxin": "入力最大値",
"minout": "出力最小値",
"maxout": "出力最大値"
},
"placeholder": {
"min": "例) 0",
@@ -1027,8 +1022,8 @@
"complete": "<code>msg.complete</code> プロパティが設定されたメッセージ受信後",
"tip": "このモードでは、本ノードが <i>split</i> ノードと組となるか、 <code>msg.parts</code> プロパティが設定されたメッセージを受け取ることが前提となります。",
"too-many": "joinード内部で保持しているメッセージが多すぎます",
"message-prop": "メッセージプロパティ",
"merge": {
"message-prop": "メッセージプロパティ",
"merge": {
"topics-label": "対象トピック",
"topics": "トピック",
"topic": "トピック",
@@ -1086,11 +1081,11 @@
"too-many": "batchード内で保持しているメッセージが多すぎます",
"unexpected": "想定外のモード",
"no-parts": "メッセージにpartsプロパティがありません",
"error": {
"invalid-count": "メッセージ数が不正",
"invalid-overlap": "オーバラップが不正",
"invalid-interval": "時間間隔が不正"
}
"error": {
"invalid-count": "メッセージ数が不正",
"invalid-overlap": "オーバラップが不正",
"invalid-interval": "時間間隔が不正"
}
},
"rbe": {
"rbe": "filter",
@@ -1100,9 +1095,9 @@
"start": "初期値",
"name": "名前",
"septopics": "個別に動作を適用",
"gap": "変化量",
"property": "プロパティ",
"topic": "トピック"
"gap": "変化量",
"property": "プロパティ",
"topic": "トピック"
},
"placeholder": {
"bandgap": "例:10、5%",

View File

@@ -24,7 +24,7 @@
<dt class="optional">method <span class="property-type">文字列</span></dt>
<dd>ノードの設定で指定していない場合このプロパティでリクエストに用いるHTTPメソッドを設定します<code>GET</code>, <code>PUT</code>, <code>POST</code>, <code>PATCH</code>, <code>DELETE</code></dd>
<dt class="optional">headers <span class="property-type">オブジェクト</span></dt>
<dd>リクエストのHTTPヘッダを指定します注釈: <code>msg.headers</code></dd>
<dd>リクエストのHTTPヘッダを指定します</dd>
<dt class="optional">cookies <span class="property-type">オブジェクト</span></dt>
<dd>設定するとリクエストと共にクッキーを送ることができます</dd>
<dt class="optional">payload</dt>

View File

@@ -15,12 +15,11 @@
-->
<script type="text/html" data-help-name="file">
<p><code>msg.payload</code></p>
<p><code>msg.payload</code></p>
<h3>入力</h3>
<dl class="message-properties">
<dt class="optional">filename <span class="property-type">文字列</span></dt>
<dd>更新するファイルの名前はノード設定やメッセージのプロパティで指定できますデフォルトでは<code>msg.filename</code>使
</dd>
<dd>対象ファイル名をノードに設定していない場合のプロパティでファイルを指定できます</dd>
<dt class="optional">encoding <span class="property-type">文字列</span></dt>
<dd>エンコーディングをmsgで設定する構成にした際はこの任意のプロパティでエンコーディングを設定できます</dt>
</dl>
@@ -31,7 +30,7 @@
<p><code>msg.filename</code>使</p>
<p>追記を行う代わりにファイル全体を上書きするように設定することもできます例えば画像のようなバイナリデータをファイルに書き出す場合はこのオプションを指定し改行を追記するオプションを指定しないようにします</p>
<p>ファイル出力の際のエンコーディングはエンコーディングリストから選択できます</p>
<p>の他ファイルの削除を行うことも可能です</p>
<p>の他ファイルの削除を行うことも可能です</p>
</script>
<script type="text/html" data-help-name="file in">
@@ -39,15 +38,14 @@
<h3>入力</h3>
<dl class="message-properties">
<dt class="optional">filename <span class="property-type">文字列</span></dt>
<dd>読み込むファイルの名前はノード設定やメッセージのプロパティで指定できますデフォルトでは<code>msg.filename</code>使
</dd>
<dd>読み出し対象のファイル名をノード設定していない場合のプロパティでファイルを指定できます</dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">文字列 | バッファ</span></dt>
<dd>ファイルの内容を文字列もしくはバッファで表現します</dd>
<dd>ファイルの内容を文字列もしくはバッファで表現します</dd>
<dt class="optional">filename <span class="property-type">文字列</span></dt>
<dd>読み出し対象のファイル名をノードに設定していない場合この任意のプロパティでファイルの名前を指定します</dd>
<dd>読み出し対象のファイル名をノードに設定していない場合このプロパティでファイルを指定します</dd>
</dl>
<h3>詳細</h3>
<p>ファイルネームは絶対パスでの指定を推奨します絶対パスを指定しない場合はNode-REDプロセスのワーキングディレクトリからの相対パスとして扱います</p>

View File

@@ -165,7 +165,7 @@ function buildDiagnosticReport(scope, callback) {
/** gets a sanitised list containing only the module name */
function listContextModules() {
const keys = Object.keys(runtime.settings.contextStorage || {});
const keys = Object.keys(runtime.settings.contextStorage);
const result = {};
keys.forEach(e => {
result[e] = {

View File

@@ -100,9 +100,7 @@
"error": "クレデンシャルの読み込みエラー: __message__",
"error-saving": "クレデンシャルの保存エラー: __message__",
"not-registered": "クレデンシャル '__type__' は登録されていません",
"system-key-warning": "\n\n---------------------------------------------------------------------\nフローのクレデンシャルファイルはシステム生成キーで暗号化されています。\n\nシステム生成キーを何らかの理由で失った場合、クレデンシャルファイルを\n復元することはできません。その場合、ファイルを削除してクレデンシャルを\n再入力しなければなりません。\n\n設定ファイル内で 'credentialSecret' オプションを使って独自キーを設定\nします。変更を次にデプロイする際、Node-REDは選択したキーを用いてクレ\nデンシャルを再暗号化します。 \n\n---------------------------------------------------------------------\n",
"unencrypted": "暗号化されていないクレデンシャルを使用",
"encryptedNotFound": "暗号化されたクレデンシャルが存在しません"
"system-key-warning": "\n\n---------------------------------------------------------------------\nフローのクレデンシャルファイルはシステム生成キーで暗号化されています。\n\nシステム生成キーを何らかの理由で失った場合、クレデンシャルファイルを\n復元することはできません。その場合、ファイルを削除してクレデンシャルを\n再入力しなければなりません。\n\n設定ファイル内で 'credentialSecret' オプションを使って独自キーを設定\nします。変更を次にデプロイする際、Node-REDは選択したキーを用いてクレ\nデンシャルを再暗号化します。 \n\n---------------------------------------------------------------------\n"
},
"flows": {
"safe-mode": "セーフモードでフローを停止しました。開始するためにはデプロイしてください",

View File

@@ -4,7 +4,7 @@ const path = require("path");
const fs = require("fs-extra");
const should = require("should");
const LATEST = "3";
const LATEST = "2";
function generateScript() {
return new Promise((resolve, reject) => {