Compare commits

..

2 Commits

Author SHA1 Message Date
Dave Conway-Jones
c2ea29e251 remove down carat from typed input with only 1 type 2018-02-03 00:02:49 +00:00
Dave Conway-Jones
6e1a2c436b let labels expand if really necessary, and pin min-width
(should we add max width also ?)
2018-02-02 22:54:51 +00:00
168 changed files with 1950 additions and 5937 deletions

View File

@@ -1,4 +1,3 @@
<!--
## Before you hit that Submit button....
This issue tracker is for problems with the Node-RED runtime, the editor or the core nodes.
@@ -15,7 +14,6 @@ That way the whole Node-RED user community can help, rather than rely on the cor
## So you have a real issue to raise...
To help us understand the issue, please fill-in as much of the following information as you can:
-->
### What are the steps to reproduce?

View File

@@ -1,4 +1,3 @@
<!--
## Before you hit that Submit button....
Please read our [contribution guidelines](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md)
@@ -7,26 +6,23 @@ before submitting a pull-request.
## Types of changes
What types of changes does your code introduce?
Put an `x` in the boxes that apply
-->
_Put an `x` in the boxes that apply_
- [ ] Bugfix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
<!--
If you want to raise a pull-request with a new feature, or a refactoring
of existing code, it **may well get rejected** if it hasn't been discussed on
the [mailing list](https://groups.google.com/forum/#!forum/node-red) or
[slack team](https://nodered.org/slack) first.
-->
## Proposed changes
<!-- Describe the nature of this change. What problem does it address? -->
Describe the nature of this change. What problem does it address?
## Checklist
<!-- Put an `x` in the boxes that apply -->
_Put an `x` in the boxes that apply_
- [ ] 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.

View File

@@ -1,12 +1,20 @@
sudo: false
language: node_js
matrix:
include:
- node_js: "10"
script:
- istanbul cover ./node_modules/.bin/grunt --report lcovonly && istanbul report text && ( cat coverage/lcov.info | $(npm get prefix)/bin/coveralls || true ) && rm -rf coverage
before_script:
- npm install -g istanbul coveralls
- node_js: "8"
- node_js: "6"
- node_js: "4"
env:
- CXX="g++-4.8"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
- gcc-4.8
node_js:
- "8"
- "6"
- "4"
script:
- istanbul cover ./node_modules/.bin/grunt --report lcovonly && istanbul report text && ( cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js || true ) && rm -rf coverage
before_script:
- npm install -g istanbul
- npm install coveralls

View File

@@ -1,138 +1,3 @@
#### 0.18.5: Maintenance Release
Projects
- Add clone project to welcome screen
- Handle cloning a project without package.json
- Keep remote branch state in sync between editor and runtime
New Features
- Add type checks to switch node options (#1714)
- add output property select to HTML parse node (#1701)
- Add Prevent Following Redirect to HTTP Request node (#615) (#1684)
- Add debug and trace functions to function node (#1654)
- Enable user defined icon for subflow
- Add MQTT disconnect message and rework broker node UI (#1719)
- Japanese message catalogue updates (#1723)
- Show node load errors in the Palette Manager view
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
- 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
- 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
- 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)
- 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
- 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
- Keep backup of .config.json
- Add warning if using \_credentialSecret from .config.json
- Filter req.user in /settings to prevent potentially leaking info
#### 0.18.4: Maintenance Release
Projects
- Ensure sshkey file path is properly escaped on Windows
- Normalize ssh key paths for Windows file names
- Ensure userDir is an absolute path when used with sshkeygen
- Detect if there are no existing flows to migrate into a project
- Use relative urls when retriving flow history
- Add credentialSecret to clone pane
- Delay clearing inflight when changing credentials key
- Mark deploy inflight when reverting a file change
- Handle missing_flow_file error on clone properly
- Remote project from cached list on delete so it can be reused
- Fix tests for existing file flag in settings
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
- 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
Node Fixes
- Ensure trigger gets reset when 2nd output is null
#### 0.18.3: Maintenance Release
Projects
- Fix permissions on git/ssh scripts
- Add support for GIT_SSH on older levels of git
- Handle host key verification as auth error
- Ensure commit list has a refs object even if empty
- Make git error detection case-insensitive
- Fix up merge conflict handling
- Use flow-diff when looking at flow file changes
Node Fixes
- Ensure debug tools show for 'complete msg object'
- Fix msg.parts handling in concat mode of Batch node
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
#### 0.18.2: Maintenance Release
Projects
- Filter out %D from git log command for older git versions
- Ensure projects are created as logged in user
- Better error handling/reporting in project creation
- Add Project Settings menu option
- Refresh vc sidebar on remote add/remove
- Fix auth prompt for ssh repos
- Prevent http git urls from including username/pword
- Fix fetch auth handling on non-default remote
- Avoid exception if git not installed
- Check version of git client on startup
- Fix pull/push when no tracked branch
- Add git_pull_unrelated_history handling
- Handle delete of last remote in project settings
Node Fixes
- Fix and Add some Chinese translations
- Update sort/batch docs
- Don't assume node has defaults when exporting icon property
- Ensure send is last thing trigger does
- Ensure trigger doesn't set two simultaneous timeouts
- Add missing property select var to HTML node
- Add a default keepalive to tcp client mode
- Move node.send in exec and httprequest nodes
#### 0.18.1: Maintenance Release
Projects

View File

@@ -392,9 +392,9 @@ module.exports = function(grunt) {
mode: '755'
},
release: {
// Target-specific file/dir lists and/or options go here.
src: [
path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/nodes/core/hardware/nrgpio*'),
path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/red/runtime/storage/localfilesystem/projects/git/node-red-*sh')
path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/nodes/core/hardware/nrgpio*')
]
}
},

View File

@@ -31,7 +31,7 @@ done
# Find the real location of this script
CURRENT_PATH=`pwd`
SCRIPT_PATH="${BASH_SOURCE[0]}";
while [ -h "${SCRIPT_PATH}" ]; do
while([ -h "${SCRIPT_PATH}" ]); do
cd "`dirname "${SCRIPT_PATH}"`"
SCRIPT_PATH="$(readlink "`basename "${SCRIPT_PATH}"`")";
done

View File

@@ -191,7 +191,7 @@ RED.history = (function() {
} else if (ev.t == "edit") {
for (i in ev.changes) {
if (ev.changes.hasOwnProperty(i)) {
if (ev.node._def.defaults && ev.node._def.defaults[i] && ev.node._def.defaults[i].type) {
if (ev.node._def.defaults[i] && ev.node._def.defaults[i].type) {
// This is a config node property
var currentConfigNode = RED.nodes.node(ev.node[i]);
if (currentConfigNode) {
@@ -229,12 +229,10 @@ RED.history = (function() {
}
});
}
RED.editor.validateNode(ev.node);
RED.nodes.filterNodes({type:"subflow:"+ev.node.id}).forEach(function(n) {
n.inputs = ev.node.in.length;
n.outputs = ev.node.out.length;
RED.editor.updateNodeProperties(n);
RED.editor.validateNode(n);
});
} else {
var outputMap;

View File

@@ -14,7 +14,7 @@
"ctrl-i": "core:show-import-dialog",
"ctrl-space": "core:toggle-sidebar",
"ctrl-,": "core:show-user-settings",
"ctrl-alt-r": "core:show-remote-diff",
"ctrl-alt-n": "core:new-project",
"ctrl-alt-o": "core:open-project",
"ctrl-g v": "core:show-version-control-tab"

View File

@@ -67,7 +67,6 @@
if (!activeProject) {
// Projects enabled but no active project
RED.menu.setDisabled('menu-item-projects-open',true);
RED.menu.setDisabled('menu-item-projects-settings',true);
if (activeProject === false) {
// User previously decline the migration to projects.
} else { // null/undefined
@@ -131,12 +130,11 @@
var project = RED.projects.getActiveProject();
var message = {
"change-branch":"Change to local branch '"+project.git.branches.local+"'",
"merge-abort":"Git merge aborted",
"abort-merge":"Git merge aborted",
"loaded":"Project '"+msg.project+"' loaded",
"updated":"Project '"+msg.project+"' updated",
"pull":"Project '"+msg.project+"' reloaded",
"revert": "Project '"+msg.project+"' reloaded",
"merge-complete":"Git merge completed"
"revert": "Project '"+msg.project+"' reloaded"
}[msg.action];
RED.notify("<p>"+message+"</p>");
RED.sidebar.info.refresh()
@@ -179,25 +177,13 @@
]
}
} else if (msg.error === "credentials_load_failed") {
if (RED.settings.theme("projects.enabled",false)) {
// projects enabled
if (RED.user.hasPermission("projects.write")) {
options.buttons = [
{
text: "Setup credentials",
click: function() {
persistentNotifications[notificationId].hideNotification();
RED.projects.showCredentialsPrompt();
}
}
]
}
} else {
if (RED.user.hasPermission("projects.write")) {
options.buttons = [
{
text: "Close",
text: "Setup credentials",
click: function() {
persistentNotifications[notificationId].hideNotification();
RED.projects.showCredentialsPrompt();
}
}
]
@@ -214,18 +200,6 @@
}
]
}
} else if (msg.error === "missing_package_file") {
if (RED.user.hasPermission("projects.write")) {
options.buttons = [
{
text: "Create default package file",
click: function() {
persistentNotifications[notificationId].hideNotification();
RED.projects.createDefaultPackageFile();
}
}
]
}
} else if (msg.error === "project_empty") {
if (RED.user.hasPermission("projects.write")) {
options.buttons = [
@@ -244,20 +218,6 @@
}
]
}
} else if (msg.error === "git_merge_conflict") {
RED.nodes.clear();
RED.sidebar.versionControl.refresh(true);
if (RED.user.hasPermission("projects.write")) {
options.buttons = [
{
text: "Show merge conflicts",
click: function() {
persistentNotifications[notificationId].hideNotification();
RED.sidebar.versionControl.showLocalChanges();
}
}
]
}
}
}
if (!persistentNotifications.hasOwnProperty(notificationId)) {
@@ -360,9 +320,8 @@
var menuOptions = [];
if (RED.settings.theme("projects.enabled",false)) {
menuOptions.push({id:"menu-item-projects-menu",label:"Projects",options:[
{id:"menu-item-projects-new",label:"New",disabled:false,onselect:"core:new-project"},
{id:"menu-item-projects-open",label:"Open",disabled:false,onselect:"core:open-project"},
{id:"menu-item-projects-settings",label:"Project Settings",disabled:false,onselect:"core:show-project-settings"}
{id:"menu-item-projects-new",label:"New...",disabled:false,onselect:"core:new-project"},
{id:"menu-item-projects-open",label:"Open...",disabled:false,onselect:"core:open-project"}
]});
}

View File

@@ -355,7 +355,7 @@ RED.nodes = (function() {
RED.nodes.registerType("subflow:"+sf.id, {
defaults:{name:{value:""}},
info: sf.info,
icon: function() { return sf.icon||"subflow.png" },
icon:"subflow.png",
category: "subflows",
inputs: sf.in.length,
outputs: sf.out.length,
@@ -550,11 +550,7 @@ RED.nodes = (function() {
if (node.out.length > 0 && n.outputLabels && !/^\s*$/.test(n.outputLabels.join(""))) {
node.outputLabels = n.outputLabels.slice();
}
if (n.icon) {
if (n.icon !== "node-red/subflow.png") {
node.icon = n.icon;
}
}
return node;
}
@@ -753,7 +749,7 @@ RED.nodes = (function() {
if (!isInitialLoad && unknownTypes.length > 0) {
var typeList = "<ul><li>"+unknownTypes.join("</li><li>")+"</li></ul>";
var type = "type"+(unknownTypes.length > 1?"s":"");
RED.notify("<p>"+RED._("clipboard.importUnrecognised",{count:unknownTypes.length})+"</p>"+typeList,"error",false,10000);
RED.notify("<strong>"+RED._("clipboard.importUnrecognised",{count:unknownTypes.length})+"</strong>"+typeList,"error",false,10000);
}
var activeWorkspace = RED.workspaces.active();
@@ -1012,13 +1008,6 @@ RED.nodes = (function() {
set: registry.getNodeSet("node-red/unknown")
};
node.users = [];
// This is a config node, so delete the default
// non-config node properties
delete node.x;
delete node.y;
delete node.wires;
delete node.inputLabels;
delete node.outputLabels;
}
var orig = {};
for (var p in n) {
@@ -1033,11 +1022,6 @@ RED.nodes = (function() {
if (node._def.category != "config") {
node.inputs = n.inputs||node._def.inputs;
node.outputs = n.outputs||node._def.outputs;
// If 'wires' is longer than outputs, clip wires
if (node.hasOwnProperty('wires') && node.wires.length > node.outputs) {
node.wires = node.wires.slice(0,node.outputs);
wireClippedNodes.push(node);
}
for (d in node._def.defaults) {
if (node._def.defaults.hasOwnProperty(d)) {
node[d] = n[d];
@@ -1059,9 +1043,7 @@ RED.nodes = (function() {
addNode(node);
RED.editor.validateNode(node);
node_map[n.id] = node;
// If an 'unknown' config node, it will not have been caught by the
// proper config node handling, so needs adding to new_nodes here
if (node.type === "unknown" || node._def.category !== "config") {
if (node._def.category != "config") {
new_nodes.push(node);
}
}

View File

@@ -408,12 +408,9 @@ RED.deploy = (function() {
delete confNode.credentials;
}
});
RED.nodes.eachSubflow(function(subflow) {
subflow.changed = false;
});
RED.nodes.eachWorkspace(function(ws) {
ws.changed = false;
});
})
// Once deployed, cannot undo back to a clean state
RED.history.markAllDirty();
RED.view.redraw();

View File

@@ -9,30 +9,29 @@ RED.diff = (function() {
// RED.actions.add("core:show-current-diff",showLocalDiff);
RED.actions.add("core:show-remote-diff",showRemoteDiff);
// RED.keyboard.add("*","ctrl-shift-l","core:show-current-diff");
// RED.keyboard.add("*","ctrl-shift-r","core:show-remote-diff");
RED.keyboard.add("*","ctrl-shift-r","core:show-remote-diff");
// RED.actions.add("core:show-test-flow-diff-1",function(){showTestFlowDiff(1)});
// RED.keyboard.add("*","ctrl-shift-f 1","core:show-test-flow-diff-1");
//
// RED.actions.add("core:show-test-flow-diff-2",function(){showTestFlowDiff(2)});
// RED.keyboard.add("*","ctrl-shift-f 2","core:show-test-flow-diff-2");
// RED.actions.add("core:show-test-flow-diff-3",function(){showTestFlowDiff(3)});
// RED.keyboard.add("*","ctrl-shift-f 3","core:show-test-flow-diff-3");
RED.actions.add("core:show-test-flow-diff-1",function(){showTestFlowDiff(1)});
RED.keyboard.add("*","ctrl-shift-f 1","core:show-test-flow-diff-1");
RED.actions.add("core:show-test-flow-diff-2",function(){showTestFlowDiff(2)});
RED.keyboard.add("*","ctrl-shift-f 2","core:show-test-flow-diff-2");
RED.actions.add("core:show-test-flow-diff-3",function(){showTestFlowDiff(3)});
RED.keyboard.add("*","ctrl-shift-f 3","core:show-test-flow-diff-3");
}
function createDiffTable(container,CurrentDiff) {
function createDiffTable(container) {
var diffList = $('<ol class="node-dialog-view-diff-diff"></ol>').appendTo(container);
diffList.editableList({
addButton: false,
height: "auto",
scrollOnAdd: false,
addItem: function(container,i,object) {
var localDiff = object.diff;
var remoteDiff = object.remoteDiff;
var tab = object.tab.n;
var def = object.def;
var conflicts = CurrentDiff.conflicts;
var conflicts = currentDiff.conflicts;
var tabDiv = $('<div>',{class:"node-diff-tab"}).appendTo(container);
tabDiv.addClass('collapsed');
@@ -151,10 +150,10 @@ RED.diff = (function() {
}
div.addClass("node-diff-node-entry-conflict");
} else {
selectState = CurrentDiff.resolutions[tab.id];
selectState = currentDiff.resolutions[tab.id];
}
// Tab properties row
createNodeConflictRadioBoxes(tab,div,localNodeDiv,remoteNodeDiv,true,!conflicts[tab.id],selectState,CurrentDiff);
createNodeConflictRadioBoxes(tab,div,localNodeDiv,remoteNodeDiv,true,!conflicts[tab.id],selectState);
}
}
// var stats = $('<span>',{class:"node-diff-tab-stats"}).appendTo(titleRow);
@@ -163,14 +162,14 @@ RED.diff = (function() {
var seen = {};
object.tab.nodes.forEach(function(node) {
seen[node.id] = true;
createNodeDiffRow(node,flowStats,CurrentDiff).appendTo(nodesDiv)
createNodeDiffRow(node,flowStats).appendTo(nodesDiv)
});
if (object.newTab) {
localNodeCount = object.newTab.nodes.length;
object.newTab.nodes.forEach(function(node) {
if (!seen[node.id]) {
seen[node.id] = true;
createNodeDiffRow(node,flowStats,CurrentDiff).appendTo(nodesDiv)
createNodeDiffRow(node,flowStats).appendTo(nodesDiv)
}
});
}
@@ -178,7 +177,7 @@ RED.diff = (function() {
remoteNodeCount = object.remoteTab.nodes.length;
object.remoteTab.nodes.forEach(function(node) {
if (!seen[node.id]) {
createNodeDiffRow(node,flowStats,CurrentDiff).appendTo(nodesDiv)
createNodeDiffRow(node,flowStats).appendTo(nodesDiv)
}
});
}
@@ -270,12 +269,12 @@ RED.diff = (function() {
if (flowStats.conflicts > 0) {
titleRow.addClass("node-diff-node-entry-conflict");
} else {
selectState = CurrentDiff.resolutions[tab.id];
selectState = currentDiff.resolutions[tab.id];
}
if (tab.id) {
var hide = !(flowStats.conflicts > 0 &&(localDiff.deleted[tab.id] || remoteDiff.deleted[tab.id]));
// Tab parent row
createNodeConflictRadioBoxes(tab,titleRow,localCell,remoteCell, false, hide, selectState, CurrentDiff);
createNodeConflictRadioBoxes(tab,titleRow,localCell,remoteCell, false, hide, selectState);
}
}
@@ -292,8 +291,11 @@ RED.diff = (function() {
var diffHeaders = $('<div class="node-dialog-view-diff-headers"></div>').appendTo(diffPanel);
if (options.mode === "merge") {
diffPanel.addClass("node-dialog-view-diff-panel-merge");
var toolbar = $('<div class="node-diff-toolbar">'+
'<span><span id="node-diff-toolbar-resolved-conflicts"></span></span> '+
'</div>').prependTo(diffPanel);
}
var diffList = createDiffTable(diffPanel, diff);
var diffList = createDiffTable(diffPanel);
var localDiff = diff.localDiff;
var remoteDiff = diff.remoteDiff;
@@ -510,10 +512,10 @@ RED.diff = (function() {
$('<span>',{class:"node-diff-node-label"}).html(nodeLabel).appendTo(contentDiv);
return nodeTitleDiv;
}
function createNodeDiffRow(node,stats,CurrentDiff) {
var localDiff = CurrentDiff.localDiff;
var remoteDiff = CurrentDiff.remoteDiff;
var conflicted = CurrentDiff.conflicts[node.id];
function createNodeDiffRow(node,stats) {
var localDiff = currentDiff.localDiff;
var remoteDiff = currentDiff.remoteDiff;
var conflicted = currentDiff.conflicts[node.id];
var hasChanges = false; // exists in original and local/remote but with changes
var unChanged = true; // existing in original,local,remote unchanged
@@ -701,10 +703,10 @@ RED.diff = (function() {
}
div.addClass("node-diff-node-entry-conflict");
} else {
selectState = CurrentDiff.resolutions[node.id];
selectState = currentDiff.resolutions[node.id];
}
// Node row
createNodeConflictRadioBoxes(node,div,localNodeDiv,remoteNodeDiv,false,!conflicted,selectState,CurrentDiff);
createNodeConflictRadioBoxes(node,div,localNodeDiv,remoteNodeDiv,false,!conflicted,selectState);
row.click(function(evt) {
$(this).parent().toggleClass('collapsed');
});
@@ -980,7 +982,7 @@ RED.diff = (function() {
});
return nodePropertiesDiv;
}
function createNodeConflictRadioBoxes(node,row,localDiv,remoteDiv,propertiesTable,hide,state,diff) {
function createNodeConflictRadioBoxes(node,row,localDiv,remoteDiv,propertiesTable,hide,state) {
var safeNodeId = "node-diff-selectbox-"+node.id.replace(/\./g,'-')+(propertiesTable?"-props":"");
var className = "";
if (node.z||propertiesTable) {
@@ -1017,7 +1019,7 @@ RED.diff = (function() {
row.addClass("node-diff-select-remote");
row.removeClass("node-diff-select-local");
}
refreshConflictHeader(diff);
refreshConflictHeader();
}
var localSelectDiv = $('<label>',{class:"node-diff-selectbox",for:safeNodeId+"-local"}).click(function(e) { e.stopPropagation();}).appendTo(localDiv);
@@ -1035,7 +1037,7 @@ RED.diff = (function() {
}
}
function refreshConflictHeader(currentDiff) {
function refreshConflictHeader() {
var resolutionCount = 0;
$(".node-diff-selectbox>input:checked").each(function() {
if (currentDiff.conflicts[$(this).data('node-id')]) {
@@ -1051,7 +1053,6 @@ RED.diff = (function() {
}
if (conflictCount === resolutionCount) {
$("#node-diff-view-diff-merge").removeClass('disabled');
$("#node-diff-view-resolve-diff").removeClass('disabled');
}
}
function getRemoteDiff(callback) {
@@ -1230,7 +1231,7 @@ RED.diff = (function() {
var localDiff = diff.localDiff;
var remoteDiff = diff.remoteDiff;
var conflicts = diff.conflicts;
// currentDiff = diff;
currentDiff = diff;
var trayOptions = {
title: options.title||"Review Changes", //TODO: nls
@@ -1249,11 +1250,7 @@ RED.diff = (function() {
},
open: function(tray) {
var trayBody = tray.find('.editor-tray-body');
var toolbar = $('<div class="node-diff-toolbar">'+
'<span><span id="node-diff-toolbar-resolved-conflicts"></span></span> '+
'</div>').prependTo(trayBody);
var diffContainer = $('<div class="node-diff-container"></div>').appendTo(trayBody);
var diffTable = buildDiffPanel(diffContainer,diff,options);
var diffTable = buildDiffPanel(trayBody,diff,options);
diffTable.list.hide();
if (remoteDiff) {
$("#node-diff-view-diff-merge").show();
@@ -1265,7 +1262,7 @@ RED.diff = (function() {
} else {
$("#node-diff-view-diff-merge").hide();
}
refreshConflictHeader(diff);
refreshConflictHeader();
// console.log("--------------");
// console.log(localDiff);
// console.log(remoteDiff);
@@ -1293,8 +1290,8 @@ RED.diff = (function() {
class: "primary disabled",
click: function() {
if (!$("#node-diff-view-diff-merge").hasClass('disabled')) {
refreshConflictHeader(diff);
mergeDiff(diff);
refreshConflictHeader();
mergeDiff(currentDiff);
RED.tray.close();
}
}
@@ -1305,7 +1302,7 @@ RED.diff = (function() {
RED.tray.show(trayOptions);
}
function applyDiff(diff) {
function mergeDiff(diff) {
var currentConfig = diff.localDiff.currentConfig;
var localDiff = diff.localDiff;
var remoteDiff = diff.remoteDiff;
@@ -1359,20 +1356,6 @@ RED.diff = (function() {
}
}
}
return {
config: newConfig,
nodeChangedStates: nodeChangedStates,
localChangedStates: localChangedStates
}
}
function mergeDiff(diff) {
var appliedDiff = applyDiff(diff);
var newConfig = appliedDiff.config;
var nodeChangedStates = appliedDiff.nodeChangedStates;
var localChangedStates = appliedDiff.localChangedStates;
var historyEvent = {
t:"replace",
config: RED.nodes.createCompleteNodeSet(),
@@ -1391,7 +1374,7 @@ RED.diff = (function() {
}
})
RED.nodes.version(diff.remoteDiff.rev);
RED.nodes.version(remoteDiff.rev);
RED.view.redraw(true);
RED.palette.refresh();
@@ -1434,7 +1417,7 @@ RED.diff = (function() {
var trayBody = tray.find('.editor-tray-body');
var diffPanel = $('<div class="node-text-diff"></div>').appendTo(trayBody);
var codeTable = $("<table>",{class:"node-text-diff-content"}).appendTo(diffPanel);
var codeTable = $("<table>").appendTo(diffPanel);
$('<colgroup><col width="50"><col width="50%"><col width="50"><col width="50%"></colgroup>').appendTo(codeTable);
var codeBody = $('<tbody>').appendTo(codeTable);
var diffSummary = diffText(textA||"",textB||"");
@@ -1698,7 +1681,7 @@ RED.diff = (function() {
files.forEach(function(file) {
var hunks = file.hunks;
var isBinary = file.binary;
var codeTable = $("<table>",{class:"node-text-diff-content"}).appendTo(diffPanel);
var codeTable = $("<table>").appendTo(diffPanel);
$('<colgroup><col width="50"><col width="50"><col width="100%"></colgroup>').appendTo(codeTable);
var codeBody = $('<tbody>').appendTo(codeTable);
@@ -1717,82 +1700,49 @@ RED.diff = (function() {
var unresolvedConflicts = 0;
var resolvedConflicts = 0;
var conflictResolutions = {};
if (commitOptions.project.files && commitOptions.project.files.flow === file.file) {
if (commitOptions.unmerged) {
$('<span style="float: right;"><span id="node-diff-toolbar-resolved-conflicts"></span></span>').appendTo(content);
}
var diffRow = $('<tr class="node-text-diff-header">').appendTo(codeBody);
var flowDiffContent = $('<td class="flow-diff" colspan="3"></td>').appendTo(diffRow);
var projectName = commitOptions.project.name;
var filename = commitOptions.project.files.flow;
var commonVersionUrl = "projects/"+projectName+"/files/"+commitOptions.commonRev+"/"+filename;
var oldVersionUrl = "projects/"+projectName+"/files/"+commitOptions.oldRev+"/"+filename;
var newVersionUrl = "projects/"+projectName+"/files/"+commitOptions.newRev+"/"+filename;
var promises = [$.Deferred(),$.Deferred(),$.Deferred()];
if (commitOptions.commonRev) {
var commonVersionUrl = "projects/"+projectName+"/files/"+commitOptions.commonRev+"/"+filename;
$.ajax({dataType: "json",url: commonVersionUrl}).then(function(data) { promises[0].resolve(data); }).fail(function() { promises[0].resolve(null);})
} else {
promises[0].resolve(null);
}
$.ajax({dataType: "json",url: oldVersionUrl}).then(function(data) { promises[1].resolve(data); }).fail(function() { promises[1].resolve({content:"[]"});})
$.ajax({dataType: "json",url: newVersionUrl}).then(function(data) { promises[2].resolve(data); }).fail(function() { promises[2].resolve({content:"[]"});})
$.when.apply($,promises).always(function(commonVersion, oldVersion,newVersion) {
var commonFlow;
var oldFlow;
var newFlow;
if (commonVersion) {
if (!commitOptions.unmerged && commitOptions.project.files && commitOptions.project.files.flow === file.file) {
var tools = $('<span style="float: right;" class="button-group"></span>').appendTo(content);
$('<button class="editor-button editor-button-small">show flow diff</button>').appendTo(tools).click(function(e) {
e.preventDefault();
e.stopPropagation();
var projectName = commitOptions.project.name;
var filename = commitOptions.project.files.flow;
var oldVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.oldRev+"/"+filename;
var newVersionUrl = "/projects/"+projectName+"/files/"+commitOptions.newRev+"/"+filename;
$.when($.getJSON(oldVersionUrl),$.getJSON(newVersionUrl)).done(function(oldVersion,newVersion) {
var oldFlow;
var newFlow;
try {
commonFlow = JSON.parse(commonVersion.content||"[]");
oldFlow = JSON.parse(oldVersion[0].content||"[]");
} catch(err) {
console.log("Common Version doesn't contain valid JSON:",commonVersionUrl);
console.log("Old Version doesn't contain valid JSON:",oldVersionUrl);
console.log(err);
return;
}
}
try {
oldFlow = JSON.parse(oldVersion.content||"[]");
} catch(err) {
console.log("Old Version doesn't contain valid JSON:",oldVersionUrl);
console.log(err);
return;
}
if (!commonFlow) {
commonFlow = oldFlow;
}
try {
newFlow = JSON.parse(newVersion.content||"[]");
} catch(err) {
console.log("New Version doesn't contain valid JSON:",newFlow);
console.log(err);
return;
}
var localDiff = generateDiff(commonFlow,oldFlow);
var remoteDiff = generateDiff(commonFlow,newFlow);
commitOptions.currentDiff = resolveDiffs(localDiff,remoteDiff);
var diffTable = buildDiffPanel(flowDiffContent,commitOptions.currentDiff,{
title: filename,
mode: commitOptions.commonRev?'merge':'view',
oldRevTitle: commitOptions.oldRevTitle,
newRevTitle: commitOptions.newRevTitle
try {
newFlow = JSON.parse(newVersion[0].content||"[]");
} catch(err) {
console.log("New Version doesn't contain valid JSON:",newFlow);
console.log(err);
return;
}
var localDiff = generateDiff(oldFlow,oldFlow);
var remoteDiff = generateDiff(oldFlow,newFlow);
var diff = resolveDiffs(localDiff,remoteDiff);
showDiff(diff,{
title: filename,
mode: 'view',
oldRevTitle: commitOptions.oldRevTitle,
newRevTitle: commitOptions.newRevTitle
});
// var flowDiffRow = $("<tr>").insertAfter(diffRow);
// var content = $('<td colspan="3"></td>').appendTo(flowDiffRow);
// currentDiff = diff;
// var diffTable = buildDiffPanel(content,diff,{mode:"view"}).finish();
});
diffTable.list.hide();
refreshConflictHeader(commitOptions.currentDiff);
setTimeout(function() {
diffTable.finish();
diffTable.list.show();
},300);
// var flowDiffRow = $("<tr>").insertAfter(diffRow);
// var content = $('<td colspan="3"></td>').appendTo(flowDiffRow);
// currentDiff = diff;
// var diffTable = buildDiffPanel(content,diff,{mode:"view"}).finish();
});
} else
})
}
if (isBinary) {
var diffBinaryRow = $('<tr class="node-text-diff-header">').appendTo(codeBody);
@@ -1800,9 +1750,6 @@ RED.diff = (function() {
$('<span></span>').text("Cannot show binary file contents").appendTo(binaryContent);
} else {
if (commitOptions.unmerged) {
conflictHeader = $('<span style="float: right;"><span>'+resolvedConflicts+'</span> of <span>'+unresolvedConflicts+'</span> conflicts resolved</span>').appendTo(content);
}
hunks.forEach(function(hunk) {
var diffRow = $('<tr class="node-text-diff-header">').appendTo(codeBody);
var content = $('<td colspan="3"></td>').appendTo(diffRow);
@@ -1821,7 +1768,7 @@ RED.diff = (function() {
// }
var actualLineNumber = hunk.diffStart + lineNumber;
var isMergeHeader = isConflict && /^\+\+(<<<<<<<|=======$|>>>>>>>)/.test(lineText);
var isMergeHeader = isConflict && /^..(<<<<<<<|=======$|>>>>>>>)/.test(lineText);
var diffRow = $('<tr>').appendTo(codeBody);
var localLineNo = $('<td class="lineno">').appendTo(diffRow);
var remoteLineNo;
@@ -1880,7 +1827,7 @@ RED.diff = (function() {
$('<span>').text(lineText.substring(prefixEnd)).appendTo(line);
} else {
diffRow.addClass("mergeHeader");
var isSeparator = /^\+\+=======$/.test(lineText);
var isSeparator = /^..(=======$)/.test(lineText);
if (!isSeparator) {
var isOurs = /^..<<<<<<</.test(lineText);
if (isOurs) {
@@ -1939,6 +1886,9 @@ RED.diff = (function() {
});
});
}
if (commitOptions.unmerged) {
conflictHeader = $('<span style="float: right;"><span>'+resolvedConflicts+'</span> of <span>'+unresolvedConflicts+'</span> conflicts resolved</span>').appendTo(content);
}
});
return diffPanel;
}
@@ -1964,7 +1914,7 @@ RED.diff = (function() {
var trayBody = tray.find('.editor-tray-body');
var diffPanel = $('<div class="node-text-diff"></div>').appendTo(trayBody);
var codeTable = $("<table>",{class:"node-text-diff-content"}).appendTo(diffPanel);
var codeTable = $("<table>").appendTo(diffPanel);
$('<colgroup><col width="50"><col width="50"><col width="100%"></colgroup>').appendTo(codeTable);
var codeBody = $('<tbody>').appendTo(codeTable);
@@ -2007,6 +1957,7 @@ RED.diff = (function() {
}
}
var trayOptions = {
title: title||"Compare Changes", //TODO: nls
width: Infinity,
@@ -2045,15 +1996,6 @@ RED.diff = (function() {
class: "primary disabled",
click: function() {
if (!$("#node-diff-view-resolve-diff").hasClass('disabled')) {
if (options.currentDiff) {
// This is a flow file. Need to apply the diff
// and generate the new flow.
var result = applyDiff(options.currentDiff);
currentResolution = {
resolutions:{}
};
currentResolution.resolutions[options.project.files.flow] = JSON.stringify(result.config,"",4);
}
if (options.onresolve) {
options.onresolve(currentResolution);
}
@@ -2105,7 +2047,7 @@ RED.diff = (function() {
} else {
lines = diff.split("\n");
}
var diffHeader = /^diff (?:(?:--git a\/(.*) b\/(.*))|(?:--cc (.*)))$/;
var diffHeader = /^diff --git a\/(.*) b\/(.*)$/;
var fileHeader = /^\+\+\+ b\/(.*)\t?/;
var binaryFile = /^Binary files /;
var hunkHeader = /^@@ -((\d+)(,(\d+))?) \+((\d+)(,(\d+))?) @@ ?(.*)$/;
@@ -2124,7 +2066,7 @@ RED.diff = (function() {
}
currentHunk = null;
currentFile = {
file: diffLine[1]||diffLine[3],
file: diffLine[1],
hunks: []
}
} else if (binaryFile.test(line)) {

View File

@@ -48,7 +48,7 @@ RED.editor = (function() {
isValid = validateNode(subflow);
hasChanged = subflow.changed;
}
node.valid = isValid && validateNodeProperties(node, node._def.defaults, node);
node.valid = isValid;
node.changed = node.changed || hasChanged;
} else if (node._def) {
node.valid = validateNodeProperties(node, node._def.defaults, node);
@@ -170,10 +170,6 @@ RED.editor = (function() {
}
}
}
validateIcon(node);
}
function validateIcon(node) {
if (node._def.hasOwnProperty("defaults") && !node._def.defaults.hasOwnProperty("icon") && node.icon) {
var iconPath = RED.utils.separateIconPath(node.icon);
var iconSets = RED.nodes.getIconSets();
@@ -192,7 +188,6 @@ RED.editor = (function() {
}
}
}
function validateNodeEditorProperty(node,defaults,property,prefix) {
var input = $("#"+prefix+"-"+property);
if (input.length > 0) {
@@ -747,7 +742,7 @@ RED.editor = (function() {
buildLabelRow().appendTo(outputsDiv);
}
if ((!node._def.defaults || !node._def.defaults.hasOwnProperty("icon"))) {
if (!node._def.defaults.hasOwnProperty("icon")) {
$('<div class="form-row"><div id="node-settings-icon"></div></div>').appendTo(dialogForm);
var iconDiv = $("#node-settings-icon");
$('<label data-i18n="editor.settingIcon">').appendTo(iconDiv);
@@ -821,51 +816,9 @@ RED.editor = (function() {
});
}
selectIconFile.prop("disabled", !iconFileList);
selectIconFile.removeClass("input-error");
selectIconModule.removeClass("input-error");
}
function updateLabels(editing_node, changes, outputMap) {
var inputLabels = $("#node-label-form-inputs").children().find("input");
var outputLabels = $("#node-label-form-outputs").children().find("input");
var hasNonBlankLabel = false;
var changed = false;
var newValue = inputLabels.map(function() {
var v = $(this).val();
hasNonBlankLabel = hasNonBlankLabel || v!== "";
return v;
}).toArray().slice(0,editing_node.inputs);
if ((editing_node.inputLabels === undefined && hasNonBlankLabel) ||
(editing_node.inputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(editing_node.inputLabels))) {
changes.inputLabels = editing_node.inputLabels;
editing_node.inputLabels = newValue;
changed = true;
}
hasNonBlankLabel = false;
newValue = new Array(editing_node.outputs);
outputLabels.each(function() {
var index = $(this).attr('id').substring(23); // node-label-form-output-<index>
if (outputMap && outputMap.hasOwnProperty(index)) {
index = parseInt(outputMap[index]);
if (index === -1) {
return;
}
}
var v = $(this).val();
hasNonBlankLabel = hasNonBlankLabel || v!== "";
newValue[index] = v;
});
if ((editing_node.outputLabels === undefined && hasNonBlankLabel) ||
(editing_node.outputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(editing_node.outputLabels))) {
changes.outputLabels = editing_node.outputLabels;
editing_node.outputLabels = newValue;
changed = true;
}
return changed;
}
function showEditDialog(node) {
var editing_node = node;
var isDefaultIcon;
@@ -1081,11 +1034,44 @@ RED.editor = (function() {
// }
var removedLinks = updateNodeProperties(editing_node,outputMap);
if (updateLabels(editing_node, changes, outputMap)) {
var inputLabels = $("#node-label-form-inputs").children().find("input");
var outputLabels = $("#node-label-form-outputs").children().find("input");
var hasNonBlankLabel = false;
newValue = inputLabels.map(function() {
var v = $(this).val();
hasNonBlankLabel = hasNonBlankLabel || v!== "";
return v;
}).toArray().slice(0,editing_node.inputs);
if ((editing_node.inputLabels === undefined && hasNonBlankLabel) ||
(editing_node.inputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(editing_node.inputLabels))) {
changes.inputLabels = editing_node.inputLabels;
editing_node.inputLabels = newValue;
changed = true;
}
hasNonBlankLabel = false;
newValue = new Array(editing_node.outputs);
outputLabels.each(function() {
var index = $(this).attr('id').substring(23); // node-label-form-output-<index>
if (outputMap && outputMap.hasOwnProperty(index)) {
index = parseInt(outputMap[index]);
if (index === -1) {
return;
}
}
var v = $(this).val();
hasNonBlankLabel = hasNonBlankLabel || v!== "";
newValue[index] = v;
})
if ((editing_node.outputLabels === undefined && hasNonBlankLabel) ||
(editing_node.outputLabels !== undefined && JSON.stringify(newValue) !== JSON.stringify(editing_node.outputLabels))) {
changes.outputLabels = editing_node.outputLabels;
editing_node.outputLabels = newValue;
changed = true;
}
if (!editing_node._def.defaults || !editing_node._def.defaults.hasOwnProperty("icon")) {
if (!editing_node._def.defaults.hasOwnProperty("icon")) {
var iconModule = $("#node-settings-icon-module-hidden").val();
var iconFile = $("#node-settings-icon-file-hidden").val();
var icon = (iconModule && iconFile) ? iconModule+"/"+iconFile : "";
@@ -1689,25 +1675,25 @@ RED.editor = (function() {
editing_node.info = newDescription;
changed = true;
}
if (updateLabels(editing_node, changes, null)) {
var inputLabels = $("#node-label-form-inputs").children().find("input");
var outputLabels = $("#node-label-form-outputs").children().find("input");
var newValue = inputLabels.map(function() { return $(this).val();}).toArray().slice(0,editing_node.inputs);
if (JSON.stringify(newValue) !== JSON.stringify(editing_node.inputLabels)) {
changes.inputLabels = editing_node.inputLabels;
editing_node.inputLabels = newValue;
changed = true;
}
var iconModule = $("#node-settings-icon-module-hidden").val();
var iconFile = $("#node-settings-icon-file-hidden").val();
var icon = (iconModule && iconFile) ? iconModule+"/"+iconFile : "";
if ((editing_node.icon === undefined && icon !== "node-red/subflow.png") ||
(editing_node.icon !== undefined && editing_node.icon !== icon)) {
changes.icon = editing_node.icon;
editing_node.icon = icon;
newValue = outputLabels.map(function() { return $(this).val();}).toArray().slice(0,editing_node.outputs);
if (JSON.stringify(newValue) !== JSON.stringify(editing_node.outputLabels)) {
changes.outputLabels = editing_node.outputLabels;
editing_node.outputLabels = newValue;
changed = true;
}
RED.palette.refresh();
if (changed) {
var wasChanged = editing_node.changed;
editing_node.changed = true;
validateNode(editing_node);
var subflowInstances = [];
RED.nodes.eachNode(function(n) {
if (n.type == "subflow:"+editing_node.id) {
@@ -1718,9 +1704,10 @@ RED.editor = (function() {
n.changed = true;
n.dirty = true;
updateNodeProperties(n);
validateNode(n);
}
});
var wasChanged = editing_node.changed;
editing_node.changed = true;
RED.nodes.dirty(true);
var historyEvent = {
t:'edit',
@@ -1799,7 +1786,6 @@ RED.editor = (function() {
$("#subflow-dialog-user-count").html(RED._("subflow.subflowInstances", {count:userCount})).show();
buildLabelForm(portLabels.content,subflow);
validateIcon(subflow);
trayBody.i18n();
},
close: function() {

View File

@@ -389,7 +389,6 @@ RED.keyboard = (function() {
var currentEditorSettings = RED.settings.get('editor') || {};
var userKeymap = currentEditorSettings.keymap || {};
userKeymap[object.id] = null;
currentEditorSettings.keymap = userKeymap;
RED.settings.set('editor',currentEditorSettings);
var obj = {
@@ -443,7 +442,6 @@ RED.keyboard = (function() {
var currentEditorSettings = RED.settings.get('editor') || {};
var userKeymap = currentEditorSettings.keymap || {};
userKeymap[object.id] = RED.keyboard.getShortcut(object.id);
currentEditorSettings.keymap = userKeymap;
RED.settings.set('editor',currentEditorSettings);
}
}

View File

@@ -15,8 +15,8 @@
**/
RED.library = (function() {
var exportToLibraryDialog;
var elementPrefix = "node-input-";
function loadFlowLibrary() {
$.getJSON("library/flows",function(data) {
@@ -86,7 +86,6 @@ RED.library = (function() {
var libraryData = {};
var selectedLibraryItem = null;
var libraryEditor = null;
elementPrefix = options.elementPrefix || "node-input-";
// Orion editor has set/getText
// ACE editor has set/getValue
@@ -158,8 +157,8 @@ RED.library = (function() {
return ul;
}
$('#'+elementPrefix+"name").css("width","calc(100% - 52px)").after(
'<div class="btn-group" style="margin-left:5px;">'+
$('#node-input-name').css("width","66%").after(
'<div class="btn-group" style="margin-left: 5px;">'+
'<a id="node-input-'+options.type+'-lookup" class="editor-button" data-toggle="dropdown"><i class="fa fa-book"></i> <i class="fa fa-caret-down"></i></a>'+
'<ul class="dropdown-menu pull-right" role="menu">'+
'<li><a id="node-input-'+options.type+'-menu-open-library" tabindex="-1" href="#">'+RED._("library.openLibrary")+'</a></li>'+
@@ -188,7 +187,7 @@ RED.library = (function() {
$('#node-input-'+options.type+'-menu-save-library').click(function(e) {
//var found = false;
var name = $("#"+elementPrefix+"name").val().replace(/(^\s*)|(\s*$)/g,"");
var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,"");
//var buildPathList = function(data,root) {
// var paths = [];
@@ -265,7 +264,7 @@ RED.library = (function() {
if (selectedLibraryItem) {
for (var i=0; i<options.fields.length; i++) {
var field = options.fields[i];
$("#"+elementPrefix+field).val(selectedLibraryItem[field]);
$("#node-input-"+field).val(selectedLibraryItem[field]);
}
options.editor.setValue(libraryEditor.getValue(),-1);
}
@@ -287,7 +286,7 @@ RED.library = (function() {
});
function saveToLibrary(overwrite) {
var name = $("#"+elementPrefix+"name").val().replace(/(^\s*)|(\s*$)/g,"");
var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,"");
if (name === "") {
name = RED._("library.unnamedType",{type:options.type});
}
@@ -331,7 +330,7 @@ RED.library = (function() {
if (field == "name") {
data.name = name;
} else {
data[field] = $("#"+elementPrefix+field).val();
data[field] = $("#node-input-"+field).val();
}
}

View File

@@ -208,8 +208,6 @@ RED.palette.editor = (function() {
if (nodeEntry) {
var activeTypeCount = 0;
var typeCount = 0;
var errorCount = 0;
nodeEntry.errorList.empty();
nodeEntries[module].totalUseCount = 0;
nodeEntries[module].setUseCount = {};
@@ -218,10 +216,7 @@ RED.palette.editor = (function() {
var inUseCount = 0;
var set = moduleInfo.sets[setName];
var setElements = nodeEntry.sets[setName];
if (set.err) {
errorCount++;
$("<li>").text(set.err).appendTo(nodeEntry.errorList);
}
if (set.enabled) {
activeTypeCount += set.types.length;
}
@@ -260,13 +255,6 @@ RED.palette.editor = (function() {
setElements.setRow.toggleClass("palette-module-set-disabled",!set.enabled);
}
}
if (errorCount === 0) {
nodeEntry.errorRow.hide()
} else {
nodeEntry.errorRow.show();
}
var nodeCount = (activeTypeCount === typeCount)?typeCount:activeTypeCount+" / "+typeCount;
nodeEntry.setCount.html(RED._('palette.editor.nodeCount',{count:typeCount,label:nodeCount}));
@@ -598,9 +586,6 @@ RED.palette.editor = (function() {
$('<span>').html(entry.name).appendTo(titleRow);
var metaRow = $('<div class="palette-module-meta palette-module-version"><i class="fa fa-tag"></i></div>').appendTo(headerRow);
var versionSpan = $('<span>').html(entry.version).appendTo(metaRow);
var errorRow = $('<div class="palette-module-meta palette-module-errors"><i class="fa fa-warning"></i></div>').hide().appendTo(headerRow);
var errorList = $('<ul class="palette-module-error-list"></ul>').appendTo(errorRow);
var buttonRow = $('<div>',{class:"palette-module-meta"}).appendTo(headerRow);
var setButton = $('<a href="#" class="editor-button editor-button-small palette-module-set-button"><i class="fa fa-angle-right palette-module-node-chevron"></i> </a>').appendTo(buttonRow);
var setCount = $('<span>').appendTo(setButton);
@@ -635,8 +620,6 @@ RED.palette.editor = (function() {
updateButton: updateButton,
removeButton: removeButton,
enableButton: enableButton,
errorRow: errorRow,
errorList: errorList,
setCount: setCount,
container: container,
shade: shade,
@@ -668,6 +651,7 @@ RED.palette.editor = (function() {
typeSwatches[t] = $('<span>',{class:"palette-module-type-swatch"}).appendTo(typeDiv);
$('<span>',{class:"palette-module-type-node"}).html(t).appendTo(typeDiv);
})
var enableButton = $('<a href="#" class="editor-button editor-button-small"></a>').appendTo(buttonGroup);
enableButton.click(function(evt) {
evt.preventDefault();

View File

@@ -116,12 +116,6 @@ RED.palette = (function() {
el.data('popover').setContent(popOverContent);
}
function setIcon(element,sf) {
var iconElement = element.find(".palette_icon");
var icon_url = RED.utils.getNodeIcon(sf._def,sf);
iconElement.attr("style", "background-image: url("+icon_url+")");
}
function escapeNodeType(nt) {
return nt.replace(" ","_").replace(".","_").replace(":","_");
}
@@ -225,19 +219,13 @@ RED.palette = (function() {
var mouseX;
var mouseY;
var spliceTimer;
var paletteWidth;
var paletteTop;
$(d).draggable({
helper: 'clone',
appendTo: 'body',
revert: true,
revertDuration: 50,
containment:'#main-container',
start: function() {
paletteWidth = $("#palette").width();
paletteTop = $("#palette").parent().position().top + $("#palette-container").position().top;
RED.view.focus();
},
start: function() {RED.view.focus();},
stop: function() { d3.select('.link_splice').classed('link_splice',false); if (spliceTimer) { clearTimeout(spliceTimer); spliceTimer = null;}},
drag: function(e,ui) {
@@ -247,8 +235,9 @@ RED.palette = (function() {
ui.position.left += 17.5;
if (def.inputs > 0 && def.outputs > 0) {
mouseX = ui.position.left-paletteWidth+(ui.helper.width()/2) - chartOffset.left + chart.scrollLeft();
mouseY = ui.position.top-paletteTop+(ui.helper.height()/2) - chartOffset.top + chart.scrollTop();
mouseX = ui.position.left+(ui.helper.width()/2) - chartOffset.left + chart.scrollLeft();
mouseY = ui.position.top+(ui.helper.height()/2) - chartOffset.top + chart.scrollTop();
if (!spliceTimer) {
spliceTimer = setTimeout(function() {
var nodes = [];
@@ -270,7 +259,6 @@ RED.palette = (function() {
mouseY /= RED.view.scale();
nodes = RED.view.getLinksAtPoint(mouseX,mouseY);
}
for (var i=0;i<nodes.length;i++) {
if (d3.select(nodes[i]).classed('link_background')) {
var length = nodes[i].getTotalLength();
@@ -381,7 +369,6 @@ RED.palette = (function() {
portOutput.remove();
}
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,marked(sf.info||""));
setIcon(paletteNode,sf);
});
}

View File

@@ -49,7 +49,7 @@ RED.projects.settings = (function() {
var tabContainer;
var trayOptions = {
title: "Project Settings",// RED._("menu.label.userSettings"),, // TODO: nls
title: "Project Information",// RED._("menu.label.userSettings"),, // TODO: nls
buttons: [
{
id: "node-dialog-ok",
@@ -143,8 +143,7 @@ RED.projects.settings = (function() {
RED.sidebar.versionControl.refresh(true);
},
400: {
'*': function(error) {
utils.reportUnexpectedError(error);
'unexpected_error': function(error) {
done(error,null);
}
},
@@ -209,8 +208,7 @@ RED.projects.settings = (function() {
done(null,data);
},
400: {
'*': function(error) {
utils.reportUnexpectedError(error);
'unexpected_error': function(error) {
done(error,null);
}
},
@@ -964,7 +962,7 @@ RED.projects.settings = (function() {
var done = function(err) {
spinner.remove();
if (err) {
utils.reportUnexpectedError(err);
console.log(err);
return;
}
flowFileLabelText.text(flowFileInput.val());
@@ -1007,6 +1005,10 @@ RED.projects.settings = (function() {
'credentials_load_failed': function(error) {
done(error);
},
'unexpected_error': function(error) {
console.log(error);
done(error);
},
'missing_current_credential_key': function(error) {
credentialSecretExistingInput.addClass("input-error");
popover = RED.popover.create({
@@ -1017,16 +1019,11 @@ RED.projects.settings = (function() {
autoClose: 3000
}).open();
done(error);
},
'*': function(error) {
done(error);
}
},
}
},payload).always(function() {
setTimeout(function() {
RED.deploy.setDeployInflight(false);
},500);
RED.deploy.setDeployInflight(false);
});
});
var updateForm = function() {
@@ -1145,8 +1142,8 @@ RED.projects.settings = (function() {
]
});
},
'*': function(error) {
utils.reportUnexpectedError(error);
'unexpected_error': function(error) {
console.log(error);
spinner.remove();
}
},
@@ -1196,19 +1193,12 @@ RED.projects.settings = (function() {
editRepoButton.attr('disabled',true);
addRemoteDialog.slideDown(200, function() {
addRemoteDialog[0].scrollIntoView();
if (isEmpty) {
remoteNameInput.val('origin');
remoteURLInput.focus();
} else {
remoteNameInput.focus();
}
validateForm();
});
});
var emptyItem = { empty: true };
var isEmpty = true;
var row = $('<div class="user-settings-row"></div>').appendTo(repoContainer);
var addRemoteDialog = $('<div class="projects-dialog-list-dialog"></div>').hide().appendTo(row);
row = $('<div class="user-settings-row projects-dialog-list"></div>').appendTo(repoContainer);
@@ -1255,14 +1245,6 @@ RED.projects.settings = (function() {
text: 'Delete remote',
click: function() {
notification.close();
if (activeProject.git.branches.remote && activeProject.git.branches.remote.indexOf(entry.name+"/") === 0) {
delete activeProject.git.branches.remote;
}
if (activeProject.git.branches.remoteAlt && activeProject.git.branches.remoteAlt.indexOf(entry.name+"/") === 0) {
delete activeProject.git.branches.remoteAlt;
}
var url = "projects/"+activeProject.name+"/remotes/"+entry.name;
var options = {
url: url,
@@ -1274,7 +1256,6 @@ RED.projects.settings = (function() {
setTimeout(spinner.remove, 100);
if (data.remotes.length === 0) {
delete activeProject.git.remotes;
isEmpty = true;
remotesList.editableList('addItem',emptyItem);
} else {
activeProject.git.remotes = {};
@@ -1284,13 +1265,11 @@ RED.projects.settings = (function() {
activeProject.git.remotes[name] = remote;
});
}
delete activeProject.git.branches.remoteAlt;
RED.sidebar.versionControl.refresh();
});
},
400: {
'*': function(error) {
utils.reportUnexpectedError(error);
'unexpected_error': function(error) {
console.log(error);
spinner.remove();
}
},
@@ -1311,26 +1290,16 @@ RED.projects.settings = (function() {
var validateForm = function() {
var validName = /^[a-zA-Z0-9\-_]+$/.test(remoteNameInput.val());
var repo = remoteURLInput.val();
// var validRepo = /^(?:file|git|ssh|https?|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+(?:\.git)?(?:\/?|\#[\d\w\.\-_]+?)$/.test(remoteURLInput.val());
var validRepo = repo.length > 0 && !/\s/.test(repo);
if (/^https?:\/\/[^/]+@/i.test(repo)) {
remoteURLLabel.text("Do not include the username/password in the url");
validRepo = false;
} else {
remoteURLLabel.text("https://, ssh:// or file://");
}
var validRepo = !/\s/.test(remoteURLInput.val());
saveButton.attr('disabled',(!validName || !validRepo))
remoteNameInput.toggleClass('input-error',remoteNameInputChanged&&!validName);
remoteURLInput.toggleClass('input-error',remoteURLInputChanged&&!validRepo);
if (popover) {
popover.close();
popover = null;
}
};
var popover;
var remoteNameInputChanged = false;
var remoteURLInputChanged = false;
$('<div class="projects-dialog-list-dialog-header">').text('Add remote').appendTo(addRemoteDialog);
@@ -1340,14 +1309,11 @@ RED.projects.settings = (function() {
remoteNameInputChanged = true;
validateForm();
});
var remoteNameInputChanged = false;
$('<label class="projects-edit-form-sublabel"><small>Must contain only A-Z 0-9 _ -</small></label>').appendTo(row).find("small");
row = $('<div class="user-settings-row"></div>').appendTo(addRemoteDialog);
$('<label for=""></label>').text('URL').appendTo(row);
var remoteURLInput = $('<input type="text">').appendTo(row).on("change keyup paste",function() {
remoteURLInputChanged = true;
validateForm()
});
var remoteURLLabel = $('<label class="projects-edit-form-sublabel"><small>https://, ssh:// or file://</small></label>').appendTo(row).find("small");
var remoteURLInput = $('<input type="text">').appendTo(row).on("change keyup paste",validateForm);
var hideEditForm = function() {
editRepoButton.attr('disabled',false);
@@ -1401,7 +1367,6 @@ RED.projects.settings = (function() {
activeProject.git.remotes[name] = remote;
});
updateForm();
RED.sidebar.versionControl.refresh();
done();
},
400: {
@@ -1416,15 +1381,14 @@ RED.projects.settings = (function() {
remoteNameInput.addClass('input-error');
done(error);
},
'*': function(error) {
utils.reportUnexpectedError(error);
'unexpected_error': function(error) {
console.log(error);
done(error);
}
},
}
},payload);
});
var updateForm = function() {
remotesList.editableList('empty');
var count = 0;
@@ -1436,8 +1400,7 @@ RED.projects.settings = (function() {
}
}
}
isEmpty = (count === 0);
if (isEmpty) {
if (count === 0) {
remotesList.editableList('addItem',emptyItem);
}
}

View File

@@ -19,45 +19,7 @@ RED.projects = (function() {
var dialogBody;
var activeProject;
function reportUnexpectedError(error) {
var notification;
if (error.error === 'git_missing_user') {
notification = RED.notify("<p>You Git client is not configured with a username/email.</p>",{
fixed: true,
type:'error',
buttons: [
{
text: "Cancel",
click: function() {
notification.close();
}
},
{
text: "Configure Git client",
click: function() {
RED.userSettings.show('gitconfig');
notification.close();
}
}
]
})
} else {
console.log(error);
notification = RED.notify("<p>An unexpected error occurred:</p><p>"+error.message+"</p><small>code: "+error.error+"</small>",{
fixed: true,
modal: true,
type: 'error',
buttons: [
{
text: "Close",
click: function() {
notification.close();
}
}
]
})
}
}
var screens = {};
function initScreens() {
var migrateProjectHeader = $('<div class="projects-dialog-screen-start-hero"></div>');
@@ -77,28 +39,8 @@ RED.projects = (function() {
var body = $('<div class="projects-dialog-screen-start-body"></div>').appendTo(container);
$('<p>').text("Hello! We have introduced 'projects' to Node-RED.").appendTo(body);
$('<p>').text("This is a new way for you to manage your flow files and includes version control of your flows.").appendTo(body);
$('<p>').text("To get started you can create your first project or clone an existing project from a git repository.").appendTo(body);
$('<p>').text("If you are not sure, you can skip this for now. You will still be able to create your first project from the 'Projects' menu at any time.").appendTo(body);
var row = $('<div style="text-align: center"></div>').appendTo(body);
var createAsEmpty = $('<button data-type="empty" class="editor-button projects-dialog-screen-create-type"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-asterisk"></i><br/>Create Project</button>').appendTo(row);
var createAsClone = $('<button data-type="clone" class="editor-button projects-dialog-screen-create-type"><i class="fa fa-archive fa-2x"></i><i style="position: absolute;" class="fa fa-git"></i><br/>Clone Repository</button>').appendTo(row);
createAsEmpty.click(function(e) {
e.preventDefault();
createProjectOptions = {
action: "create"
}
show('git-config');
})
createAsClone.click(function(e) {
e.preventDefault();
createProjectOptions = {
action: "clone"
}
show('git-config');
})
$('<p>').text("To get started you can create your first project using your current flow files in a few easy steps.").appendTo(body);
$('<p>').text("If you are not sure, you can skip this for now. You will still be able to create your first project from the 'Projects' menu option at any time.").appendTo(body);
return container;
},
@@ -110,6 +52,13 @@ RED.projects = (function() {
createProjectOptions = {};
$( this ).dialog( "close" );
}
},
{
text: "Create your first project", // TODO: nls
class: "primary",
click: function() {
show('git-config');
}
}
]
},
@@ -183,11 +132,7 @@ RED.projects = (function() {
currentGitSettings.user.name = gitUsernameInput.val();
currentGitSettings.user.email = gitEmailInput.val();
RED.settings.set('git', currentGitSettings);
if (createProjectOptions.action === "create") {
show('project-details');
} else if (createProjectOptions.action === "clone") {
show('clone-project');
}
show('project-details');
}
}
]
@@ -320,366 +265,6 @@ RED.projects = (function() {
}
};
})(),
'clone-project': (function() {
var projectNameInput;
var projectSummaryInput;
var projectFlowFileInput;
var projectSecretInput;
var projectSecretSelect;
var copyProject;
var projectRepoInput;
var projectCloneSecret;
var emptyProjectCredentialInput;
var projectRepoUserInput;
var projectRepoPasswordInput;
var projectNameSublabel;
var projectRepoSSHKeySelect;
var projectRepoPassphrase;
var projectRepoRemoteName
var projectRepoBranch;
var selectedProject;
return {
content: function(options) {
var container = $('<div class="projects-dialog-screen-start"></div>');
migrateProjectHeader.appendTo(container);
var body = $('<div class="projects-dialog-screen-start-body"></div>').appendTo(container);
$('<p>').text("Clone a project").appendTo(body);
$('<p>').text("If you already have a git repository containing a project, you can clone it to get started.").appendTo(body);
var projectList = null;
var pendingFormValidation = false;
$.getJSON("projects", function(data) {
projectList = {};
data.projects.forEach(function(p) {
projectList[p] = true;
if (pendingFormValidation) {
pendingFormValidation = false;
validateForm();
}
})
});
var validateForm = function() {
var projectName = projectNameInput.val();
var valid = true;
if (projectNameInputChanged) {
if (projectList === null) {
pendingFormValidation = true;
return;
}
projectNameStatus.empty();
if (!/^[a-zA-Z0-9\-_]+$/.test(projectName) || projectList[projectName]) {
projectNameInput.addClass("input-error");
$('<i style="margin-top: 8px;" class="fa fa-exclamation-triangle"></i>').appendTo(projectNameStatus);
projectNameValid = false;
valid = false;
if (projectList[projectName]) {
projectNameSublabel.text("Project already exists");
} else {
projectNameSublabel.text("Must contain only A-Z 0-9 _ -");
}
} else {
projectNameInput.removeClass("input-error");
$('<i style="margin-top: 8px;" class="fa fa-check"></i>').appendTo(projectNameStatus);
projectNameSublabel.text("Must contain only A-Z 0-9 _ -");
projectNameValid = true;
}
projectNameLastChecked = projectName;
}
valid = projectNameValid;
var repo = projectRepoInput.val();
// var validRepo = /^(?:file|git|ssh|https?|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+(?:\/?|\#[\d\w\.\-_]+?)$/.test(repo);
var validRepo = repo.length > 0 && !/\s/.test(repo);
if (/^https?:\/\/[^/]+@/i.test(repo)) {
$("#projects-dialog-screen-create-project-repo-label small").text("Do not include the username/password in the url");
validRepo = false;
}
if (!validRepo) {
if (projectRepoChanged) {
projectRepoInput.addClass("input-error");
}
valid = false;
} else {
projectRepoInput.removeClass("input-error");
}
if (/^https?:\/\//.test(repo)) {
$(".projects-dialog-screen-create-row-creds").show();
$(".projects-dialog-screen-create-row-sshkey").hide();
} else if (/^(?:ssh|[\S]+?@[\S]+?):(?:\/\/)?/.test(repo)) {
$(".projects-dialog-screen-create-row-creds").hide();
$(".projects-dialog-screen-create-row-sshkey").show();
// if ( !getSelectedSSHKey(projectRepoSSHKeySelect) ) {
// valid = false;
// }
} else {
$(".projects-dialog-screen-create-row-creds").hide();
$(".projects-dialog-screen-create-row-sshkey").hide();
}
$("#projects-dialog-clone-project").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid);
}
var row;
row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-empty projects-dialog-screen-create-row-clone"></div>').appendTo(body);
$('<label for="projects-dialog-screen-create-project-name">Project name</label>').appendTo(row);
var subrow = $('<div style="position:relative;"></div>').appendTo(row);
projectNameInput = $('<input id="projects-dialog-screen-create-project-name" type="text"></input>').appendTo(subrow);
var projectNameStatus = $('<div class="projects-dialog-screen-input-status"></div>').appendTo(subrow);
var projectNameInputChanged = false;
var projectNameLastChecked = "";
var projectNameValid;
var checkProjectName;
var autoInsertedName = "";
projectNameInput.on("change keyup paste",function() {
projectNameInputChanged = (projectNameInput.val() !== projectNameLastChecked);
if (checkProjectName) {
clearTimeout(checkProjectName);
} else if (projectNameInputChanged) {
projectNameStatus.empty();
$('<img src="red/images/spin.svg"/>').appendTo(projectNameStatus);
if (projectNameInput.val() === '') {
validateForm();
return;
}
}
checkProjectName = setTimeout(function() {
validateForm();
checkProjectName = null;
},300)
});
projectNameSublabel = $('<label class="projects-edit-form-sublabel"><small>Must contain only A-Z 0-9 _ -</small></label>').appendTo(row).find("small");
row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-clone"></div>').appendTo(body);
$('<label for="projects-dialog-screen-create-project-repo">Git repository URL</label>').appendTo(row);
projectRepoInput = $('<input id="projects-dialog-screen-create-project-repo" type="text" placeholder="https://git.example.com/path/my-project.git"></input>').appendTo(row);
$('<label id="projects-dialog-screen-create-project-repo-label" class="projects-edit-form-sublabel"><small>https://, ssh:// or file://</small></label>').appendTo(row);
var projectRepoChanged = false;
var lastProjectRepo = "";
projectRepoInput.on("change keyup paste",function() {
projectRepoChanged = true;
var repo = $(this).val();
if (lastProjectRepo !== repo) {
$("#projects-dialog-screen-create-project-repo-label small").text("https://, ssh:// or file://");
}
lastProjectRepo = repo;
var m = /\/([^/]+?)(?:\.git)?$/.exec(repo);
if (m) {
var projectName = projectNameInput.val();
if (projectName === "" || projectName === autoInsertedName) {
autoInsertedName = m[1];
projectNameInput.val(autoInsertedName);
projectNameInput.change();
}
}
validateForm();
});
var cloneAuthRows = $('<div class="projects-dialog-screen-create-row"></div>').appendTo(body);
row = $('<div class="form-row projects-dialog-screen-create-row-auth-error"></div>').hide().appendTo(cloneAuthRows);
$('<div><i class="fa fa-warning"></i> Authentication failed</div>').appendTo(row);
// Repo credentials - username/password ----------------
row = $('<div class="hide form-row projects-dialog-screen-create-row-creds"></div>').hide().appendTo(cloneAuthRows);
var subrow = $('<div style="width: calc(50% - 10px); display:inline-block;"></div>').appendTo(row);
$('<label for="projects-dialog-screen-create-project-repo-user">Username</label>').appendTo(subrow);
projectRepoUserInput = $('<input id="projects-dialog-screen-create-project-repo-user" type="text"></input>').appendTo(subrow);
subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row);
$('<label for="projects-dialog-screen-create-project-repo-pass">Password</label>').appendTo(subrow);
projectRepoPasswordInput = $('<input id="projects-dialog-screen-create-project-repo-pass" type="password"></input>').appendTo(subrow);
// -----------------------------------------------------
// Repo credentials - key/passphrase -------------------
row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-sshkey"></div>').hide().appendTo(cloneAuthRows);
subrow = $('<div style="width: calc(50% - 10px); display:inline-block;"></div>').appendTo(row);
$('<label for="projects-dialog-screen-create-project-repo-passphrase">SSH Key</label>').appendTo(subrow);
projectRepoSSHKeySelect = $("<select>",{style:"width: 100%"}).appendTo(subrow);
$.getJSON("settings/user/keys", function(data) {
var count = 0;
data.keys.forEach(function(key) {
projectRepoSSHKeySelect.append($("<option></option>").val(key.name).text(key.name));
count++;
});
if (count === 0) {
projectRepoSSHKeySelect.addClass("input-error");
projectRepoSSHKeySelect.attr("disabled",true);
sshwarningRow.show();
} else {
projectRepoSSHKeySelect.removeClass("input-error");
projectRepoSSHKeySelect.attr("disabled",false);
sshwarningRow.hide();
}
});
subrow = $('<div style="width: calc(50% - 10px); margin-left: 20px; display:inline-block;"></div>').appendTo(row);
$('<label for="projects-dialog-screen-create-project-repo-passphrase">Passphrase</label>').appendTo(subrow);
projectRepoPassphrase = $('<input id="projects-dialog-screen-create-project-repo-passphrase" type="password"></input>').appendTo(subrow);
subrow = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-sshkey"></div>').appendTo(cloneAuthRows);
var sshwarningRow = $('<div class="projects-dialog-screen-create-row-auth-error-no-keys"></div>').hide().appendTo(subrow);
$('<div class="form-row"><i class="fa fa-warning"></i> Before you can clone a repository over ssh you must add an SSH key to access it.</div>').appendTo(sshwarningRow);
subrow = $('<div style="text-align: center">').appendTo(sshwarningRow);
$('<button class="editor-button">Add an ssh key</button>').appendTo(subrow).click(function(e) {
e.preventDefault();
$('#projects-dialog-cancel').click();
RED.userSettings.show('gitconfig');
setTimeout(function() {
$("#user-settings-gitconfig-add-key").click();
},500);
});
// -----------------------------------------------------
// Secret - clone
row = $('<div class="form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-clone"></div>').appendTo(body);
$('<label>Credentials encryption key</label>').appendTo(row);
projectSecretInput = $('<input type="password"></input>').appendTo(row);
return container;
},
buttons: function(options) {
return [
{
text: "Back",
click: function() {
show('git-config');
}
},
{
id: "projects-dialog-clone-project",
disabled: true,
text: "Clone project", // TODO: nls
class: "primary disabled",
click: function() {
var projectType = $(".projects-dialog-screen-create-type.selected").data('type');
var projectData = {
name: projectNameInput.val(),
}
projectData.credentialSecret = projectSecretInput.val();
var repoUrl = projectRepoInput.val();
var metaData = {};
if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(repoUrl)) {
var selected = projectRepoSSHKeySelect.val();//false;//getSelectedSSHKey(projectRepoSSHKeySelect);
if ( selected ) {
projectData.git = {
remotes: {
'origin': {
url: repoUrl,
keyFile: selected,
passphrase: projectRepoPassphrase.val()
}
}
};
}
else {
console.log("Error! Can't get selected SSH key path.");
return;
}
}
else {
projectData.git = {
remotes: {
'origin': {
url: repoUrl,
username: projectRepoUserInput.val(),
password: projectRepoPasswordInput.val()
}
}
};
}
$(".projects-dialog-screen-create-row-auth-error").hide();
$("#projects-dialog-screen-create-project-repo-label small").text("https://, ssh:// or file://");
projectRepoUserInput.removeClass("input-error");
projectRepoPasswordInput.removeClass("input-error");
projectRepoSSHKeySelect.removeClass("input-error");
projectRepoPassphrase.removeClass("input-error");
RED.deploy.setDeployInflight(true);
RED.projects.settings.switchProject(projectData.name);
sendRequest({
url: "projects",
type: "POST",
handleAuthFail: false,
responses: {
200: function(data) {
dialog.dialog( "close" );
},
400: {
'project_exists': function(error) {
console.log("already exists");
},
'git_error': function(error) {
console.log("git error",error);
},
'git_connection_failed': function(error) {
projectRepoInput.addClass("input-error");
$("#projects-dialog-screen-create-project-repo-label small").text("Connection failed");
},
'git_not_a_repository': function(error) {
projectRepoInput.addClass("input-error");
$("#projects-dialog-screen-create-project-repo-label small").text("Not a git repository");
},
'git_repository_not_found': function(error) {
projectRepoInput.addClass("input-error");
$("#projects-dialog-screen-create-project-repo-label small").text("Repository not found");
},
'git_auth_failed': function(error) {
$(".projects-dialog-screen-create-row-auth-error").show();
projectRepoUserInput.addClass("input-error");
projectRepoPasswordInput.addClass("input-error");
// getRepoAuthDetails(req);
projectRepoSSHKeySelect.addClass("input-error");
projectRepoPassphrase.addClass("input-error");
},
'missing_flow_file': function(error) {
// This is handled via a runtime notification.
dialog.dialog("close");
},
'project_empty': function(error) {
// This is handled via a runtime notification.
dialog.dialog("close");
},
'credentials_load_failed': function(error) {
// This is handled via a runtime notification.
dialog.dialog("close");
},
'*': function(error) {
reportUnexpectedError(error);
$( dialog ).dialog( "close" );
}
}
}
},projectData).then(function() {
RED.events.emit("project:change", {name:name});
}).always(function() {
setTimeout(function() {
RED.deploy.setDeployInflight(false);
},500);
})
}
}
]
}
}
})(),
'default-files': (function() {
var projectFlowFileInput;
var projectCredentialFileInput;
@@ -690,9 +275,9 @@ RED.projects = (function() {
var body = $('<div class="projects-dialog-screen-start-body"></div>').appendTo(container);
$('<p>').text("Create your project files").appendTo(body);
$('<p>').text("A project contains your flow files, a README file and a package.json file.").appendTo(body);
$('<p>').text("A project contains your flow files, a README file, a package.json file and a settings file.").appendTo(body);
$('<p>').text("It can contain any other files you want to maintain in the Git repository.").appendTo(body);
if (!options.existingProject && RED.settings.files) {
if (!options.existingProject) {
$('<p>').text("Your existing flow and credential files will be copied into the project.").appendTo(body);
}
@@ -726,14 +311,14 @@ RED.projects = (function() {
var row = $('<div class="form-row"></div>').appendTo(body);
$('<label for="projects-dialog-screen-create-project-file">Flow file</label>').appendTo(row);
var subrow = $('<div style="position:relative;"></div>').appendTo(row);
var defaultFlowFile = (createProjectOptions.files &&createProjectOptions.files.flow) || (RED.settings.files && RED.settings.files.flow)||"flow.json";
var defaultFlowFile = (createProjectOptions.files &&createProjectOptions.files.flow) || RED.settings.files.flow||"flow.json";
projectFlowFileInput = $('<input id="projects-dialog-screen-create-project-file" type="text">').val(defaultFlowFile)
.on("change keyup paste",validateForm)
.appendTo(subrow);
$('<div class="projects-dialog-screen-input-status"></div>').appendTo(subrow);
$('<label class="projects-edit-form-sublabel"><small>*.json</small></label>').appendTo(row);
var defaultCredentialsFile = (createProjectOptions.files &&createProjectOptions.files.credentials) || (RED.settings.files && RED.settings.files.credentials)||"flow_cred.json";
var defaultCredentialsFile = (createProjectOptions.files &&createProjectOptions.files.credentials) || RED.settings.files.credentials||"flow_cred.json";
row = $('<div class="form-row"></div>').appendTo(body);
$('<label for="projects-dialog-screen-create-project-credfile">Credentials file</label>').appendTo(row);
subrow = $('<div style="position:relative;"></div>').appendTo(row);
@@ -961,7 +546,6 @@ RED.projects = (function() {
} else {
show('create-success');
RED.menu.setDisabled('menu-item-projects-open',false);
RED.menu.setDisabled('menu-item-projects-settings',false);
}
},
400: {
@@ -980,9 +564,8 @@ RED.projects = (function() {
// getRepoAuthDetails(req);
console.log("git auth error",error);
},
'*': function(error) {
reportUnexpectedError(error);
$( dialog ).dialog( "close" );
'unexpected_error': function(error) {
console.log("unexpected_error",error)
}
}
}
@@ -1031,7 +614,6 @@ RED.projects = (function() {
var projectSecretSelect;
var copyProject;
var projectRepoInput;
var projectCloneSecret;
var emptyProjectCredentialInput;
var projectRepoUserInput;
var projectRepoPasswordInput;
@@ -1100,11 +682,7 @@ RED.projects = (function() {
var repo = projectRepoInput.val();
// var validRepo = /^(?:file|git|ssh|https?|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+(?:\/?|\#[\d\w\.\-_]+?)$/.test(repo);
var validRepo = repo.length > 0 && !/\s/.test(repo);
if (/^https?:\/\/[^/]+@/i.test(repo)) {
$("#projects-dialog-screen-create-project-repo-label small").text("Do not include the username/password in the url");
validRepo = false;
}
var validRepo = !/\s/.test(repo);
if (!validRepo) {
if (projectRepoChanged) {
projectRepoInput.addClass("input-error");
@@ -1191,11 +769,7 @@ RED.projects = (function() {
validateForm();
},
delete: function(project) {
if (projectList) {
delete projectList[project.name];
}
selectedProject = null;
validateForm();
}
}).appendTo(row);
@@ -1397,12 +971,10 @@ RED.projects = (function() {
// -----------------------------------------------------
// Secret - clone
row = $('<div class="hide form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-clone"></div>').appendTo(container);
$('<label>Credentials encryption key</label>').appendTo(row);
projectSecretInput = $('<input type="password"></input>').appendTo(row);
// // Secret - clone
// row = $('<div class="hide form-row projects-dialog-screen-create-row projects-dialog-screen-create-row-clone"></div>').appendTo(container);
// $('<label>Credentials encryption key</label>').appendTo(row);
// projectSecretInput = $('<input type="text"></input>').appendTo(row);
switch(options.screen||"empty") {
case "empty": createAsEmpty.click(); break;
case "open": openProject.click(); break;
@@ -1460,7 +1032,7 @@ RED.projects = (function() {
} else if (projectType === 'copy') {
projectData.copy = copyProject.name;
} else if (projectType === 'clone') {
projectData.credentialSecret = projectSecretInput.val();
// projectData.credentialSecret = projectSecretInput.val();
var repoUrl = projectRepoInput.val();
var metaData = {};
if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(repoUrl)) {
@@ -1504,13 +1076,13 @@ RED.projects = (function() {
}
$(".projects-dialog-screen-create-row-auth-error").hide();
$("#projects-dialog-screen-create-project-repo-label small").text("https://, ssh:// or file://");
projectRepoUserInput.removeClass("input-error");
projectRepoPasswordInput.removeClass("input-error");
projectRepoSSHKeySelect.removeClass("input-error");
projectRepoPassphrase.removeClass("input-error");
RED.deploy.setDeployInflight(true);
RED.projects.settings.switchProject(projectData.name);
@@ -1550,10 +1122,6 @@ RED.projects = (function() {
projectRepoSSHKeySelect.addClass("input-error");
projectRepoPassphrase.addClass("input-error");
},
'missing_flow_file': function(error) {
// This is handled via a runtime notification.
dialog.dialog("close");
},
'project_empty': function(error) {
// This is handled via a runtime notification.
dialog.dialog("close");
@@ -1562,9 +1130,8 @@ RED.projects = (function() {
// This is handled via a runtime notification.
dialog.dialog("close");
},
'*': function(error) {
reportUnexpectedError(error);
$( dialog ).dialog( "close" );
'unexpected_error': function(error) {
console.log("unexpected_error",error)
}
}
}
@@ -1950,7 +1517,7 @@ RED.projects = (function() {
'</div>');
var isSSH = false;
if (/^https?:\/\//.test(url)) {
if (/^https?:\/\//) {
$('<div class="form-row"><label for="projects-user-auth-username">Username</label><input id="projects-user-auth-username" type="text"></input></div>'+
'<div class="form-row"><label for=projects-user-auth-password">Password</label><input id="projects-user-auth-password" type="password"></input></div>').appendTo(message);
} else if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(url)) {
@@ -2171,17 +1738,8 @@ RED.projects = (function() {
},Math.max(300-(Date.now() - start),0));
},
400: {
'git_connection_failed': function(error) {
RED.notify(error.message,'error');
},
'git_not_a_repository': function(error) {
RED.notify(error.message,'error');
},
'git_repository_not_found': function(error) {
RED.notify(error.message,'error');
},
'unexpected_error': function(error) {
reportUnexpectedError(error);
console.log(error);
}
}
}
@@ -2224,12 +1782,11 @@ RED.projects = (function() {
RED.actions.add("core:new-project",RED.projects.newProject);
RED.actions.add("core:open-project",RED.projects.selectProject);
RED.actions.add("core:show-project-settings",RED.projects.settings.show);
var projectsAPI = {
sendRequest:sendRequest,
createBranchList:createBranchList,
addSpinnerOverlay:addSpinnerOverlay,
reportUnexpectedError:reportUnexpectedError
addSpinnerOverlay:addSpinnerOverlay
};
RED.projects.settings.init(projectsAPI);
RED.projects.userSettings.init(projectsAPI);
@@ -2251,43 +1808,6 @@ RED.projects = (function() {
createProjectOptions = {};
show('default-files',{existingProject: true});
}
function createDefaultPackageFile() {
RED.deploy.setDeployInflight(true);
RED.projects.settings.switchProject(activeProject.name);
var method = "PUT";
var url = "projects/"+activeProject.name;
var createProjectOptions = {
initialise: true
};
sendRequest({
url: url,
type: method,
requireCleanWorkspace: true,
handleAuthFail: false,
responses: {
200: function(data) { },
400: {
'git_error': function(error) {
console.log("git error",error);
},
'missing_flow_file': function(error) {
// This is a natural next error - but let the runtime event
// trigger the dialog rather than double-report it.
$( dialog ).dialog( "close" );
},
'*': function(error) {
reportUnexpectedError(error);
$( dialog ).dialog( "close" );
}
}
}
},createProjectOptions).always(function() {
setTimeout(function() {
RED.deploy.setDeployInflight(false);
},500);
})
}
function refresh(done) {
$.getJSON("projects",function(data) {
@@ -2367,7 +1887,6 @@ RED.projects = (function() {
RED.projects.settings.show('deps');
},
createDefaultFileSet: createDefaultFileSet,
createDefaultPackageFile: createDefaultPackageFile,
// showSidebar: showSidebar,
refresh: refresh,
editProject: function() {

View File

@@ -30,6 +30,7 @@ RED.sidebar.versionControl = (function() {
var unmergedContent;
var unmergedChangesList;
var commitButton;
var mergeConflictNotification;
var localChanges;
var localCommitList;
@@ -50,6 +51,10 @@ RED.sidebar.versionControl = (function() {
// done(error,null);
},
200: function(data) {
if (mergeConflictNotification) {
mergeConflictNotification.close();
mergeConflictNotification = null;
}
var title;
if (state === 'unstaged') {
title = 'Unstaged changes : '+entry.file
@@ -75,11 +80,6 @@ RED.sidebar.versionControl = (function() {
options.oldRev = "@";
options.newRev = ":0";
} else {
options.oldRevTitle = "Local";
options.newRevTitle = "Remote";
options.commonRev = ":1";
options.oldRev = ":2";
options.newRev = ":3";
options.onresolve = function(resolution) {
utils.sendRequest({
url: "projects/"+activeProject.name+"/resolve/"+encodeURIComponent(entry.file),
@@ -102,7 +102,9 @@ RED.sidebar.versionControl = (function() {
},{resolutions:resolution.resolutions[entry.file]});
}
}
options.oncancel = showMergeConflictNotification;
RED.diff.showUnifiedDiff(options);
// console.log(data.diff);
},
400: {
'unexpected_error': function(error) {
@@ -120,18 +122,6 @@ RED.sidebar.versionControl = (function() {
if (entry.label) {
row.addClass('node-info-none');
container.text(entry.label);
if (entry.button) {
container.css({
display: "inline-block",
maxWidth: "300px",
textAlign: "left"
})
var toolbar = $('<div style="float: right; margin: 5px; height: 50px;"></div>').appendTo(container);
$('<button class="editor-button editor-button-small"></button>').text(entry.button.label)
.appendTo(toolbar)
.click(entry.button.click);
}
return;
}
@@ -154,7 +144,6 @@ RED.sidebar.versionControl = (function() {
.appendTo(bg)
.click(function(evt) {
evt.preventDefault();
var spinner = utils.addSpinnerOverlay(container).addClass('projects-dialog-spinner-contain');
var notification = RED.notify("Are you sure you want to revert the changes to '"+entry.file+"'? This cannot be undone.", {
type: "warning",
@@ -189,12 +178,7 @@ RED.sidebar.versionControl = (function() {
}
}
}
RED.deploy.setDeployInflight(true);
utils.sendRequest(options).always(function() {
setTimeout(function() {
RED.deploy.setDeployInflight(false);
},500);
});
utils.sendRequest(options);
}
}
@@ -368,7 +352,6 @@ RED.sidebar.versionControl = (function() {
evt.stopPropagation();
var spinner = utils.addSpinnerOverlay(unmergedContent);
var activeProject = RED.projects.getActiveProject();
RED.deploy.setDeployInflight(true);
utils.sendRequest({
url: "projects/"+activeProject.name+"/merge",
type: "DELETE",
@@ -386,10 +369,6 @@ RED.sidebar.versionControl = (function() {
}
},
}
}).always(function() {
setTimeout(function() {
RED.deploy.setDeployInflight(false);
},500);
});
});
unmergedChangesList = $("<ol>",{style:"position: absolute; top: 30px; bottom: 0; right:0; left:0;"}).appendTo(unmergedContent);
@@ -397,16 +376,6 @@ RED.sidebar.versionControl = (function() {
addButton: false,
scrollOnAdd: false,
addItem: function(row,index,entry) {
if (entry === emptyMergedItem) {
entry.button = {
label: 'commit',
click: function(evt) {
evt.preventDefault();
evt.stopPropagation();
showCommitBox();
}
}
}
createChangeEntry(row,entry,entry.treeStatus,'unmerged');
},
sort: function(A,B) {
@@ -426,32 +395,28 @@ RED.sidebar.versionControl = (function() {
header = $('<div class="sidebar-version-control-change-header">Changes to commit</div>').appendTo(stagedContent);
bg = $('<div style="float: right"></div>').appendTo(header);
var showCommitBox = function() {
commitMessage.val("");
submitCommitButton.attr("disabled",true);
unstagedContent.css("height","30px");
if (unmergedContent.is(":visible")) {
unmergedContent.css("height","30px");
stagedContent.css("height","calc(100% - 60px - 175px)");
} else {
stagedContent.css("height","calc(100% - 30px - 175px)");
}
commitBox.show();
setTimeout(function() {
commitBox.css("height","175px");
},10);
stageAllButton.attr("disabled",true);
unstageAllButton.attr("disabled",true);
commitButton.attr("disabled",true);
abortMergeButton.attr("disabled",true);
commitMessage.focus();
}
commitButton = $('<button class="editor-button editor-button-small" style="margin-right: 5px;">commit</button>')
.appendTo(bg)
.click(function(evt) {
evt.preventDefault();
evt.stopPropagation();
showCommitBox();
commitMessage.val("");
submitCommitButton.attr("disabled",true);
unstagedContent.css("height","30px");
if (unmergedContent.is(":visible")) {
unmergedContent.css("height","30px");
stagedContent.css("height","calc(100% - 60px - 175px)");
} else {
stagedContent.css("height","calc(100% - 30px - 175px)");
}
commitBox.show();
setTimeout(function() {
commitBox.css("height","175px");
},10);
stageAllButton.attr("disabled",true);
unstageAllButton.attr("disabled",true);
commitButton.attr("disabled",true);
commitMessage.focus();
});
unstageAllButton = $('<button class="editor-button editor-button-small"><i class="fa fa-minus"></i> all</button>')
.appendTo(bg)
@@ -480,7 +445,7 @@ RED.sidebar.versionControl = (function() {
commitBox = $('<div class="sidebar-version-control-slide-box sidebar-version-control-slide-box-bottom"></div>').hide().appendTo(localChanges.content);
var commitMessage = $('<textarea placeholder="Enter your commit message"></textarea>')
var commitMessage = $('<textarea>')
.appendTo(commitBox)
.on("change keyup paste",function() {
submitCommitButton.attr('disabled',$(this).val().trim()==="");
@@ -502,8 +467,6 @@ RED.sidebar.versionControl = (function() {
stageAllButton.attr("disabled",false);
unstageAllButton.attr("disabled",false);
commitButton.attr("disabled",false);
abortMergeButton.attr("disabled",false);
})
var submitCommitButton = $('<button class="editor-button">Commit</button>')
.appendTo(commitToolbar)
@@ -511,7 +474,6 @@ RED.sidebar.versionControl = (function() {
evt.preventDefault();
var spinner = utils.addSpinnerOverlay(submitCommitButton).addClass('projects-dialog-spinner-sidebar');
var activeProject = RED.projects.getActiveProject();
RED.deploy.setDeployInflight(true);
utils.sendRequest({
url: "projects/"+activeProject.name+"/commit",
type: "POST",
@@ -525,18 +487,17 @@ RED.sidebar.versionControl = (function() {
refresh(true);
},
400: {
'*': function(error) {
utils.reportUnexpectedError(error);
'unexpected_error': function(error) {
console.log(error);
}
},
}
},{
message:commitMessage.val()
}).always(function() {
setTimeout(function() {
RED.deploy.setDeployInflight(false);
},500);
})
});
})
@@ -550,7 +511,7 @@ RED.sidebar.versionControl = (function() {
.appendTo(bg)
.click(function(evt) {
evt.preventDefault();
refresh(true,true);
refresh(true);
})
var localBranchToolbar = $('<div class="sidebar-version-control-change-header" style="text-align: right;"></div>').appendTo(localHistory.content);
@@ -592,10 +553,7 @@ RED.sidebar.versionControl = (function() {
closeBranchBox();
localCommitListShade.show();
$(this).addClass('selected');
var activeProject = RED.projects.getActiveProject();
$("#sidebar-version-control-repo-toolbar-set-upstream-row").toggle(!!activeProject.git.branches.remoteAlt);
remoteBox.show();
setTimeout(function() {
remoteBox.css("height","265px");
},100);
@@ -791,13 +749,7 @@ RED.sidebar.versionControl = (function() {
},
400: {
'git_connection_failed': function(error) {
RED.notify(error.message,'error');
},
'git_not_a_repository': function(error) {
RED.notify(error.message,'error');
},
'git_repository_not_found': function(error) {
RED.notify(error.message,'error');
RED.notify(error.message);
},
'unexpected_error': function(error) {
console.log(error);
@@ -871,8 +823,7 @@ RED.sidebar.versionControl = (function() {
if (activeProject.git.branches.remoteAlt) {
url+="/"+activeProject.git.branches.remoteAlt;
}
var setUpstream = $("#sidebar-version-control-repo-toolbar-set-upstream").prop('checked');
if (setUpstream) {
if ($("#sidebar-version-control-repo-toolbar-set-upstream").prop('checked')) {
url+="?u=true"
}
utils.sendRequest({
@@ -884,10 +835,6 @@ RED.sidebar.versionControl = (function() {
// done(error,null);
},
200: function(data) {
if (setUpstream && activeProject.git.branches.remoteAlt) {
activeProject.git.branches.remote = activeProject.git.branches.remoteAlt;
delete activeProject.git.branches.remoteAlt;
}
refresh(true);
closeRemoteBox();
},
@@ -907,91 +854,54 @@ RED.sidebar.versionControl = (function() {
});
});
var pullRemote = function(options) {
options = options || {};
var spinner = utils.addSpinnerOverlay(remoteBox).addClass("projects-dialog-spinner-contain");
var activeProject = RED.projects.getActiveProject();
var url = "projects/"+activeProject.name+"/pull";
if (activeProject.git.branches.remoteAlt) {
url+="/"+activeProject.git.branches.remoteAlt;
}
if (options.setUpstream || options.allowUnrelatedHistories) {
url+="?";
}
if (options.setUpstream) {
url += "setUpstream=true"
if (options.allowUnrelatedHistories) {
url += "&";
}
}
if (options.allowUnrelatedHistories) {
url += "allowUnrelatedHistories=true"
}
utils.sendRequest({
url: url,
type: "POST",
responses: {
0: function(error) {
console.log(error);
// done(error,null);
},
200: function(data) {
if (options.setUpstream && activeProject.git.branches.remoteAlt) {
activeProject.git.branches.remote = activeProject.git.branches.remoteAlt;
delete activeProject.git.branches.remoteAlt;
}
refresh(true);
closeRemoteBox();
},
400: {
'git_local_overwrite': function(err) {
RED.notify("<p>Unable to pull remote changes; your unstaged local changes would be overwritten.</p><p>Commit your changes and try again.</p>"+
'<p><a href="#" onclick="RED.sidebar.versionControl.showLocalChanges(); return false;">'+'Show unstaged changes'+'</a></p>',"error",false,10000000);
},
'git_pull_merge_conflict': function(err) {
refresh(true);
closeRemoteBox();
},
'git_connection_failed': function(err) {
RED.notify("Could not connect to remote repository: "+err.toString(),"warning")
},
'git_pull_unrelated_history': function(error) {
var notification = RED.notify("<p>The remote has an unrelated history of commits.</p><p>Are you sure you want to pull the changes into your local repository?</p>",{
type: 'error',
modal: true,
fixed: true,
buttons: [
{
text: RED._("common.label.cancel"),
click: function() {
notification.close();
}
},{
text: 'Pull changes',
click: function() {
notification.close();
options.allowUnrelatedHistories = true;
pullRemote(options)
}
}
]
});
},
'*': function(error) {
utils.reportUnexpectedError(error);
}
},
}
},{}).always(function() {
spinner.remove();
});
}
$('<button id="sidebar-version-control-repo-pull" class="sidebar-version-control-repo-sub-action editor-button"><i class="fa fa-long-arrow-down"></i> <span>pull</span></button>')
.appendTo(row)
.click(function(e) {
e.preventDefault();
pullRemote({
setUpstream: $("#sidebar-version-control-repo-toolbar-set-upstream").prop('checked')
var spinner = utils.addSpinnerOverlay(remoteBox).addClass("projects-dialog-spinner-contain");
var activeProject = RED.projects.getActiveProject();
var url = "projects/"+activeProject.name+"/pull";
if (activeProject.git.branches.remoteAlt) {
url+="/"+activeProject.git.branches.remoteAlt;
}
if ($("#sidebar-version-control-repo-toolbar-set-upstream").prop('checked')) {
url+="?u=true"
}
utils.sendRequest({
url: url,
type: "POST",
responses: {
0: function(error) {
console.log(error);
// done(error,null);
},
200: function(data) {
refresh(true);
closeRemoteBox();
},
400: {
'git_local_overwrite': function(err) {
RED.notify("Unable to pull remote changes; your unstaged local changes would be overwritten. Commit your changes and try again."+
'<p><a href="#" onclick="RED.sidebar.versionControl.showLocalChanges(); return false;">'+'Show unstaged changes'+'</a></p>',"error",false,10000000);
},
'git_pull_merge_conflict': function(err) {
refresh(true);
},
'git_connection_failed': function(err) {
RED.notify("Could not connect to remote repository: "+err.toString(),"warning")
},
'unexpected_error': function(error) {
console.log(error);
// done(error,null);
},
'git_pull_unrelated_history': function(error) {
RED.notify("Unable to pull remote changes; refusing to merge unrelated histories.","error");
}
},
}
},{}).always(function() {
spinner.remove();
});
});
@@ -1129,6 +1039,16 @@ RED.sidebar.versionControl = (function() {
// }
// }
function showMergeConflictNotification() {
if (isMerging) {
mergeConflictNotification = RED.notify("NLS: Automatic merging of remote changes failed. Fix the unmerged conflicts then commit the results."+
'<p><a href="#" onclick="RED.sidebar.versionControl.showLocalChanges(); return false;">'+'Show merge conflicts'+'</a></p>',"error",true);
}
}
function refreshFiles(result) {
var files = result.files;
if (bulkChangeSpinner) {
@@ -1137,9 +1057,16 @@ RED.sidebar.versionControl = (function() {
}
isMerging = !!result.merging;
if (isMerging) {
if (!mergeConflictNotification) {
showMergeConflictNotification();
}
sidebarContent.addClass("sidebar-version-control-merging");
unmergedContent.show();
} else {
if (mergeConflictNotification) {
mergeConflictNotification.close();
mergeConflictNotification = null;
}
sidebarContent.removeClass("sidebar-version-control-merging");
unmergedContent.hide();
}
@@ -1246,7 +1173,7 @@ RED.sidebar.versionControl = (function() {
}
}
function refresh(full, includeRemote) {
function refresh(full) {
if (refreshInProgress) {
return;
}
@@ -1266,11 +1193,7 @@ RED.sidebar.versionControl = (function() {
var activeProject = RED.projects.getActiveProject();
if (activeProject) {
var url = "projects/"+activeProject.name+"/status";
if (includeRemote) {
url += "?remote=true"
}
$.getJSON(url,function(result) {
$.getJSON("projects/"+activeProject.name+"/status",function(result) {
refreshFiles(result);
$('#sidebar-version-control-local-branch').text(result.branches.local);
@@ -1314,8 +1237,6 @@ RED.sidebar.versionControl = (function() {
}
refreshInProgress = false;
$('.sidebar-version-control-shade').hide();
}).fail(function() {
refreshInProgress = false;
});
} else {
$('.sidebar-version-control-shade').show();

View File

@@ -476,7 +476,7 @@ RED.utils = (function() {
for (i=0;i<keys.length;i++) {
var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(element);
var newPath = path;
if (newPath !== undefined) {
if (newPath) {
if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(keys[i])) {
newPath += (newPath.length > 0?".":"")+keys[i];
} else {
@@ -708,9 +708,7 @@ RED.utils = (function() {
function getDefaultNodeIcon(def,node) {
var icon_url;
if (node && node.type === "subflow") {
icon_url = "node-red/subflow.png";
} else if (typeof def.icon === "function") {
if (typeof def.icon === "function") {
try {
icon_url = def.icon.call(node);
} catch(err) {
@@ -723,26 +721,11 @@ RED.utils = (function() {
var iconPath = separateIconPath(icon_url);
if (!iconPath.module) {
if (def.set) {
iconPath.module = def.set.module;
} else {
// Handle subflow instance nodes that don't have def.set
iconPath.module = "node-red";
}
iconPath.module = def.set.module;
}
return iconPath;
}
function isIconExists(iconPath) {
var iconSets = RED.nodes.getIconSets();
var iconFileList = iconSets[iconPath.module];
if (iconFileList && iconFileList.indexOf(iconPath.file) !== -1) {
return true;
} else {
return false;
}
}
function getNodeIcon(def,node) {
if (def.category === 'config') {
return "icons/node-red/cog.png"
@@ -750,19 +733,18 @@ RED.utils = (function() {
return "icons/node-red/subflow.png"
} else if (node && node.type === 'unknown') {
return "icons/node-red/alert.png"
} else if (node && node.type === 'subflow') {
return "icons/node-red/subflow.png"
} else if (node && node.icon) {
var iconPath = separateIconPath(node.icon);
if (isIconExists(iconPath)) {
var iconSets = RED.nodes.getIconSets();
var iconFileList = iconSets[iconPath.module];
if (iconFileList && iconFileList.indexOf(iconPath.file) !== -1) {
return "icons/" + node.icon;
}
}
var iconPath = getDefaultNodeIcon(def, node);
if (def.category === 'subflows') {
if (!isIconExists(iconPath)) {
return "icons/node-red/subflow.png";
}
}
return "icons/"+iconPath.module+"/"+iconPath.file;
}

View File

@@ -490,7 +490,6 @@ RED.view = (function() {
}
} else {
var subflow = RED.nodes.subflow(m[1]);
nn.name = "";
nn.inputs = subflow.in.length;
nn.outputs = subflow.out.length;
}

View File

@@ -43,7 +43,7 @@ RED.workspaces = (function() {
return ws;
}
function deleteWorkspace(ws) {
if (workspaceTabCount === 1) {
if (workspace_tabs.count() == 1) {
return;
}
removeWorkspace(ws);
@@ -65,7 +65,7 @@ RED.workspaces = (function() {
buttons: [
{
id: "node-dialog-delete",
class: 'leftButton'+((workspaceTabCount === 1)?" disabled":""),
class: 'leftButton'+((workspace_tabs.count() == 1)?" disabled":""),
text: RED._("common.label.delete"), //'<i class="fa fa-trash"></i>',
click: function() {
deleteWorkspace(workspace);
@@ -214,7 +214,6 @@ RED.workspaces = (function() {
var workspace_tabs;
var workspaceTabCount = 0;
function createWorkspaceTabs() {
workspace_tabs = RED.tabs.create({
id: "workspace-tabs",
@@ -241,24 +240,18 @@ RED.workspaces = (function() {
}
},
onadd: function(tab) {
if (tab.type === "tab") {
workspaceTabCount++;
}
$('<span class="workspace-disabled-icon"><i class="fa fa-ban"></i> </span>').prependTo("#red-ui-tab-"+(tab.id.replace(".","-"))+" .red-ui-tab-label");
if (tab.disabled) {
$("#red-ui-tab-"+(tab.id.replace(".","-"))).addClass('workspace-disabled');
}
RED.menu.setDisabled("menu-item-workspace-delete",workspaceTabCount <= 1);
if (workspaceTabCount === 1) {
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() <= 1);
if (workspace_tabs.count() === 1) {
showWorkspace();
}
},
onremove: function(tab) {
if (tab.type === "tab") {
workspaceTabCount--;
}
RED.menu.setDisabled("menu-item-workspace-delete",workspaceTabCount <= 1);
if (workspaceTabCount === 0) {
RED.menu.setDisabled("menu-item-workspace-delete",workspace_tabs.count() <= 1);
if (workspace_tabs.count() === 0) {
hideWorkspace();
}
},
@@ -273,7 +266,6 @@ RED.workspaces = (function() {
addWorkspace();
}
});
workspaceTabCount = 0;
}
function showWorkspace() {
$("#workspace .red-ui-tabs").show()
@@ -342,7 +334,7 @@ RED.workspaces = (function() {
return workspace_tabs.contains(id);
},
count: function() {
return workspaceTabCount;
return workspace_tabs.count();
},
active: function() {
return activeWorkspace

View File

@@ -113,8 +113,8 @@
.debug-message-meta {
background: #fff;
font-size: 11px;
color: #707070;
font-size: 10px;
color: #777;
}
.debug-message-date {
padding: 1px 5px 1px 1px;
@@ -125,7 +125,7 @@
}
.debug-message-name {
padding: 1px 5px;
color: #707070;
color: #777;
}
.debug-message-tools {
position: absolute;
@@ -159,7 +159,7 @@
.debug-message-element {
color: #333;
font-family: Menlo, monospace;
font-size: 13px !important;
font-size: 12px !important;
line-height: 1.3em;
}
.debug-message-object-key {
@@ -188,9 +188,11 @@
.debug-message-element.collapsed>span>.debug-message-object-handle {
transform: rotate(0deg);
}
.debug-message-object-entry.collapsed > .debug-message-object-entry {
display:none;
}
.debug-message-element.collapsed .debug-message-object-entry {
display:none;
}
@@ -200,13 +202,14 @@
.debug-message-element.collapsed .debug-message-buffer-opts {
display: none;
}
.debug-message-element.collapsed .debug-message-object-type-header {
display:none;
}
.debug-message-object-entry pre {
font-family: Menlo, monospace;
font-size: 13px;
line-height: 1.2em;
font-size: 12px;
line-height: 1.4em;
margin: 0 0 0 -1em;
}

View File

@@ -16,16 +16,17 @@
.node-dialog-view-diff-panel {
padding: 5px;
padding-top: 30px;
position: relative;
.red-ui-editableList-container {
border-radius:1px;
padding:0;
background: #f9f9f9;
}
.node-dialog-view-diff-diff {
position: absolute;
top:30px;
bottom:10px;
left:10px;
right:10px;
li {
background: #f9f9f9;
padding: 0px;
@@ -37,20 +38,21 @@
padding: 5px;
// padding-bottom: 5px;
}
}
.node-diff-container {
position: absolute;
top: 40px;
right:0;
bottom: 0;
left: 0;
overflow-y: scroll;
&.node-dialog-view-diff-panel-merge {
.node-dialog-view-diff-diff {
top: 80px
}
.node-dialog-view-diff-headers {
top: 55px;
}
}
}
.node-dialog-view-diff-headers {
position: absolute;
left:232px;
right:12px;
left:237px;
right:18px;
top: 5px;
height: 25px;
div {
@@ -74,6 +76,11 @@
}
.node-diff-toolbar {
position:absolute;
top:0;
left:0;
right:0;
height: 43px;
box-sizing: border-box;
color: #666;
text-align: right;
@@ -548,129 +555,129 @@ ul.node-dialog-configm-deploy-list {
.node-text-diff {
height: 100%;
overflow-y:auto;
table.node-text-diff-content {
table {
margin: 10px;
border: 1px solid $secondary-border-color;
border-radius: 3px;
table-layout: fixed;
width: calc(100% - 20px);
td {
vertical-align: top;
word-wrap: break-word;
}
td.lineno {
font-family: monospace;
text-align: right;
color: #aaa;
background: #f6f6f6;
padding: 1px 5px;
}
td.lineno:nth-child(3) {
border-left: 1px solid $secondary-border-color;
}
td.linetext {
font-family: monospace;
white-space: pre-wrap;
padding: 1px 5px;
span.prefix {
width: 30px;
display: inline-block;
text-align: center;
color: #999;
}
}
td.blank {
background: #f6f6f6;
}
td.added {
background: #eefaee;
}
td.removed {
background: #fadddd;
}
tr.mergeHeader td {
color: #800080;
background: #e5f9ff;
height: 26px;
vertical-align: middle;
}
tr.mergeHeader-separator td {
color: #800080;
background: darken(#e5f9ff, 10%);
height: 0px;
}
tr.mergeHeader-ours td {
border-top: 2px solid darken(#e5f9ff, 10%);
}
tr.mergeHeader-theirs td {
border-bottom: 2px solid darken(#e5f9ff, 10%);
}
td.unchanged {
}
td {
vertical-align: top;
word-wrap: break-word;
}
td.lineno {
font-family: monospace;
text-align: right;
color: #aaa;
background: #f6f6f6;
padding: 1px 5px;
}
td.lineno:nth-child(3) {
border-left: 1px solid $secondary-border-color;
}
td.linetext {
font-family: monospace;
white-space: pre-wrap;
padding: 1px 5px;
span.prefix {
width: 30px;
display: inline-block;
text-align: center;
color: #999;
}
tr.unchanged {
background: #fefefe;
}
tr.start-block {
border-top: 1px solid #f0f0f0;
}
tr.end-block {
border-bottom: 1px solid #f0f0f0;
}
tr.node-text-diff-file-header td {
.filename {
font-family: monospace;
}
background: #f3f3f3;
padding: 5px 10px 5px 0;
color: #333;
cursor: pointer;
i.node-diff-chevron {
width: 30px;
}
}
tr.node-text-diff-file-header.collapsed {
td i.node-diff-chevron {
transform: rotate(-90deg);
}
}
tr.node-text-diff-commit-header td {
background: #f3f3f3;
padding: 5px 10px;
color: #333;
h3 {
font-size: 1.4em;
margin: 0;
}
.commit-summary {
border-top: 1px solid $secondary-border-color;
padding-top: 5px;
color: #999;
}
.commit-body {
margin-bottom:15px;
white-space: pre;
line-height: 1.2em;
}
}
tr.node-text-diff-header > td:not(.flow-diff) {
}
td.blank {
background: #f6f6f6;
}
td.added {
background: #eefaee;
}
td.removed {
background: #fadddd;
}
tr.mergeHeader td {
color: #800080;
background: #e5f9ff;
height: 26px;
vertical-align: middle;
}
tr.mergeHeader-separator td {
color: #800080;
background: darken(#e5f9ff, 10%);
height: 0px;
}
tr.mergeHeader-ours td {
border-top: 2px solid darken(#e5f9ff, 10%);
}
tr.mergeHeader-theirs td {
border-bottom: 2px solid darken(#e5f9ff, 10%);
}
td.unchanged {
color: #999;
}
tr.unchanged {
background: #fefefe;
}
tr.start-block {
border-top: 1px solid #f0f0f0;
}
tr.end-block {
border-bottom: 1px solid #f0f0f0;
}
tr.node-text-diff-file-header td {
.filename {
font-family: monospace;
padding: 5px 10px;
text-align: left;
color: #666;
background: #ffd;
height: 30px;
vertical-align: middle;
border-top: 1px solid #f0f0f0;
border-bottom: 1px solid #f0f0f0;
}
tr.node-text-diff-expand td {
cursor: pointer;
&:hover {
background: #ffc;
}
background: #f3f3f3;
padding: 5px 10px 5px 0;
color: #333;
cursor: pointer;
i.node-diff-chevron {
width: 30px;
}
}
tr.node-text-diff-file-header.collapsed {
td i.node-diff-chevron {
transform: rotate(-90deg);
}
}
tr.node-text-diff-commit-header td {
background: #f3f3f3;
padding: 5px 10px;
color: #333;
h3 {
font-size: 1.4em;
margin: 0;
}
.commit-summary {
border-top: 1px solid $secondary-border-color;
padding-top: 5px;
color: #999;
}
.commit-body {
margin-bottom:15px;
white-space: pre;
line-height: 1.2em;
}
}
tr.node-text-diff-header td {
font-family: monospace;
padding: 5px 10px;
text-align: left;
color: #666;
background: #ffd;
height: 30px;
vertical-align: middle;
border-top: 1px solid #f0f0f0;
border-bottom: 1px solid #f0f0f0;
}
tr.node-text-diff-expand td {
cursor: pointer;
&:hover {
background: #ffc;
}
}
}

View File

@@ -178,7 +178,7 @@
}
.form-row label {
display: inline-block;
width: 100px;
min-width: 100px;
}
.form-row input, .form-row div[contenteditable="true"] {
width:70%;
@@ -323,6 +323,7 @@
margin-right: 20px;
text-align: right;
width: 30px;
min-width: 30px;
}
button {
margin-left: 10px;

View File

@@ -49,12 +49,7 @@
.palette-module-version {
color: #aaa;
}
.palette-module-errors .fa-warning {
opacity: 0.5;
}
ul.palette-module-error-list li {
color: #aaa;
}
}
@@ -227,20 +222,6 @@
margin-left: 5px;
}
}
.palette-module-meta .fa-warning {
color: #AD1625;
}
ul.palette-module-error-list {
display: inline-block;
list-style-type: none;
margin: 0;
font-size: 0.9em;
li {
border: none;
background: none;
}
}
.palette-module-shade {
@include shade;
text-align: center;

View File

@@ -139,17 +139,16 @@
}
}
button.editor-button {
width: calc(50% - 80px);
width: calc(50% - 40px);
margin: 20px;
height: auto;
height: 175px;
line-height: 2em;
padding: 10px;
border-color: #aaa;
font-size: 1.5em !important;
i {
color: #aaa;
color: #ccc;
}
&:hover i {
color: #999;
color: #aaa;
}
}
.button-group {
@@ -161,6 +160,7 @@
button.projects-dialog-screen-create-type {
height: auto;
padding: 10px;
}
.button-group {
text-align: center;
@@ -501,9 +501,9 @@
top: 4px;
right: 4px;
display: none;
button {
width: 24px;
}
}
button {
width: 24px;
}
&:hover {

View File

@@ -181,7 +181,7 @@
this.handleDebugMessage = function(t,o) {
var sourceNode = RED.nodes.node(o.id) || RED.nodes.node(o.z);
if (sourceNode) {
o._source = {id:sourceNode.id,z:sourceNode.z,name:sourceNode.name,type:sourceNode.type,_alias:o._alias};
o._source = {id:sourceNode.id,z:sourceNode.z,name:sourceNode.name};
}
RED.debug.handleDebugMessage(o);
if (subWindow) {

View File

@@ -138,7 +138,7 @@
icon: "arrow-in.png",
align: "right",
label: function() {
return this.name||this.command||(this.useSpawn=="true"?this._("exec.spawn"):this._("exec.exec"));
return this.name||this.command;
},
labelStyle: function() {
return this.name?"node_label_italic":"";

View File

@@ -68,7 +68,7 @@
outputs:1,
icon: "function.png",
label: function() {
return this.name||this._("function.function");
return this.name;
},
labelStyle: function() {
return this.name?"node_label_italic":"";

View File

@@ -65,8 +65,6 @@ module.exports = function(RED) {
"log:__node__.log,"+
"error:__node__.error,"+
"warn:__node__.warn,"+
"debug:__node__.debug,"+
"trace:__node__.trace,"+
"on:__node__.on,"+
"status:__node__.status,"+
"send:function(msgs){ __node__.send(__msgid__,msgs);}"+
@@ -93,12 +91,6 @@ module.exports = function(RED) {
warn: function() {
node.warn.apply(node, arguments);
},
debug: function() {
node.debug.apply(node, arguments);
},
trace: function() {
node.trace.apply(node, arguments);
},
send: function(id, msgs) {
sendResults(node, id, msgs);
},
@@ -204,14 +196,7 @@ module.exports = function(RED) {
}
var context = vm.createContext(sandbox);
try {
this.script = vm.createScript(functionText, {
filename: 'Function node:'+this.id+(this.name?' ['+this.name+']':''), // filename for stack traces
displayErrors: true
// Using the following options causes node 4/6 to not include the line number
// in the stack output. So don't use them.
// lineOffset: -11, // line number offset to be used for stack traces
// columnOffset: 0, // column number offset to be used for stack traces
});
this.script = vm.createScript(functionText);
this.on("input", function(msg) {
try {
var start = process.hrtime();
@@ -226,13 +211,6 @@ module.exports = function(RED) {
this.status({fill:"yellow",shape:"dot",text:""+converted});
}
} catch(err) {
//remove unwanted part
var index = err.stack.search(/\n\s*at ContextifyScript.Script.runInContext/);
err.stack = err.stack.slice(0, index).split('\n').slice(0,-1).join('\n');
var stack = err.stack.split(/\r?\n/);
//store the error in msg to be used in flows
msg.error = err;
var line = 0;
var errorMessage;

View File

@@ -88,7 +88,7 @@
category: 'function',
defaults: {
name: {value:""},
field: {value:"payload", validate:RED.validators.typedInput("fieldType")},
field: {value:"payload", validate: RED.validators.typedInput("fieldType")},
fieldType: {value:"msg"},
format: {value:"handlebars"},
syntax: {value:"mustache"},
@@ -99,17 +99,13 @@
outputs:1,
icon: "template.png",
label: function() {
return this.name||this._("template.template");;
return this.name;
},
labelStyle: function() {
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
var that = this;
if (!this.field) {
this.field = 'payload';
$("#node-input-field").val("payload");
}
if (!this.fieldType) {
this.fieldType = 'msg';
}

View File

@@ -50,7 +50,6 @@ module.exports = function(RED) {
// try node context:
var dot = name.indexOf(".");
/* istanbul ignore else */
if (dot > 0) {
var contextName = name.substr(0, dot);
var variableName = name.substr(dot + 1);
@@ -62,8 +61,7 @@ module.exports = function(RED) {
return this.nodeContext.global.get(variableName);
}
}
}
catch(err) {
}catch(err) {
throw err;
}
}
@@ -89,27 +87,24 @@ module.exports = function(RED) {
* Allow template contents to be defined externally
* through inbound msg.template IFF node.template empty
*/
var template = node.template;
if (msg.hasOwnProperty("template")) {
if (template == "" || template === null) {
template = msg.template;
if (node.template == "" || node.template === null) {
node.template = msg.template;
}
}
if (node.syntax === "mustache") {
if (node.outputFormat === "json") {
value = mustache.render(template,new NodeContext(msg, node.context(), null, true));
value = mustache.render(node.template,new NodeContext(msg, node.context(), null, true));
} else {
value = mustache.render(template,new NodeContext(msg, node.context(), null, false));
value = mustache.render(node.template,new NodeContext(msg, node.context(), null, false));
}
} else {
value = template;
value = node.template;
}
/* istanbul ignore else */
if (node.outputFormat === "json") {
value = JSON.parse(value);
}
/* istanbul ignore else */
if (node.outputFormat === "yaml") {
value = yaml.load(value);
}
@@ -122,8 +117,7 @@ module.exports = function(RED) {
node.context().global.set(node.field,value);
}
node.send(msg);
}
catch(err) {
} catch(err) {
node.error(err.message);
}
});

View File

@@ -108,7 +108,7 @@
outstanding messages held by the node are cleared without being sent.</dd>
</dl>
<h3>Details</h3>
<p>When configured to delay messages, the delay interval can be a fixed value,
<p>When configured to delay messages, the delay interval can be a fixed value
a random value within a range or dynamically set for each message.</p>
<p>When configured to rate limit messages, their delivery is spread across
the configured time period. The status shows the number of messages currently in the queue.

View File

@@ -100,6 +100,8 @@ module.exports = function(RED) {
msg.payload = RED.util.evaluateNodeProperty(node.op1,node.op1type,node,msg);
}
if (node.op1type !== "nul") { node.send(RED.util.cloneMessage(msg)); }
if (node.duration === 0) { node.topics[topic].tout = 0; }
else if (node.loop === true) {
/* istanbul ignore else */
@@ -111,25 +113,21 @@ module.exports = function(RED) {
}
}
else {
if (!node.topics[topic].tout) {
node.topics[topic].tout = setTimeout(function() {
var msg2 = null;
if (node.op2type !== "nul") {
msg2 = RED.util.cloneMessage(msg);
if (node.op2type === "flow" || node.op2type === "global") {
node.topics[topic].m2 = RED.util.evaluateNodeProperty(node.op2,node.op2type,node,msg);
}
msg2.payload = node.topics[topic].m2;
delete node.topics[topic];
node.send(msg2);
node.topics[topic].tout = setTimeout(function() {
var msg2 = null;
if (node.op2type !== "nul") {
msg2 = RED.util.cloneMessage(msg);
if (node.op2type === "flow" || node.op2type === "global") {
node.topics[topic].m2 = RED.util.evaluateNodeProperty(node.op2,node.op2type,node,msg);
}
else { delete node.topics[topic]; }
node.status({});
}, node.duration);
}
msg2.payload = node.topics[topic].m2;
}
delete node.topics[topic];
node.status({});
node.send(msg2);
}, node.duration);
}
node.status({fill:"blue",shape:"dot",text:" "});
if (node.op1type !== "nul") { node.send(RED.util.cloneMessage(msg)); }
}
else if ((node.extend === "true" || node.extend === true) && (node.duration > 0)) {
/* istanbul ignore else */

View File

@@ -33,7 +33,7 @@
outputs:0,
icon: "comment.png",
label: function() {
return this.name||this._("comment.comment");
return this.name||"";
},
labelStyle: function() {
return this.name?"node_label_italic":"";

View File

@@ -222,6 +222,7 @@ RED.debug = (function() {
clearMessageList(false);
});
return {
content: content,
footer: footerToolbar
@@ -237,9 +238,6 @@ RED.debug = (function() {
workspaceOrder.forEach(function(ws,i) {
workspaceOrderMap[ws] = i;
});
candidateNodes = candidateNodes.filter(function(node) {
return workspaceOrderMap.hasOwnProperty(node.z);
})
candidateNodes.sort(function(A,B) {
var wsA = workspaceOrderMap[A.z];
var wsB = workspaceOrderMap[B.z];
@@ -341,7 +339,7 @@ RED.debug = (function() {
activeMenuMessage.clearPinned();
}},
null,
{id:"debug-message-menu-item-filter", label:RED._("node-red:debug.messageMenu.filterNode"),onselect:function(){
{id:"debug-message-menu-item-filter",label:RED._("node-red:debug.messageMenu.filterNode"),onselect:function(){
var candidateNodes = RED.nodes.filterNodes({type:'debug'});
candidateNodes.forEach(function(n) {
filteredNodes[n.id] = true;
@@ -363,15 +361,6 @@ RED.debug = (function() {
menuOptionMenu.on('mouseup', function() { $(this).hide() });
menuOptionMenu.appendTo("body");
}
var filterOptionDisabled = false;
var sourceNode = RED.nodes.node(sourceId);
if (sourceNode && sourceNode.type !== 'debug') {
filterOptionDisabled = true;
}
RED.menu.setDisabled('debug-message-menu-item-filter',filterOptionDisabled);
RED.menu.setDisabled('debug-message-menu-item-clear-filter',filterOptionDisabled);
var elementPos = button.offset();
menuOptionMenu.css({
top: elementPos.top+"px",
@@ -403,19 +392,12 @@ RED.debug = (function() {
$(msg).addClass('debug-message-hover');
if (o._source) {
config.messageMouseEnter(o._source.id);
if (o._source._alias) {
config.messageMouseEnter(o._source._alias);
}
}
};
msg.onmouseleave = function() {
$(msg).removeClass('debug-message-hover');
if (o._source) {
config.messageMouseLeave(o._source.id);
if (o._source._alias) {
config.messageMouseLeave(o._source._alias);
}
}
};
var name = sanitize(((o.name?o.name:o.id)||"").toString());

View File

@@ -179,7 +179,7 @@
<dt>payload <span class="property-type">number</span></dt>
<dd>the payload will be a 1 or a 0.</dd>
<dt>topic <span class="property-type">string</span></dt>
<dd>the topic will be set to <code>pi/{the pin number}</code>.</dd>
<dd>the topic will be set to `pi/{the pin number}`.</dd>
</dl>
<h3>Details</h3>
<p>You may also enable the input pullup resistor or the pulldown resistor.</p>

View File

@@ -142,9 +142,9 @@ module.exports = function(RED) {
var limit = 1;
if (node.out === "pwm") { limit = 100; }
if ((out >= 0) && (out <= limit)) {
if (RED.settings.verbose) { node.log("out: "+out); }
if (RED.settings.verbose) { node.log("out: "+msg.payload); }
if (node.child !== null) {
node.child.stdin.write(out+"\n");
node.child.stdin.write(msg.payload+"\n");
node.status({fill:"green",shape:"dot",text:msg.payload.toString()});
}
else {

View File

@@ -212,84 +212,48 @@
<input type="password" id="node-config-input-password">
</div>
</div>
<div id="mqtt-broker-tab-messages" style="display:none">
<div id="mqtt-broker-section-birth">
<div class="palette-header">
<i class="fa fa-angle-down"></i><span data-i18n="mqtt.sections-label.birth-message"></span>
</div>
<div class="section-content" style="padding:10px 0 0 10px">
<div class="form-row">
<label style="width: 100px !important;" for="node-config-input-birthTopic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
<input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-birthTopic" data-i18n="[placeholder]mqtt.placeholder.birth-topic">
<label style="margin-left: 10px; width: 90px !important;" for="node-config-input-birthRetain"><i class="fa fa-history"></i> <span data-i18n="mqtt.label.retain"></span></label>
<select id="node-config-input-birthRetain" style="width:75px !important">
<option value="false" data-i18n="mqtt.false"></option>
<option value="true" data-i18n="mqtt.true"></option>
</select>
</div>
<div class="form-row">
<label style="width: 100px !important;" for="node-config-input-birthPayload"><i class="fa fa-envelope"></i> <span data-i18n="common.label.payload"></span></label>
<input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-birthPayload" style="width:300px" data-i18n="[placeholder]common.label.payload">
<label style="margin-left: 10px; width: 90px !important;" for="node-config-input-birthQos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label>
<select id="node-config-input-birthQos" style="width:75px !important">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
</div>
<div id="mqtt-broker-tab-birth" style="display:none">
<div class="form-row">
<label for="node-config-input-birthTopic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
<input type="text" id="node-config-input-birthTopic" data-i18n="[placeholder]mqtt.placeholder.birth-topic">
</div>
<div id="mqtt-broker-section-close">
<div class="palette-header">
<i class="fa fa-angle-down"></i><span data-i18n="mqtt.sections-label.close-message"></span>
</div>
<div class="section-content" style="padding:10px 0 0 10px">
<div class="form-row">
<label style="width: 100px !important;" for="node-config-input-closeTopic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
<input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-closeTopic" style="width:300px" data-i18n="[placeholder]mqtt.placeholder.close-topic">
<label style="margin-left: 10px; width: 90px !important;" for="node-config-input-closeRetain"><i class="fa fa-history"></i> <span data-i18n="mqtt.label.retain"></span></label>
<select id="node-config-input-closeRetain" style="width:75px !important">
<option value="false" data-i18n="mqtt.false"></option>
<option value="true" data-i18n="mqtt.true"></option>
</select>
</div>
<div class="form-row">
<label style="width: 100px !important;" for="node-config-input-closePayload"><i class="fa fa-envelope"></i> <span data-i18n="common.label.payload"></span></label>
<input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-closePayload" style="width:300px" data-i18n="[placeholder]common.label.payload">
<label style="margin-left: 10px; width: 90px !important;" for="node-config-input-closeQos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label>
<select id="node-config-input-closeQos" style="width:75px !important">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
</div>
<div class="form-row">
<label for="node-config-input-birthQos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label>
<select id="node-config-input-birthQos" style="width:125px !important">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
&nbsp;&nbsp;<i class="fa fa-history"></i>&nbsp;<span data-i18n="mqtt.retain"></span> &nbsp;<select id="node-config-input-birthRetain" style="width:125px !important">
<option value="false" data-i18n="mqtt.false"></option>
<option value="true" data-i18n="mqtt.true"></option>
</select>
</div>
<div id="mqtt-broker-section-will">
<div class="palette-header">
<i class="fa fa-angle-down"></i><span data-i18n="mqtt.sections-label.will-message"></span>
</div>
<div class="section-content" style="padding:10px 0 0 10px">
<div class="form-row">
<label style="width: 100px !important;" for="node-config-input-willTopic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
<input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-willTopic" style="width:300px" data-i18n="[placeholder]mqtt.placeholder.will-topic">
<label style="margin-left: 10px; width: 90px !important;" for="node-config-input-willRetain"><i class="fa fa-history"></i> <span data-i18n="mqtt.label.retain"></span></label>
<select id="node-config-input-willRetain" style="width:75px !important">
<option value="false" data-i18n="mqtt.false"></option>
<option value="true" data-i18n="mqtt.true"></option>
</select>
</div>
<div class="form-row">
<label style="width: 100px !important;" for="node-config-input-willPayload"><i class="fa fa-envelope"></i> <span data-i18n="common.label.payload"></span></label>
<input style="width: calc(100% - 300px) !important" type="text" id="node-config-input-willPayload" style="width:300px" data-i18n="[placeholder]common.label.payload">
<label style="margin-left: 10px; width: 90px !important;" for="node-config-input-willQos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label>
<select id="node-config-input-willQos" style="width:75px !important">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
</div>
<div class="form-row">
<label for="node-config-input-birthPayload"><i class="fa fa-envelope"></i> <span data-i18n="common.label.payload"></span></label>
<input type="text" id="node-config-input-birthPayload" data-i18n="[placeholder]common.label.payload">
</div>
</div>
<div id="mqtt-broker-tab-will" style="display:none">
<div class="form-row">
<label for="node-config-input-willTopic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
<input type="text" id="node-config-input-willTopic" data-i18n="[placeholder]mqtt.placeholder.will-topic">
</div>
<div class="form-row">
<label for="node-config-input-willQos"><i class="fa fa-empire"></i> <span data-i18n="mqtt.label.qos"></span></label>
<select id="node-config-input-willQos" style="width:125px !important">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
&nbsp;&nbsp;<i class="fa fa-history"></i>&nbsp;<span data-i18n="mqtt.retain"></span> &nbsp;<select id="node-config-input-willRetain" style="width:125px !important">
<option value="false" data-i18n="mqtt.false"></option>
<option value="true" data-i18n="mqtt.true"></option>
</select>
</div>
<div class="form-row">
<label for="node-config-input-willPayload"><i class="fa fa-envelope"></i> <span data-i18n="common.label.payload"></span></label>
<input type="text" id="node-config-input-willPayload" data-i18n="[placeholder]common.label.payload">
</div>
</div>
</div>
@@ -305,9 +269,6 @@
<h4>Birth Message</h4>
<p>This is a message that will be published on the configured topic whenever the
connection is established.</p>
<h4>Close Message</h4>
<p>This is a message that will be published on the configured topic before the
connection is closed normally, either by re-deploying the node, or by shutting down.</p>
<h4>Will Message</h4>
<p>This is a message that will be published by the broker in the event the node
unexpectedly loses its connection.</p>
@@ -339,18 +300,14 @@
compatmode: { value: true},
keepalive: {value:60,validate:RED.validators.number()},
cleansession: {value: true},
birthTopic: {value:""},
birthQos: {value:"0"},
birthRetain: {value:false},
birthPayload: {value:""},
closeTopic: {value:""},
closeQos: {value:"0"},
closeRetain: {value:false},
closePayload: {value:""},
willTopic: {value:""},
willQos: {value:"0"},
willRetain: {value:false},
willPayload: {value:""}
willPayload: {value:""},
birthTopic: {value:""},
birthQos: {value:"0"},
birthRetain: {value:false},
birthPayload: {value:""}
},
credentials: {
user: {type:"text"},
@@ -386,39 +343,14 @@
id: "mqtt-broker-tab-security",
label: this._("mqtt.tabs-label.security")
});
tabs.addTab({
id: "mqtt-broker-tab-messages",
label: this._("mqtt.tabs-label.messages")
id: "mqtt-broker-tab-birth",
label: this._("mqtt.tabs-label.birth")
});
tabs.addTab({
id: "mqtt-broker-tab-will",
label: this._("mqtt.tabs-label.will")
});
function setUpSection(sectionId, isExpanded) {
var birthMessageSection = $(sectionId);
var paletteHeader = birthMessageSection.find('.palette-header');
var twistie = paletteHeader.find('i');
var sectionContent = birthMessageSection.find('.section-content');
function toggleSection(expanded) {
twistie.toggleClass('expanded', expanded);
sectionContent.toggle(expanded);
}
paletteHeader.click(function(e) {
e.preventDefault();
var isExpanded = twistie.hasClass('expanded');
toggleSection(!isExpanded);
});
toggleSection(isExpanded);
}
// show first section if none are set so the user gets the idea
var showBirthSection = this.birthTopic !== ""
|| this.willTopic === ""
&& this.birthTopic === ""
&& this.closeTopic == "";
setUpSection('#mqtt-broker-section-birth', showBirthSection);
setUpSection('#mqtt-broker-section-close', this.closeTopic !== "");
setUpSection('#mqtt-broker-section-will', this.willTopic !== "");
setTimeout(function() { tabs.resize(); },0);
if (typeof this.cleansession === 'undefined') {
this.cleansession = true;
@@ -436,18 +368,14 @@
this.keepalive = 15;
$("#node-config-input-keepalive").val(this.keepalive);
}
if (typeof this.birthQos === 'undefined') {
this.birthQos = "0";
$("#node-config-input-birthQos").val("0");
}
if (typeof this.closeQos === 'undefined') {
this.willQos = "0";
$("#node-config-input-willQos").val("0");
}
if (typeof this.willQos === 'undefined') {
this.willQos = "0";
$("#node-config-input-willQos").val("0");
}
if (typeof this.birthQos === 'undefined') {
this.birthQos = "0";
$("#node-config-input-birthQos").val("0");
}
function updateTLSOptions() {
if ($("#node-config-input-usetls").is(':checked')) {

View File

@@ -60,15 +60,6 @@ module.exports = function(RED) {
};
}
if (n.closeTopic) {
this.closeMessage = {
topic: n.closeTopic,
payload: n.closePayload || "",
qos: Number(n.closeQos||0),
retain: n.closeRetain=="true"|| n.closeRetain===true
};
}
if (this.credentials) {
this.username = this.credentials.user;
this.password = this.credentials.password;
@@ -323,10 +314,6 @@ module.exports = function(RED) {
this.on('close', function(done) {
this.closing = true;
if (this.connected) {
// Send close message
if (node.closeMessage) {
node.publish(node.closeMessage);
}
this.client.once('close', function() {
done();
});

View File

@@ -75,7 +75,7 @@
<p>The node will listen on the configured path for requests of a particular type.
The path can be fully specified, such as <code>/user</code>, or include
named parameters that accept any value, such as <code>/user/:name</code>.
When named parameters are used, their actual value in a request can be accessed under <code>msg.req.params</code>.</p>
When named parameters are used, their actual value in a request can be accessed under `msg.req.params`.</p>
<p>For requests that include a body, such as a POST or PUT, the contents of
the request is made available as <code>msg.payload</code>.</p>
<p>If the content type of the request can be determined, the body will be parsed to

View File

@@ -86,10 +86,8 @@
<dt class="optional">payload</dt>
<dd>Sent as the body of the request.</dd>
<dt class="optional">rejectUnauthorized</dt>
<dd>If set to <code>false</code>, allows requests to be made to https sites that use
<dd>If set to <code>true</code>, allows requests to be made to https sites that use
self signed certificates.</dd>
<dt class="optional">followRedirects</dt>
<dd>If set to <code>false</code> prevent following Redirect (HTTP 301).<code>true</code> by default</dd>
</dl>
<h3>Outputs</h3>
<dl class="message-properties">
@@ -119,7 +117,7 @@
the response headers. The next node will then use those headers for its request - this
is not usually the right thing to do. If <code>msg.headers</code> property is left unchanged
between nodes, it will be ignored by the second node. To set custom headers, <code>msg.headers</code>
should first be deleted or reset to an empty object: <code>{}</code>.
should first be deleted or reset to an empty object: `{}`.
<h4>Cookie handling</h4>
<p>The <code>cookies</code> property passed to the node must be an object of name/value pairs.
The value can be either a string to set the value of the cookie or it can be an

View File

@@ -108,9 +108,6 @@ module.exports = function(RED) {
}
}
}
if (msg.hasOwnProperty('followRedirects')) {
opts.followRedirects = msg.followRedirects;
}
if (msg.cookies) {
var cookies = [];
if (opts.headers.hasOwnProperty('cookie')) {
@@ -266,8 +263,9 @@ module.exports = function(RED) {
catch(e) { node.warn(RED._("httpin.errors.json-error")); }
}
}
node.status({});
node.send(msg);
node.status({});
}
});
});
@@ -282,8 +280,8 @@ module.exports = function(RED) {
node.error(err,msg);
msg.payload = err.toString() + " : " + url;
msg.statusCode = err.code;
node.status({fill:"red",shape:"ring",text:err.code});
node.send(msg);
node.status({fill:"red",shape:"ring",text:err.code});
});
if (payload) {
req.write(payload);

View File

@@ -59,7 +59,7 @@
outputs:1,
icon: "watch.png",
label: function() {
return this.name||this.files||this._("watch.watch");
return this.name||this.files;
},
labelStyle: function() {
return this.name?"node_label_italic":"";

View File

@@ -52,7 +52,6 @@ module.exports = function(RED) {
node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port}));
node.status({fill:"green",shape:"dot",text:"common.status.connected"});
});
client.setKeepAlive(true,120000);
connectionPool[id] = client;
client.on('data', function (data) {
@@ -124,8 +123,7 @@ module.exports = function(RED) {
clearTimeout(reconnectTimeout);
if (!node.connected) { done(); }
});
}
else {
} else {
var server = net.createServer(function (socket) {
socket.setKeepAlive(true,120000);
if (socketTimeout !== null) { socket.setTimeout(socketTimeout); }
@@ -186,7 +184,6 @@ module.exports = function(RED) {
node.log(err);
});
});
server.on('error', function(err) {
if (err) {
node.error(RED._("tcpin.errors.cannot-listen",{port:node.port,error:err.toString()}));
@@ -240,7 +237,6 @@ module.exports = function(RED) {
node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port}));
node.status({fill:"green",shape:"dot",text:"common.status.connected"});
});
client.setKeepAlive(true,120000);
client.on('error', function (err) {
node.log(RED._("tcpin.errors.error",{error:err.toString()}));
});
@@ -292,8 +288,7 @@ module.exports = function(RED) {
if (!node.connected) { done(); }
});
}
else if (node.beserver == "reply") {
} else if (node.beserver == "reply") {
node.on("input",function(msg) {
if (msg._session && msg._session.type == "tcp") {
var client = connectionPool[msg._session.id];
@@ -319,8 +314,7 @@ module.exports = function(RED) {
}
}
});
}
else {
} else {
var connectedSockets = [];
node.status({text:RED._("tcpin.status.connections",{count:0})});
var server = net.createServer(function (socket) {

View File

@@ -29,7 +29,7 @@
</div>
<div class="form-row node-input-iface">
<label for="node-input-iface"><i class="fa fa-random"></i> <span data-i18n="udp.label.interface"></span></label>
<input type="text" id="node-input-iface" data-i18n="[placeholder]udp.placeholder.interfaceprompt">
<input type="text" id="node-input-iface" data-i18n="[placeholder]udp.label.interfaceprompt">
</div>
<div class="form-row">
<label for="node-input-port"><i class="fa fa-sign-in"></i> <span data-i18n="udp.label.onport"></span></label>

View File

@@ -16,7 +16,6 @@
module.exports = function(RED) {
"use strict";
var os = require('os');
var dgram = require('dgram');
var udpInputPortsInUse = {};
@@ -31,29 +30,6 @@ module.exports = function(RED) {
this.ipv = n.ipv || "udp4";
var node = this;
if (node.iface && node.iface.indexOf(".") === -1) {
try {
if ((os.networkInterfaces())[node.iface][0].hasOwnProperty("scopeid")) {
if (node.ipv === "udp4") {
node.iface = (os.networkInterfaces())[node.iface][1].address;
} else {
node.iface = (os.networkInterfaces())[node.iface][0].address;
}
}
else {
if (node.ipv === "udp4") {
node.iface = (os.networkInterfaces())[node.iface][0].address;
} else {
node.iface = (os.networkInterfaces())[node.iface][1].address;
}
}
}
catch(e) {
node.warn(RED._("udp.errors.ifnotfound",{iface:node.iface}));
node.iface = null;
}
}
var opts = {type:node.ipv, reuseAddr:true};
if (process.version.indexOf("v0.10") === 0) { opts = node.ipv; }
var server;
@@ -63,7 +39,7 @@ module.exports = function(RED) {
udpInputPortsInUse[this.port] = server;
}
else {
node.warn(RED._("udp.errors.alreadyused",{port:node.port}));
node.warn(RED._("udp.errors.alreadyused",node.port));
server = udpInputPortsInUse[this.port]; // re-use existing
}
@@ -145,38 +121,12 @@ module.exports = function(RED) {
this.ipv = n.ipv || "udp4";
var node = this;
if (node.iface && node.iface.indexOf(".") === -1) {
try {
if ((os.networkInterfaces())[node.iface][0].hasOwnProperty("scopeid")) {
if (node.ipv === "udp4") {
node.iface = (os.networkInterfaces())[node.iface][1].address;
} else {
node.iface = (os.networkInterfaces())[node.iface][0].address;
}
}
else {
if (node.ipv === "udp4") {
node.iface = (os.networkInterfaces())[node.iface][0].address;
} else {
node.iface = (os.networkInterfaces())[node.iface][1].address;
}
}
}
catch(e) {
node.warn(RED._("udp.errors.ifnotfound",{iface:node.iface}));
node.iface = null;
}
}
var opts = {type:node.ipv, reuseAddr:true};
if (process.version.indexOf("v0.10") === 0) { opts = node.ipv; }
var sock;
var p = this.port;
if (node.multicast != "false") { p = this.outport||"0"; }
if (udpInputPortsInUse[p]) {
sock = udpInputPortsInUse[p];
node.log(RED._("udp.status.re-use",{outport:node.outport,host:node.addr,port:node.port}));
if (udpInputPortsInUse[this.outport || this.port]) {
sock = udpInputPortsInUse[this.outport || this.port];
}
else {
sock = dgram.createSocket(opts); // default to udp4
@@ -186,35 +136,36 @@ module.exports = function(RED) {
// prevent it going to the global error handler and shutting node-red
// down.
});
udpInputPortsInUse[p] = sock;
udpInputPortsInUse[this.outport || this.port] = sock;
}
if (node.multicast != "false") {
sock.bind(node.outport, function() { // have to bind before you can enable broadcast...
sock.setBroadcast(true); // turn on broadcast
if (node.multicast == "multi") {
try {
sock.setMulticastTTL(128);
sock.addMembership(node.addr,node.iface); // Add to the multicast group
node.log(RED._("udp.status.mc-ready",{iface:node.iface,outport:node.outport,host:node.addr,port:node.port}));
} catch (e) {
if (e.errno == "EINVAL") {
node.error(RED._("udp.errors.bad-mcaddress"));
} else if (e.errno == "ENODEV") {
node.error(RED._("udp.errors.interface"));
} else {
node.error(RED._("udp.errors.error",{error:e.errno}));
}
if (node.multicast != "false") {
if (node.outport === "") { node.outport = node.port; }
sock.bind(node.outport, function() { // have to bind before you can enable broadcast...
sock.setBroadcast(true); // turn on broadcast
if (node.multicast == "multi") {
try {
sock.setMulticastTTL(128);
sock.addMembership(node.addr,node.iface); // Add to the multicast group
node.log(RED._("udp.status.mc-ready",{outport:node.outport,host:node.addr,port:node.port}));
} catch (e) {
if (e.errno == "EINVAL") {
node.error(RED._("udp.errors.bad-mcaddress"));
} else if (e.errno == "ENODEV") {
node.error(RED._("udp.errors.interface"));
} else {
node.error(RED._("udp.errors.error",{error:e.errno}));
}
} else {
node.log(RED._("udp.status.bc-ready",{outport:node.outport,host:node.addr,port:node.port}));
}
});
} else if ((node.outport !== "") && (!udpInputPortsInUse[node.outport])) {
sock.bind(node.outport);
node.log(RED._("udp.status.ready",{outport:node.outport,host:node.addr,port:node.port}));
} else {
node.log(RED._("udp.status.ready-nolocal",{host:node.addr,port:node.port}));
}
} else {
node.log(RED._("udp.status.bc-ready",{outport:node.outport,host:node.addr,port:node.port}));
}
});
} else if ((node.outport !== "") && (!udpInputPortsInUse[node.outport])) {
sock.bind(node.outport);
node.log(RED._("udp.status.ready",{outport:node.outport,host:node.addr,port:node.port}));
} else {
node.log(RED._("udp.status.ready-nolocal",{host:node.addr,port:node.port}));
}
node.on("input", function(msg) {
@@ -247,8 +198,8 @@ module.exports = function(RED) {
});
node.on("close", function() {
if (udpInputPortsInUse.hasOwnProperty(p)) {
delete udpInputPortsInUse[p];
if (udpInputPortsInUse.hasOwnProperty(node.outport || node.port)) {
delete udpInputPortsInUse[node.outport || node.port];
}
try {
sock.close();

View File

@@ -70,8 +70,8 @@
}
},
"catch": {
"catch": "catch: all",
"catchNodes": "catch: __number__",
"catch": "catch all",
"catchNodes": "catch (__number__)",
"label": {
"source": "Catch errors from",
"node": "node",
@@ -86,8 +86,8 @@
}
},
"status": {
"status": "status: all",
"statusNodes": "status: __number__",
"status": "status (all)",
"statusNodes": "status (__number__)",
"label": {
"source": "Report status from",
"node": "node",
@@ -166,8 +166,6 @@
}
},
"exec": {
"exec": "exec",
"spawn": "spawn",
"label": {
"command": "Command",
"append": "Append",
@@ -186,7 +184,6 @@
"oldrc": "Use old style output (compatibility mode)"
},
"function": {
"function": "",
"label": {
"function": "Function",
"outputs": "Outputs"
@@ -198,7 +195,6 @@
"tip": "See the Info tab for help writing functions."
},
"template": {
"template": "template",
"label": {
"template": "Template",
"property": "Set property",
@@ -305,7 +301,6 @@
}
},
"comment": {
"comment": "comment",
"label": {
"title": "Title",
"body": "Body"
@@ -323,7 +318,6 @@
"broker": "Server",
"example": "e.g. localhost",
"qos": "QoS",
"retain": "Retain",
"clientid": "Client ID",
"port": "Port",
"keepalive": "Keep alive time (s)",
@@ -333,22 +327,17 @@
"verify-server-cert":"Verify server certificate",
"compatmode": "Use legacy MQTT 3.1 support"
},
"sections-label":{
"birth-message": "Message sent on connection (birth message)",
"will-message":"Message sent on an unexpected disconnection (will message)",
"close-message":"Message sent before disconnecting (close message)"
},
"tabs-label": {
"connection": "Connection",
"security": "Security",
"messages": "Messages"
"will": "Will Message",
"birth": "Birth Message"
},
"placeholder": {
"clientid": "Leave blank for auto generated",
"clientid-nonclean":"Must be set for non-clean sessions",
"will-topic": "Leave blank to disable will message",
"birth-topic": "Leave blank to disable birth message",
"close-topic": "Leave blank to disable close message"
"birth-topic": "Leave blank to disable birth message"
},
"state": {
"connected": "Connected to broker: __broker__",
@@ -427,7 +416,6 @@
}
},
"watch": {
"watch": "watch",
"label": {
"files": "File(s)",
"recursive": "Watch sub-directories recursively"
@@ -501,15 +489,15 @@
"using": "using",
"output": "Output",
"group": "Group",
"interface": "Local IF",
"interface": "Local IP",
"interfaceprompt": "(optional) local ip address to bind to",
"send": "Send a",
"toport": "to port",
"address": "Address",
"decode-base64": "Decode Base64 encoded payload?"
},
"placeholder": {
"interface": "(optional) local interface or address to bind to",
"interfaceprompt": "(optional) local interface or address to bind to",
"interface": "(optional) ip address of eth0",
"address": "destination ip"
},
"udpmsgs": "udp messages",
@@ -537,11 +525,10 @@
"mc-group": "udp multicast group __group__",
"listener-stopped": "udp listener stopped",
"output-stopped": "udp output stopped",
"mc-ready": "udp multicast ready: __iface__:__outport__ -> __host__:__port__",
"mc-ready": "udp multicast ready: __outport__ -> __host__:__port__",
"bc-ready": "udp broadcast ready: __outport__ -> __host__:__port__",
"ready": "udp ready: __outport__ -> __host__:__port__",
"ready-nolocal": "udp ready: __host__:__port__",
"re-use": "udp re-use socket: __outport__ -> __host__:__port__"
"ready-nolocal": "udp ready: __host__:__port__"
},
"errors": {
"access-error": "UDP access error, you may need root access for ports below 1024",
@@ -551,12 +538,10 @@
"ip-notset": "udp: ip address not set",
"port-notset": "udp: port not set",
"port-invalid": "udp: port number not valid",
"alreadyused": "udp: port __port__ already in use",
"ifnotfound": "udp: interface __iface__ not found"
"alreadyused": "udp: port already in use"
}
},
"switch": {
"switch": "switch",
"label": {
"property": "Property",
"rule": "rule",
@@ -574,7 +559,6 @@
"false":"is false",
"null":"is null",
"nnull":"is not null",
"istype":"is of type",
"head":"head",
"tail":"tail",
"index":"index between",
@@ -613,7 +597,6 @@
}
},
"range": {
"range": "range",
"label": {
"action": "Action",
"inputrange": "Map the input range",
@@ -680,8 +663,7 @@
"html": {
"label": {
"select": "Selector",
"output": "Output",
"in": "in"
"output": "Output"
},
"output": {
"html": "the html content of the elements",
@@ -781,9 +763,7 @@
"status": {
"stopped": "stopped",
"closed": "closed",
"not-running": "not running",
"not-available": "not available",
"na": "N/A : __value__"
"not-running": "not running"
},
"errors": {
"ignorenode": "Ignoring Raspberry Pi specific node",
@@ -802,7 +782,6 @@
}
},
"tail": {
"tail": "tail",
"label": {
"filename": "Filename",
"type": "File type",
@@ -856,7 +835,6 @@
"tip": "Tip: The filename should be an absolute path, otherwise it will be relative to the working directory of the Node-RED process."
},
"split": {
"split": "split",
"intro":"Split <code>msg.payload</code> based on type:",
"object":"<b>Object</b>",
"objectSend":"Send a message for each key/value pair",
@@ -868,7 +846,6 @@
"addname":" Copy key to "
},
"join":{
"join": "join",
"mode":{
"mode":"Mode",
"auto":"automatic",
@@ -915,7 +892,6 @@
}
},
"sort" : {
"sort": "sort",
"target" : "Sort",
"seq" : "message sequence",
"key" : "Key",
@@ -929,7 +905,6 @@
"clear" : "clear pending message in sort node"
},
"batch" : {
"batch": "batch",
"mode": {
"label" : "Mode",
"num-msgs" : "Group by number of messages",

View File

@@ -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.
-->
<script type="text/x-red" data-help-name="sentiment">
<p>指定したプロパティ(デフォルトは<code>payload</code>)<code>sentiment</code></p>
<h3>出力</h3>
<dl class="message-properties">
<dt>sentiment <span class="property-type">オブジェクト</span></dt>
<dd>AFINN-111による感情分析の結果</dd>
<dt>sentiment.score <span class="property-type">数値</span></dt>
<dd>感情分析スコア</dd>
</dl>
<h3>入力</h3>
<dl class="message-properties">
<dt>overrides <span class="property-type">オブジェクト</span></dt>
<dd>単語スコアの上書きをするためのオブジェクト - <code>{ word:score,... }</code></dd>
</dl>
<h3>詳細</h3>
<p>ゼロ以上のスコアはポジティブゼロ以下はネガティブを意味します</p>
<p>スコアの範囲は通常-5から+5ですがより大きかったり小さかったりすることもあります</p>
<p>詳細は<a href="https://github.com/thisandagain/sentiment/blob/master/README.md" target="_blank">the Sentiment docs here</a></p>
</script>

View File

@@ -1,34 +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.
-->
<script type="text/x-red" data-help-name="inject">
<p>手動もしくは一定間隔でメッセージをフローに注入しますメッセージのペイロードには文字列JavaScriptオブジェクト現在の時刻などさまざまな値を指定できます</p>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">各種</span></dt>
<dd>指定したメッセージペイロード</dd>
<dt class="optional">topic <span class="property-type">文字列</span></dt>
<dd>任意で指定可能なプロパティ</dd>
</dl>
<h3>詳細</h3>
<p>injectードを用いることで指定したペイロード値を用いてフローを開始できますデフォルトのペイロード値は現在時刻のタイムスタンプを1970年1月1日からの経過ミリ秒で表現した値です</p>
<p>文字列数値論理値JavaScriptオブジェクトフロー/グローバルコンテキストの値などの送出も可能です</p>
<p> デフォルト設定ではエディタ内に表示されるボタンをクリックすることでノードを手動で起動できます指定間隔もしくはスケジュールに従ってメッセージを送出するように設定することも可能です</p>
<p>またフロー開始の際に一度だけメッセージを送出させることもできます</p>
<p><i>時間間隔</i>596(24)</p>
<p><b></b>:「<i>指定した時間間隔、日時</i><i>指定した日時</i>」オプションは標準的なcronシステムを内部で利用します。したがって「20分」という指定は、その時点から20分後ではなく、毎時きっかり、20分、40分を意味します。現時刻から20分毎を指定するには「<i>指定した時間間隔</i>オプションを用います</p>
<p><b></b>: function使</p>
</script>

View File

@@ -1,36 +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.
-->
<script type="text/x-red" data-help-name="catch">
<p>同じタブ内のノードが送出したエラーをキャッチします</p>
<h3>出力</h3>
<dl class="message-properties">
<dt>error.message <span class="property-type">文字列</span></dt>
<dd>エラーメッセージ</dd>
<dt>error.source.id <span class="property-type">文字列</span></dt>
<dd>エラーを送出したードのID</dd>
<dt>error.source.type <span class="property-type">文字列</span></dt>
<dd>エラーを送出したノードの種別</dd>
<dt>error.source.name <span class="property-type">文字列</span></dt>
<dd>エラーを送出したノードの名称(設定されている場合)</dd>
</dl>
<h3>詳細</h3>
<p>メッセージの処理中にノードがエラーを送出した場合フロー実行は基本的に停止しますこのノードを使うとエラーをキャッチして対応するフローで処理させることができます</p>
<p>デフォルトでは同じタブの全てのノードが送出したエラーをキャッチします特定のノードをキャッチ対象とすることも可能です</p>
<p>エラー発生時にはマッチするすべてのcatchードがメッセージを受け取ります</p>
<p>サブフロー内でエラーが送出された場合まずサブフロー内のcatchードで処理されます対応するノードが存在しない場合にはそのサブフローが配置されたタブにエラーを伝播して処理します</p>
<p>メッセージが<code>error</code><code>error</code><code>_error</code></p>
</script>

View File

@@ -1,33 +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.
-->
<script type="text/x-red" data-help-name="status">
<p>同じタブ内のノードのステータスメッセージを取得します</p>
<h3>出力</h3>
<dl class="message-properties">
<dt>status.text <span class="property-type">文字列</span></dt>
<dd>ステータス文字列</dd>
<dt>status.source.type <span class="property-type">文字列</span></dt>
<dd>ステータスを表示したノードの種別</dd>
<dt>status.source.id <span class="property-type">文字列</span></dt>
<dd>ステータスを表示したードのID</dd>
<dt>status.source.name <span class="property-type">文字列</span></dt>
<dd>ステータスを表示したノードの名称(設定されている場合)</dd>
</dl>
<h3>詳細</h3>
<p>このノードは<code>payload</code></p>
<p>デフォルトでは同じワークスペースタブ内の全てのノードのステータスを取得します特定のノードのステータスを取得対象とすることも可能です</p>
</script>

View File

@@ -1,26 +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.
-->
<script type="text/x-red" data-help-name="debug">
<p>サイドバーのデバッグタブに選択したメッセージプロパティの値を表示します設定によりランタイムログへの出力も可能ですデフォルトの表示対象は<code>msg.payload</code></p>
<h3>詳細</h3>
<p>デバッグサイドバーは受け取ったメッセージの階層構造を表示する機能を備えますこの機能によりメッセージの構造を容易に理解できます</p>
<p>JavaScriptオブジェクトと配列は必要に応じて折り畳んだり展開したりできますバッファオブジェクトを生データとして表示したり表現可能な場合に文字列として表示することも可能です</p>
<p>メッセージを受信した時刻送信ノードメッセージの型に関する情報をデバッグサイドバーに表示されたメッセージに付随して表示します送信元ードのIDを選択するとワークスペース内の対応ノードを確認できます</p>
<p>出力の有効/無効はノード上のボタンで切り替えられますフロー上で未使用のdebugードは無効化するか削除することを推奨します</p>
<p>全てのメッセージをランタイムログに送付もしくは(32文字の)短いデータをdebugードの下のステータステキストに表示することも可能です</p>
</script>

View File

@@ -1,31 +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.
-->
<script type="text/x-red" data-help-name="link in">
<p>フロー間に仮想的なリンクを作成します</p>
<h3>詳細</h3>
<p>任意のタブ上に存在する<code>link out</code></p>
<p>linkード間のリンクはlinkードを選択した場合にのみ表示されます他のタブへのリンクがある場合には仮想的なノードを表示しますこの仮想的ノードをクリックすると対応するタブに移動できます</p>
<p><b>: </b></p>
</script>
<script type="text/x-red" data-help-name="link out">
<p>フロー間に仮想的なリンクを作成します</p>
<h3>詳細</h3>
<p>任意のタブ上に存在する<code>link in</code></p>
<p>linkード間のリンクはlinkードを選択した場合にのみ表示されます他のタブへのリンクがある場合には仮想的なノードを表示しますこの仮想的ノードをクリックすると対応するタブに移動できます</p>
<p><b>: </b></p>
</script>

View File

@@ -1,75 +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.
-->
<script type="text/x-red" data-help-name="exec">
<p>システムのコマンドを実行し出力を返します</p>
<p>コマンドの完了まで待つかコマンドが出力を行う毎にメッセージを出力するかを指定できます</p>
<p>実行対象のコマンドはノードの設定もしくは受信メッセージで指定します</p>
<h3>入力</h3>
<dl class="message-properties">
<dt class="optional">payload <span class="property-type">文字列</span></dt>
<dd>実行コマンドの最後に追加するよう設定できます</dd>
<dt class="optional">kill <span class="property-type">文字列</span></dt>
<dd>execードのプロセスに対して送るシグナルの種別を指定します</dd>
<dt class="optional">pid <span class="property-type">数値|文字列</span></dt>
<dd>シグナル送信対象のexecードのプロセスID</dd>
</dl>
<h3>出力</h3>
<ol class="node-ports">
<li>標準出力(stdout)
<dl class="message-properties">
<dt>payload <span class="property-type">文字列</span></dt>
<dd>コマンドの標準出力</dd>
</dl>
<dl class="message-properties">
<dt>rc <span class="property-type">オブジェクト</span></dt>
<dd>返却コードオブジェクト(3番目の端子でも受取り可能)のコピー(execモードのみ)</dd>
</dl>
</li>
<li>標準エラー出力(stderr)
<dl class="message-properties">
<dt>payload <span class="property-type">文字列</span></dt>
<dd>コマンドの標準エラー出力</dd>
</dl>
<dl class="message-properties">
<dt>rc <span class="property-type">オブジェクト</span></dt>
<dd>返却コードオブジェクト(3番目の端子でも受取り可能)のコピー(execモードのみ)</dd>
</dl>
</li>
<li>返却コード(return code)
<dl class="message-properties">
<dt>payload <span class="property-type">オブジェクト</span></dt>
<dd>リターンコード<code>message</code><code>signal</code>(<code>message</code><code>signal</code>)</dd>
</dl>
</li>
</ol>
<h3>詳細</h3>
<p>デフォルトでは<code>exec</code><code>{ code: 0 }</code></p>
<p><code>spawn</code>使
標準出力および標準エラー出力へ出力を返すようにすることもできますこの場合通常1行毎に値を返しますコマンドの実行が完了すると3番目の端子にオブジェクトを出力します例えばコマンドの実行が成功した場合には<code>{ code: 0 }</code></p>
<p>エラー発生時には3番目の端子の<code>msg.payload</code><code>message</code><code>signal</code></p>
<p>実行対象のコマンドはノード設定で定義します<code>msg.payload</code></p>
<p>コマンドもしくはパラメータが空白を含む場合には引用符で囲みます- <code>"This is a single parameter"</code></p>
<p>返却する<code>payload</code>は通常<i>文字列</i>ですがUTF8文字以外が存在すると<i>バッファ</i></p>
<p>ノードが実行中の場合ステータスアイコンとPIDを表示しますこの状態変化は<code>status</code></p>
<h4>プロセスの停止</h4>
<p><code>msg.kill</code><code>msg.kill</code><code>SIGINT</code><code>SIGQUIT</code><code>SIGHUP</code><code>SIGTERM</code></p>
<p>ードが1つ以上のプロセスを実行している場合<code>msg.pid</code>PID</p>
<p><code>タイムアウト</code></p>
<p>ヒント: Pythonアプリケーションを実行する場合<code>-u</code></p>
</script>

View File

@@ -1,43 +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.
-->
<script type="text/x-red" data-help-name="function">
<p>受信メッセージに対して処理を行うJavaScriptコード(関数の本体)を定義します</p>
<p>入力メッセージは<code>msg</code>JavaScript</p>
<p><code>msg</code><code>msg.payload</code></p>
<p>通常コードはメッセージオブジェクト(もしくは複数のメッセージオブジェクト)を返却します何も返却しない場合にはフロー実行を停止します</p>
<h3>詳細</h3>
<p>コードの書き方の詳細については<a target="_blank" href="http://nodered.org/docs/writing-functions.html">オンラインドキュメント</a></p>
<h4>メッセージの送信</h4>
<p>フロー内の次ノードにメッセージを渡すためにはメッセージを返却するか<code>node.send(messages)</code></p>
<p>返却/sendの対象は次のとおりです:</p>
<ul>
<li>単一メッセージオブジェクト - 最初の出力に接続されたノードに渡されます</li>
<li>メッセージオブジェクトの配列 - 対応する出力に接続されたノードに渡されます</li>
</ul>
<p>配列要素が配列の場合には複数のメッセージを対応する出力に送出します</p>
<p>返却方法が単一値か配列要素かにかかわらず返却値がnullの場合メッセージの送出は行いません</p>
<h4>ログ出力とエラー処理</h4>
<p>ログ情報の出力エラー出力を行うには以下の関数を用います:</p>
<ul>
<li><code>node.log("ログメッセージ")</code></li>
<li><code>node.warn("警告")</code></li>
<li><code>node.error("エラー")</code></li>
</ul>
</p>
<p>catchードを用いてエラー処理が可能ですcatchードで処理させるためには<code>msg</code><code>node.error</code>:</p>
<pre>node.error("エラー",msg);</pre>
</script>

View File

@@ -1,47 +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.
-->
<script type="text/x-red" data-help-name="template">
<p>テンプレートに基づいてプロパティを設定します</p>
<h3>入力</h3>
<dl class="message-properties">
<dt>msg <span class="property-type">オブジェクト</span></dt>
<dd>テンプレートを生成するための情報を含むメッセージオブジェクト</dd>
<dt class="optional">template <span class="property-type">文字列</span></dt>
<dd><code>msg.payload</code></dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>msg <span class="property-type">オブジェクト</span></dt>
<dd>指定したテンプレートと入力メッセージのプロパティから生成した値を設定したメッセージ</dd>
</dl>
<h3>詳細</h3>
<p>このノードは<i><a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache</a></i>形式をデフォルトで利用しますが使用しないようにすることもできます</p>
<p>例えば
<pre>こんにちは{{payload.name}}さん今日は{{date}}です</pre>
<p>というテンプレートに対して
<pre>{
date: "月曜日"
payload: {
name: "山田",
}
}</pre>
<p>というメッセージを受信した場合</p>
<pre>こんにちは山田さん今日は月曜日です</pre>
<p>というプロパティが生成されます</p>
<p>フローコンテキストもしくはグローバルコンテキストのプロパティ値を使うこともできますそれぞれ<code>{{flow.名前}}</code><code>{{global.}}</code></p>
<p><b>: </b>デフォルトでは、<i>mustache</i>形式は置換対象のHTML要素をエスケープしますこれを抑止するには<code>{{{三重}}}</code>使</p>
</script>

View File

@@ -1,30 +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.
-->
<script type="text/x-red" data-help-name="delay">
<p>ノードを通過するメッセージを遅延もしくは流量を制限します</p>
<h3>入力</h3>
<dl class="message-properties">
<dt class="optional">delay <span class="property-type">数値</span></dt>
<dd>メッセージの遅延時間をミリ秒単位で設定しますこれはノードの設定でデフォルトの遅延時間を上書きできるようノードを設定した場合にのみ適用します</dd>
<dt class="optional">reset</dt>
<dd>受信メッセージでこのプロパティを任意の値に設定するとノードが保持する全ての未送信メッセージをクリアします</dd>
</dl>
<h3>詳細</h3>
<p>メッセージを遅延させるように設定する場合遅延時間は固定値範囲内の乱数値メッセージ毎の動的な指定値のいずれかを指定できます</p>
<p>流量制御する場合メッセージは指定した時間間隔内に分散して送信しますキューに残っているメッセージ数はノードのステータスに表示されます受け取った中間メッセージを破棄することも可能です</p>
<p>流量制御は全てのメッセージに適用することも<code>msg.topic</code></p>
</script>

View File

@@ -1,33 +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.
-->
<script type="text/x-red" data-help-name="trigger">
<p>メッセージの受信すると別のメッセージの送信を行います延長もしくは初期化が指定されていない場合には2つ目のメッセージを送信することもできます</p>
<h3>入力</h3>
<dl class="message-properties">
<dt class="optional">reset</dt>
<dd>このプロパティを持つメッセージを受け取ると仕掛かり中の待機や繰り返しをクリアしメッセージの送信は行いません</dd>
</dl>
<h3>詳細</h3>
<p>フロー内でタイムアウトを作成するのに利用しますメッセージを受け取るとデフォルトでは<code>payload</code><code>1</code>250ms<code>payload</code><code>0</code>2Raspberry PIGPIOLED</p>
<p>各送信メッセージのペイロードはさまざまな種類の値に設定できます再送信データなしとすることも可能です例えば再送信データを<i>なし</i>trigger</p>
<p>ペイロードに<i>文字列</i>mustache</p>
<p><code>reset</code><code>payload</code></p>
<p>受信メッセージでリセットするまで一定間隔でメッセージを再送するように指定することもできます</p>
<p><code>msg.topic</code></p>
</script>

View File

@@ -1,21 +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.
-->
<script type="text/x-red" data-help-name="comment">
<p>フローにコメントを記述するために利用します</p>
<h3>詳細</h3>
<p>編集パネルはMarkdown形式を記入可能です入力したテキストは情報サイドパネルに表示されます</p>
</script>

View File

@@ -1,24 +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.
-->
<script type="text/x-red" data-help-name="unknown">
<p>インストールされたNode-REDが認識できない種別のードです</p>
<h3>詳細</h3>
<p><i>この種別のノードをデプロイした場合設定は保持されますが足りないノードをインストールするまでフローを開始することはできません</i></p>
<p><code>メニュー - パレットの管理</code>使<b>npm install &lt;&gt;</b>Node-RED</p>
<p>この種別のノードがインストール済みであるが依存ライブラリがインストールされていないケースもありますNode-REDの起動ログを参照して不足ードに関連したエラーメッセージをチェックすると良いでしょう</p>
<p>それでも解決しない場合フローの作者に依頼して不足ノードのコピーを入手してください</p>
</script>

View File

@@ -1,71 +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.
-->
<script type="text/x-red" data-help-name="rpi-gpio in">
<p>Raspberry Piの入力ード入力ピンの状態に応じて0 または 1 の値を持つ<code>msg.payload</code></p>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">数値</span></dt>
<dd>ペイロードには0 または 1 が設定されます</dd>
<dt>topic <span class="property-type">文字列</span></dt>
<dd>トピックには<code>pi/{ピン番号}</code></dd>
</dl>
<h3>詳細</h3>
<p>入力のプルアップ抵抗またはプルダウン抵抗を有効にすることもできます</p>
<p>動作にはRPi.GPIO pythonライブラリのバージョン 0.5.10 (またはそれ以上)が必要です</p>
</script>
<script type="text/x-red" data-help-name="rpi-gpio out">
<p>Raspberry Piの出力ードデジタルモードまたはPWMモードで利用できます
<h3>入力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">数値 | 文字列 | 真偽値</span></dt>
</dl>
<h3>詳細</h3>
<p>デジタルモード - <code>msg.payload</code> 0 1 ( true false ) </p>
<p>デプロイ時にピンの初期値として 0 または 1 を設定することもできます</p>
<p>PWMモード - 入力値に 0 から 100 の数値を指定でき小数値の指定も可能です</p>
<p>サーボの制御にPWMモードが利用でき入力に小数値も含む 10 から 20 の値が指定可能です
PWMを行うハードウェアを利用していることからPWMモードの指定にはGPIO2ピンが最も適しています
より良くサーボの制御を行いたい場合はnode-red-node-pi-gpiod ノードの利用も検討してください</p>
<p>動作にはRPi.GPIO pythonライブラリのバージョン 0.5.10 (またはそれ以上)が必要です</p>
</script>
<script type="text/x-red" data-help-name="rpi-mouse">
<p>Raspberry Pi のマウスボタンノードUSBマウスが必要です</p>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">数値</span></dt>
<dd>選択されたマウスのボタンが押されたまたは離された場合に 1 または 0 が設定されます</dd>
<dt>button <span class="property-type">数値</span></dt>
<dd>真ん中のボタンに応じて 1, 2, 4 が設定されボタンあるいはボタンの組み合わせに応じた処理ができます</dd>
<dt>topic <span class="property-type">文字列</span></dt>
<dd><code>pi/mouse</code></dd>
</dl>
</script>
<script type="text/x-red" data-help-name="rpi-keyboard">
<p>Raspberry Pi のキーボードを制御するノードUSBキーボードが必要です</p>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">数値</span></dt>
<dd>キーコードを含みます</dd>
<dt>action <span class="property-type">文字列</span></dt>
<dd>"up", "down", または "repeat" が設定されます</dd>
<dt>topic <span class="property-type">文字列</span></dt>
<dd><code>pi/key</code></dd>
</dl>
</script>

View File

@@ -1,19 +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.
-->
<script type="text/x-red" data-help-name="tls-config">
<p>TLS接続のためのオプション設定</p>
</script>

View File

@@ -1,72 +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.
-->
<script type="text/x-red" data-help-name="mqtt in">
<p>MQTTブローカに接続し指定したトピックのメッセージをサブスクライブ(購読)します</p>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">文字列 | バッファ</span></dt>
<dd>バイナリバッファでない場合は文字列</dd>
<dt>topic <span class="property-type">文字列</span></dt>
<dd>MQTTのトピック/を階層の区切りに使用する</dd>
<dt>qos <span class="property-type">数値</span> </dt>
<dd>0: 最大1度到着, 1: 一度以上到着, 2: 1度のみ到着</dd>
<dt>retain <span class="property-type">真偽値</span></dt>
<dd>真の場合メッセージを保持メッセージが古い値の場合があります</dd>
</dl>
<h3>詳細</h3>
<p>購読トピックにはMQTTのワイルドカード(+: 1レベル, #: 複数レベル)を含めることができます</p>
<p>このノードの利用のためにはMQTTブローカへの接続設定が必要ですこの設定は鉛筆アイコンをクリックすることで行えます</p>
<p>MQTT(inおよびout)ノードはブローカへの接続設定を必要に応じて共有できます</p>
</script>
<script type="text/x-red" data-help-name="mqtt out">
<p>MQTTブローカに接続しメッセージをパブリッシュ(発行)します</p>
<h3>入力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">文字列 | バッファ</span></dt>
<dd>多くの場合単純なテキスト形式のペイロードが使われますがバイナリバッファを発行することも可能です</dd>
<dt class="optional">topic <span class="property-type">文字列</span></dt>
<dd>発行対象のMQTTトピック</dd>
<dt class="optional">qos <span class="property-type">数値</span></dt>
<dd>0: 最大1度到着, 1: 一度以上到着, 2: 1度のみ到着デフォルトは0です</dd>
<dt class="optional">retain <span class="property-type">真偽値</span></dt>
<dd>真の場合メッセージをブローカに保持しますデフォルトは偽です</dd>
</dl>
<h3>詳細</h3>
<p><code>msg.payload</code>JSON</p>
<p>発行に利用するトピックはノードに設定するかもしくは<code>msg.topic</code></p>
<p>同様にQoSとretainもードの設定もしくはノードの設定が空の場合にはそれぞれ<code>msg.qos</code><code>msg.retain</code>retain</p>
<p>このノードの利用のためにはMQTTブローカへの接続設定が必要ですこの設定は鉛筆アイコンをクリックすることで行えます</p>
<p>MQTT(inおよびout)ノードはブローカへの接続設定を必要に応じて共有できます</p>
</script>
<script type="text/x-red" data-help-name="mqtt-broker">
<p>MQTTブローカへの接続設定</p>
<p>ブローカへの接続設定を作成します設定は<code>MQTT In</code><code>MQTT Out</code></p>
<p>ードにクライアントIDを設定しておらずセッションの初期化を設定している場合ランダムなクライアントIDを生成しますクライアントIDを設定する場合接続先のブローカで一意となるようにしてください</p>
<h4>Birthメッセージ</h4>
<p>接続を確立した際に設定したトピックに対して発行するメッセージ</p>
<h4>Willメッセージ</h4>
<p>予期せず接続が切断された場合にブローカが発行するメッセージ</p>
<h4>WebSocket</h4>
<p>WebSocketによる接続を行うように設定できますWebSocketを利用するにはサーバフィールドに接続先のURIを完全な形式で記述します以下に例を示します</p>
<pre>ws://example.com:4000/mqtt</pre>
</script>

View File

@@ -1,81 +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.
-->
<script type="text/x-red" data-help-name="http in">
<p>HTTPエンドポイントを作成しWebサービスを構成します</p>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload</dt>
<dd>GETリクエストの場合クエリパラメータからなるオブジェクトそれ以外の場合HTTPリクエストの本体を指します</dd>
<dt>req<span class="property-type">オブジェクト</span></dt>
<dd>HTTPリクエストオブジェクトオブジェクトはリクエストの情報に関する複数のプロパティを含みます
<ul>
<li><code>body</code> - </li>
<li><code>headers</code> - HTTP</li>
<li><code>query</code> - </li>
<li><code>params</code> - </li>
<li><code>cookies</code> - </li>
<li><code>files</code> - POST</li>
</ul>
</dd>
<dt>res<span class="property-type">オブジェクト</span></dt>
<dd>HTTPレスポンスオブジェクトこのプロパティを直接利用することは推奨しませんリクエストの処理方法については<code>HTTP Response</code>response</dd>
</dl>
<h3>詳細</h3>
<p>このノードは設定で指定したパスとリクエスト種別でリクエストを待ち受けますパス指定は完全に指定する形式(: <code>/user</code>)(: <code>/user/:name</code>)<code>msg.req.params</code></p>
<p>POSTやPUTのようにリクエストボディを含むリクエストの場合リクエストの内容は<code>msg.payload</code></p>
<p>リクエストの要素タイプが識別可能な場合にはリクエストボディを適切な形式に変換します例えば<code>application/json</code>JavaScript</p>
<p><b>:</b> HTTP Response</p>
</script>
<script type="text/x-red" data-help-name="http response">
<p>HTTP Inードで受け付けたリクエストに対するレスポンスを送り返します</p>
<h3>入力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">文字列</span></dt>
<dd>レスポンス本体</dd>
<dt class="optional">statusCode <span class="property-type">数値</span></dt>
<dd>設定するとレスポンスのステータスコードとしますデフォルト: 200</dd>
<dt class="optional">headers <span class="property-type">オブジェクト</span></dt>
<dd>設定するとレスポンスのHTTPヘッダとします</dd>
<dt class="optional">cookies <span class="property-type">オブジェクト</span></dt>
<dd>設定するとクッキーを設定もしくは削除するために使用します</dd>
</dl>
<h3>詳細</h3>
<p><code>statusCode</code><code>headers</code>使</p>
<h4>クッキーの処理</h4>
<p><code>cookies</code>/使<p>
<p>以下の例では2つのクッキーを設定しています1つ目は<code>name</code><code>nick</code>2<code>session</code><code>1234,</code>15</p>
<pre>
msg.cookies = {
name: 'nick',
session: {
value: '1234',
maxAge: 900000
}
}</pre>
<p>有効なオプションには以下があります</p>
<ul>
<li><code>domain</code> - () </li>
<li><code>expires</code> - () GMT0</li>
<li><code>maxAge</code> - () </li>
<li><code>path</code> - (文字列) クッキーのパス。デフォルトは「/</li>
<li><code>value</code> - () </li>
</ul>
<p>クッキーを削除するには<code>value</code><code>null</code></p>
</script>

View File

@@ -1,60 +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.
-->
<script type="text/x-red" data-help-name="http request">
<p>HTTPリクエストを送信しレスポンスを返します</p>
<h3>入力</h3>
<dl class="message-properties">
<dt class="optional">url <span class="property-type">文字列</span></dt>
<dd>ノードの設定で指定していない場合このプロパティでリクエストのurlを設定します</dd>
<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ヘッダを指定します</dd>
<dt class="optional">cookies <span class="property-type">オブジェクト</span></dt>
<dd>設定するとリクエストと共にクッキーを送ることができます</dd>
<dt class="optional">payload</dt>
<dd>リクエストボディとして送るデータ</dd>
<dt class="optional">rejectUnauthorized</dt>
<dd><code>true</code>使https</dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">文字列 | オブジェクト | バッファ</span></dt>
<dd>レスポンスボディ返却するボディデータを文字列JSON文字列として解釈した結果バイナリバッファのままのいずれにするかをノード設定により指定できます</dd>
<dt>statusCode <span class="property-type">数値</span></dt>
<dd>レスポンスのステータスコードもしくはリクエストが完了しなかった場合のエラーコード</dd>
<dt>headers <span class="property-type">オブジェクト</span></dt>
<dd>レスポンスヘッダを含むオブジェクト</dd>
<dt>responseUrl <span class="property-type">文字列</span></dt>
<dd>リクエストの処理時にリダイレクトが発生した場合このプロパティが最後にリダイレクトされたURLを表しますリダイレクトが起こらなかった場合最初リクエストのURLを表します</dd>
<dt>responseCookies <span class="property-type">オブジェクト</span></dt>
<dd>レスポンスがクッキーを含む場合このプロパティは各クッキーの名前/値を含むオブジェクトを表します</dd>
</dl>
<h3>詳細</h3>
<p>ードの設定でurlプロパティを指定する場合<a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache形式</a>のタグを含めることができます。これにより、URLを入力メッセージの値から構成することができます。例えば、urlが<code>example.com/{{{topic}}}</code><code>msg.topic</code>{{{...}}}使/&mustache</p>
<p><b></b>: proxy<code>http_proxy=...</code>Node-RED</p>
<h4>複数のHTTPリクエストードの利用</h4>
<p>同一フローで本ノードを複数利用するためには<code>msg.headers</code><code>msg.headers</code>2<code>msg.headers</code><code>{}</code>
<h4>クッキーの扱い</h4>
<p>ノードに<code>cookies</code>/<code>value</code><p>
<p>リクエストに対して返却されたクッキーは<code>responseCookies</code></p>
<h4>要素タイプの扱い</h4>
<p><code>msg.payload</code><code>msg.payload</code>JSON</p>
<p>リクエストをフォームデータにエンコードするには<code>msg.headers["content-type"]</code><code>application/x-www-form-urlencoded</code></p>
</script>

View File

@@ -1,36 +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.
-->
<script type="text/x-red" data-help-name="websocket in">
<p>WebSocket入力ード</p>
<p>デフォルトではWebSocketにより受信したデータは<code>msg.payload</code>JSONJSON</p>
</script>
<script type="text/x-red" data-help-name="websocket out">
<p>WebSocket出力ード</p>
<p>デフォルトでは<code>msg.payload</code>WebSocket<code>msg</code>JSONWebSocket</p>
<p>このードが受信したメッセージがWebSocket Inードが生成したものである場合メッセージはフローを起動したクライアントに送り返されますそれ以外の場合メッセージは接続している全てのクライアントにブロードキャストされます</p>
<p>WebSocket Inードが生成したメッセージをブロードキャストしたい場合にはフロー中で<code>msg._session</code></p>
</script>
<script type="text/x-red" data-help-name="websocket-listener">
<p>この設定ードはパスを指定してWebSocketサーバのエンドポイントを作成します</p>
</script>
<script type="text/x-red" data-help-name="websocket-client">
<p>この設定ードは指定したURLにWebSocketクライアントを接続します</p>
</script>

View File

@@ -1,25 +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.
-->
<script type="text/x-red" data-help-name="watch">
<p>ディレクトリもしくはファイルの変化を検知します</p>
<p>カンマ区切りでディレクトリおよびファイルのリストを指定します空白を含む場合は引用符で"..."のように囲んでください</p>
<p>Windowsでは2重バックスラッシュ\\をディレクトリ名に使用します</p>
<p>実際に変化したファイルのフルパス名を<code>msg.payload</code><code>msg.topic</code></p>
<p><code>msg.file</code><code>msg.type</code>(<i>file</i><i>directory</i>)<code>msg.size</code>()</p>
<p>Linuxではファイルとして表されるもの<i>全て</i></p>
<p><b>: </b></p>
</script>

View File

@@ -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.
-->
<script type="text/x-red" data-help-name="tcp in">
<p>TCPからの入力を行いますリモートTCPポートに接続するか外部らからのコネクションを受け付けます</p>
<p><b>: </b>1024rootadministrator</p>
</script>
<script type="text/x-red" data-help-name="tcp out">
<p>TCPへの出力を行いますリモートTCPポートへ接続外部からのコネクションの受け付けもしくはTCP Inードで受け付けたメッセージへのリプライを行います</p>
<p><code>msg.payload</code></p>
<p><code>msg.payload</code>Base64Base64</p>
<p><code>msg._session</code><b></b></p>
<p><b>: </b>1024rootadministrator</p>
</script>
<script type="text/x-red" data-help-name="tcp request">
<p>シンプルなTCPリクエストード<code>msg.payload</code>TCP</p>
<p>サーバに接続"リクエスト"送信"レスポンス"受信を行います固定長の文字数指定文字へのマッチ最初のリプライの到着から指定した時間待つデータの到着待ちデータ送信を行いリプライを待たず接続を即時解除などから動作を選択できます</p>
<p>レスポンスはバッファ形式で<code>msg.payload</code>toString()使</p>
<p>TCPホストのポート番号設定を空にした場合<code>msg.host</code><code>msg.port</code></p>
</script>

View File

@@ -1,28 +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.
-->
<script type="text/x-red" data-help-name="udp in">
<p>UDP入力ード<code>msg.payload</code>Base64</p>
<p><code>msg.ip</code><code>msg.port</code>IP</p>
<p><b></b>: 1024rootadministrator</p>
</script>
<script type="text/x-red" data-help-name="udp out">
<p><code>msg.payload</code>UDP</p>
<p><code>msg.ip</code><code>msg.port</code></p>
<p>ブロードキャストを行うにはアドレスをローカルブロードキャストIPアドレスに設定するかグローバルブロードキャストアドレスである255.255.255.255を試してください</p>
<p><b></b>: 1024rootadministrator</p>
</script>

View File

@@ -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.
-->
<script type="text/x-red" data-help-name="switch">
<p>プロパティの値によってメッセージの振り分けを行います</p>
<h3>詳細</h3>
<p>受信したメッセージに対し指定されたルールを順に評価しマッチしたルールに対応する出力ポートにメッセージを送出します</p>
<p>最初にルールがマッチしたところで評価を止めることも可能です</p>
<p>評価ルールにはメッセージプロパティフローコンテキスト/グローバルコンテキストのプロパティJSONata式の評価結果が利用できます</p>
<h3>ルール</h3>
<p>振り分けルールは以下の4つに分類されます</p>
<ol>
<li><b>(value)</b> - </li>
<li><b>(sequence)</b> - (split)</li>
<li><b>JSONata式</b> - </li>
<li><b>その他</b> - </li>
</ol>
<h3>メッセージ列の扱い</h3>
<p>switchードは入力メッセージの列に関する情報を保持する<code>msg.parts</code></p>
<p><b>メッセージ列の補正</b>switch<code>nodeMessageBufferMaxLength</code></p>
</script>

View File

@@ -1,33 +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.
-->
<script type="text/x-red" data-help-name="change">
<p>メッセージフローコンテキストグローバルコンテキストのプロパティを変更削除移動します</p>
<p>ルールを複数指定した場合定義した順に適用します</p>
<h3>詳細</h3>
<p>利用可能な処理</p>
<dl class="message-properties">
<dt>代入</dt>
<dd>プロパティをセットします設定値にはさまざまな型の値メッセージやコンテキストの既存プロパティを利用できます<dd>
<dt>置換</dt>
<dd>プロパティに対して検索と置換を行います正規表現を指定した場合置換後の文字列には<code>$1</code></dd>
<dt>削除</dt>
<dd>プロパティを削除します</dd>
<dt>移動</dt>
<dd>プロパティの移動または名前の変更を行います</dd>
</dl>
<p>expressionには<a href="http://jsonata.org/" target="_new">JSONata</a></p>
</script>

View File

@@ -1,33 +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.
-->
<script type="text/x-red" data-help-name="range">
<p>数値を異なる範囲の値に変換します</p>
<h3>入力</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">数値</span></dt>
<dd>数値以外の場合は数値に変換します変換不能な場合はラーとなります</dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">数値</span></dt>
<dd>新しい範囲に変換した結果の値</dd>
</dl>
<h3>詳細</h3>
<p>このノードは受け取った数値を線形スケーリングしますデフォルトでは結果の値はノードに設定した範囲内に限定しません</p>
<p><i>入力値の範囲外の値を最小値/最大値として拡大/縮小</i></p>
<p><i>入力値の範囲外の値を範囲幅で割った余りとし拡大/縮小</i></p>
</script>

View File

@@ -1,137 +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.
-->
<script type="text/x-red" data-help-name="split">
<p>メッセージをメッセージ列に分割します</p>
<h3>入力</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">オブジェクト | 文字列 | 配列 | バッファ</span></dt>
<dd><code>msg.payload</code>
<ul>
<li><b>文字列</b>/<b>バッファ</b> - (: <code>\n</code>)</li>
<li><b>配列</b> - </li>
<li><b>オブジェクト</b> - /</li>
</ul>
</dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>parts<span class="property-type">オブジェクト</span></dt>
<dd>元のメッセージをどのように分割したかに関する情報をこのプロパティに保持します例えば<b>join</b><code>parts</code>
<ul>
<li><code>id</code> - </li>
<li><code>index</code> - </li>
<li><code>count</code> - </li>
<li><code>type</code> - - ///</li>
<li><code>ch</code> - </li>
<li><code>key</code> -
ノードの設定によりキーを<code>msg.topic</code></li>
<li><code>len</code> - </li>
</ul>
</dd>
</dl>
<h3>詳細</h3>
<p>このノードはメッセージ列を構成するメッセージに対して共通処理を行い<b>join</b></p>
<p><code>msg.parts</code></p>
<h4>ストリームモード</h4>
<p>このノードはメッセージ列を再構成して送信する際にも有用です例えば改行終端のコマンドを送信するようなシリアルデバイスではメッセージの最後のコマンド部分が途切れたメッセージを送出する場合がありますストリームモードを用いることで完結した個別コマンドにメッセージを分割することができます入力メッセージの最後に未完部分がある場合<b>split</b></p>
<p>このモードで処理する際にはメッセージ数を予め知ることができないため<code>msg.parts.count</code><b>join</b></p>
</script>
<script type="text/x-red" data-help-name="join">
<p>メッセージ列を結合して一つのメッセージにします</p>
<p>メッセージの結合には次の3つのモードが利用できます</p>
<dl>
<dt>自動</dt>
<dd><b>split</b>split</dd>
<dt>手動</dt>
<dd>メッセージ列をさまざまな方法で結合します</dd>
<dt>列の集約</dt>
<dd>メッセージ列に対して指定した式を適用し1つのメッセージに集約します</dd>
</dl>
<h3>入力</h3>
<dl class="message-properties">
<dt class="optional">parts<span class="property-type">オブジェクト</span></dt>
<dd>自動的にメッセージ列を結合するには全メッセージがこのプロパティを持っていなければなりません<b>split</b><code>parts</code>
<ul>
<li><code>id</code> - </li>
<li><code>index</code> - </li>
<li><code>count</code> - </li>
<li><code>type</code> - - string/array/object/buffer</li>
<li><code>ch</code> - </li>
<li><code>key</code> - </li>
<li><code>len</code> - </li>
</ul>
</dd>
<dt class="optional">complete</dt>
<dd>設定されている場合保持しているメッセージを結合して送信します</dd>
</dl>
<h3>詳細</h3>
<h4>自動モード</h4>
<p>自動モードでは入力メッセージの<code>parts</code><b>split</b></p>
<h4>手動モード</h4>
<p>手動モードではメッセージ列をさまざまな結果に結合できます</p>
<ul>
<li><b>文字列</b><b></b> - </li>
<li><b>配列</b> - </li>
<li><b>key/valueオブジェクト</b> - </li>
<li><b>統合オブジェクト</b> - </li>
</ul>
<p>出力メッセージのその他のプロパティはメッセージを送信する直前のメッセージをコピーします</p>
<p><i>合計値</i></p>
<p><i></i></p>
<p><code>msg.complete</code></p>
<h4>列の集約モード</h4>
<p>列の集約モードを選択するとメッセージ列を構成する各々のメッセージに対して式を適用し集約した値を用いて一つのメッセージを構成します</p>
<dl class="message-properties">
<dt>初期値</dt>
<dd>
集約の初期値(<code>$A</code>)
</dd>
<dt>集約式</dt>
<dd>メッセージグループを構成する各メッセージに適用するJSONata式
式の評価結果は次回の呼び出しの際に集約値として渡します
<ul>
<li><code>$A</code> </li>
<li><code>$I</code> </li>
<li><code>$N</code> </li>
</ul>
</dd>
<dt>最終調整式</dt>
<dd>メッセージグループの集約が完了した後で適用されるJSONata式任意で指定可能です式中では以下の特殊変数を参照できます
<ul>
<li><code>$A</code> </li>
<li><code>$N</code> </li>
</ul>
</dd>
<p>メッセージグループのメッセージに対しデフォルトでは集約式は最初のメッセージから最後のメッセージに対し順に適用します指定により適用を逆順にすることも可能です</p>
</dl>
<p><b>:</b>
<ul>
<li><b>集約式</b>: <code>$A+payload</code></li>
<li><b>初期値</b>: <code>0</code></li>
<li><b>最終調整式</b>: <code>$A/$N</code></li>
</ul>
</p>
<h4>メッセージの蓄積</h4>
<p>このノードの処理ではメッセージ列の処理のためメッセージを内部に蓄積します<code>nodeMessageBufferMaxLength</code></p>
</script>

View File

@@ -1,40 +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.
-->
<script type="text/x-red" data-help-name="sort">
<p>メッセージ列もしくは配列型のペイロードをソートします</p>
<p><b>split</b></p>
<p>ソート順序は以下が指定可能です</p>
<ul>
<li><b>昇順</b></li>
<li><b>降順</b></li>
</ul>
<p>数値による並べ替えを選択することもできます</p>
<p>メッセージの並べ替えを行うためのソートキーは<code>payload</code>JSONataJSONata</p>
<p>sortードの処理では受信したメッセージが<code>msg.parts</code>split<code>parts</code></p>
<p>
<ul>
<li><code>id</code> - </li>
<li><code>index</code> - </li>
<li><code>count</code> - </li>
</ul>
</p>
<p><b>:</b> 使
<ul>
<li><b>settings.js</b><code>nodeMessageBufferMaxLength</code></li>
</ul>
</p>
</script>

View File

@@ -1,34 +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.
-->
<script type="text/x-red" data-help-name="batch">
<p>指定したルールによりメッセージ列を生成します</p>
<h3>詳細</h3>
<p>メッセージ列の生成には以下の3つのモードが利用できます</p>
<dl>
<dt>入力メッセージ数でグループ化</dt>
<dd>入力メッセージを指定した長さのメッセージ列にグループ化しますメッセージ列の最後の部分を次のメッセージ列の先頭で繰り返すメッセージ数を<b>オーバラップ</b></dd>
<dt>入力間隔()でグループ化</dt>
<dd>指定時間間隔内に受信した入力メッセージをメッセージ列にグループ化します指定した時間内にメッセージを受信しない場合に空のメッセージを送信するように設定することもできます</dd>
<dt>メッセージグループの結合</dt>
<dd>入力メッセージ列を結合し1つのメッセージ列にしますメッセージ列の識別のため各メッセージは<code>msg.topic</code><code>msg.parts</code><code>topic</code>batch
</dd>
</dl>
<h4>メッセージの蓄積</h4>
<p>このノードの処理ではメッセージ列の処理のためメッセージを内部に蓄積します<code>nodeMessageBufferMaxLength</code></p>
</script>

View File

@@ -234,7 +234,7 @@
"and": "回/",
"rate": "流量",
"msgper": "メッセージ/",
"dropmsg": "中間メッセージを削除",
"dropmsg": "仲介メッセージを削除",
"label": {
"delay": "delay",
"variable": "variable",
@@ -327,22 +327,17 @@
"verify-server-cert": "サーバの証明書を確認",
"compatmode": "旧MQTT 3.1のサポート"
},
"sections-label":{
"birth-message": "接続時の送信メッセージ(Birthメッセージ)",
"will-message":"予期しない切断時の送信メッセージ(Willメッセージ)",
"close-message":"切断前の送信メッセージ(Closeメッセージ)"
},
"tabs-label": {
"connection": "接続",
"security": "セキュリティ",
"messages": "メッセージ"
"will": "Willメッセージ",
"birth": "Birthメッセージ"
},
"placeholder": {
"clientid": "IDを自動生成する場合は、無記入にしてください",
"clientid-nonclean": "新規ではないセッションを設定してください",
"will-topic": "Willメッセージを無効化する場合は、無記入にしてください",
"birth-topic": "Birthメッセージを無効化する場合は、無記入にしてください",
"close-topic": "Closeメッセージを無効化する場合は、無記入にしてください"
"birth-topic": "Birthメッセージを無効化する場合は、無記入にしてください"
},
"state": {
"connected": "ブローカへ接続しました: __broker__",
@@ -493,14 +488,14 @@
"output": "出力",
"group": "グループ",
"interface": "ローカルIP",
"interfaceprompt": "(任意) 使用するローカルIPアドレス",
"send": "送信",
"toport": "ポート",
"address": "アドレス",
"decode-base64": "Base64形式のペイロードを復号"
},
"placeholder": {
"interface": "(任意) 使用するローカルインターフェイスもしくはアドレス",
"interfaceprompt": "(任意) 使用するローカルインターフェイスもしくはアドレス",
"interface": "(任意) eth0のIPアドレス",
"address": "宛先IPアドレス"
},
"udpmsgs": "UDPメッセージ",
@@ -528,11 +523,10 @@
"mc-group": "udpードがグループ __group__ へマルチキャストしました",
"listener-stopped": "udpードが待ち受けを停止しました",
"output-stopped": "udpードが出力を停止しました",
"mc-ready": "udpードはマルチキャストの準備ができています: __iface__:__outport__ -> __host__:__port__",
"mc-ready": "udpードはマルチキャストの準備ができています: __outport__ -> __host__:__port__",
"bc-ready": "udpードはブロードキャストの準備ができています: __outport__ -> __host__:__port__",
"ready": "udpードは準備ができています: __outport__ -> __host__:__port__",
"ready-nolocal": "udpードは準備ができています: __host__:__port__",
"re-use": "udp再利用ソケット: __outport__ -> __host__:__port__"
"ready-nolocal": "udpードは準備ができています: __host__:__port__"
},
"errors": {
"access-error": "UDP接続エラー 管理者権限で1024未満のポート番号にアクセスできる必要があります",
@@ -542,8 +536,6 @@
"ip-notset": "udp: IPアドレスが設定されていません",
"port-notset": "udp: ポートが設定されていません",
"port-invalid": "udp: ポート番号が不正です",
"alreadyused": "udp: 既に__port__番ポートが使用されています",
"ifnotfound": "udp: インターフェイス __iface__ がありません",
"alreadyused": "udp: 既にポートが使用されています"
}
},
@@ -669,8 +661,7 @@
"html": {
"label": {
"select": "抽出する要素",
"output": "出力",
"in": "対象:"
"output": "出力"
},
"output": {
"html": "要素内のHTML",
@@ -770,9 +761,7 @@
"status": {
"stopped": "停止",
"closed": "切断",
"not-running": "停止中",
"not-available": "利用不可",
"na": "N/A : __value__"
"not-running": "停止中"
},
"errors": {
"ignorenode": "Raspberry Pi固有のードを無視しました",

View File

@@ -1,44 +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.
-->
<script type="text/x-red" data-help-name="csv">
<p>CSV形式の文字列とそのJavaScriptオブジェクト表現の間で双方向の変換を行います</p>
<h3>入力</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">オブジェクト | 配列 | 文字列</span></dt>
<dd>JavaScriptオブジェクト配列CSV文字列のいずれか</dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">オブジェクト | 配列 | 文字列</span></dt>
<dd>
<ul>
<li>入力が文字列の場合CSVとして解釈しCSVの各行をキー/バリューとしたJavaScriptオブジェクトを生成します
各行毎にメッセージを送信するかオブジェクトの配列からなる一つのメッセージを送信するかを選択できます</li>
<li>入力がJavaScriptオブジェクトの場合CSV文字列への変換を行います</li>
<li>入力が基本型の配列の場合1行のCSV文字列へ変換します</li>
<li>入力が配列の配列もしくはオブジェクトの配列の場合複数行のCSV文字列へ変換します</li>
</ul>
</dd>
</dl>
<h3>詳細</h3>
<p>列名にカラム名のリストを指定することができますCSVからオブジェクトに変換を行う際カラム名をプロパティ名として使用します列名の代わりにCSVデータの1行目にカラム名を含めることもできます</p>
<p>CSVへの変換を行う際にはオブジェクトから取り出すべきプロパティとその順序を列名を参照して決めます</p>
<p>入力が配列の場合には列名はカラム名を表す行の出力指定がされた場合だけ用います</p>
<p><code>parts</code></p>
<p>CSVを複数のメッセージに変換して出力する場合出力がメッセージ列となるよう<code>parts</code></p>
<p><b>:</b> </p>
</script>

View File

@@ -1,33 +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.
-->
<script type="text/x-red" data-help-name="html">
<p><code>msg.payload</code>HTMLCSS使</p>
<h3>入力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">文字列</span></dt>
<dd>要素を取り出すHTML文字列</dd>
<dt class="optional">select <span class="property-type">文字列</span></dt>
<dd>編集パネルでセレクタを指定していない場合メッセージのプロパティとして設定できます</dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">配列 | 文字列</span></dt>
<dd>結果はペイロードにマッチした要素の配列を含む単一メッセージもしくはマッチした要素毎のメッセージのいずれかを選択できます複数メッセージを送信する場合メッセージには<code>parts</code></dd>
</dl>
<h3>詳細</h3>
<p>このードはCSSおよびjQueryセレクタの組み合わせをサポートします利用可能な構文の詳細については<a href="https://github.com/fb55/CSSselect#user-content-supported-selectors" target="_blank">css-select documentation</a></p>
</script>

View File

@@ -1,38 +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.
-->
<script type="text/x-red" data-help-name="json">
<p>JSON文字列とJavaScriptオブジェクトとの間で相互変換を行います</p>
<h3>入力</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">オブジェクト | 文字列</span></dt>
<dd>JavaScriptオブジェクトもしくはJSON文字列</dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">オブジェクト | 文字列</span></dt>
<dd>
<ul>
<li>入力が文字列の場合JSONとして解釈しJavaScriptオブジェクトに変換します</li>
<li>入力がJavaScriptオブジェクトの場合JSON文字列に変換しますJSON文字列は整形することも可能です</li>
</ul>
</dd>
</dl>
<h3>詳細</h3>
<p>デフォルトの変換対象は<code>msg.payload</code></p>
<p>双方向の変換を自動選択するのではなく特定の変換のみ行うように設定できますこの機能は例えば<code>HTTP In</code>content-typeJSONJavaScript</p>
<p>JSON文字列への変換が指定されている場合受信した文字列に対してさらなるチェックは行いませんすなわち文字列がJSONとして正しいかどうかの検査や整形オプションを指定していたとしても整形処理を実施しません</p>
</script>

View File

@@ -1,49 +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.
-->
<script type="text/x-red" data-help-name="xml">
<p>XML文字列とJavaScriptオブジェクトとの間で相互変換を行います</p>
<h3>入力</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">オブジェクト | 文字列</span></dt>
<dd>JavaScriptオブジェクトもしくはXML文字列</dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">オブジェクト | 文字列</span></dt>
<dd>
<ul>
<li>入力が文字列の場合XMLとして解釈しJavaScriptオブジェクトに変換します</li>
<li>入力がJavaScriptオブジェクトの場合XML文字列に変換します</li>
</ul>
</dd>
<dt class="optional">options <span class="property-type">オブジェクト</span></dt>
<dd>内部で用いているXMLへの変換ライブラリに対してオプションを渡すことができます詳しくは<a href="https://github.com/Leonidas-from-XIV/node-xml2js/blob/master/README.md#options" target="_blank">the xml2js docs</a></dd>
</dl>
<h3>詳細</h3>
<p>XMLとオブジェクトの間での変換を行う場合デフォルトではXML属性は<code>$</code>
テキストの内容は<code>_</code></p>
<p>例として以下のXMLの変換結果を示します</p>
<pre>&lt;p class="tag"&gt;Hello World&lt;/p&gt;</pre>
<pre>{
"p": {
"$": {
"class": "tag"
},
"_": "Hello World"
}
}</pre>
</script>

View File

@@ -1,34 +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.
-->
<script type="text/x-red" data-help-name="yaml">
<p>YAML形式の文字列とJavaScriptオブジェクトの間で相互変換を行います</p>
<h3>入力</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">オブジェクト | 文字列</span></dt>
<dd>JavaScriptオブジェクトもしくはYAML形式文字列</dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload<span class="property-type">オブジェクト | 文字列</span></dt>
<dd>
<ul>
<li>入力がYAML形式の文字列の場合JavaScriptオブジェクトに変換します</li>
<li>入力がJavaScriptオブジェクトの場合YAML形式の文字列に変換します</li>
</ul>
</dd>
</dl>
</script>

View File

@@ -1,25 +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.
-->
<script type="text/x-red" data-help-name="tail">
<p>設定したファイルの末尾を出力(追加されたデータを監視)します(Linux/Macのみ)</p>
<p>このノードは<b>tail -F</b>Windows</p>
<h3>出力</h3>
<ul>
<li>(UTF-8形式の)テキストファイルは文字列を返却</li>
<li>バイナルファイルはバッファオブジェクトを返却</li>
</ul>
</script>

View File

@@ -1,55 +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.
-->
<script type="text/x-red" data-help-name="file">
<p><code>msg.payload</code></p>
<h3>入力</h3>
<dl class="message-properties">
<dt class="optional">filename <span class="property-type">文字列</span></dt>
<dd>対象ファイル名をノードに設定していない場合このプロパティでファイルを指定できます</dd>
</dl>
<h3>詳細</h3>
<p>入力メッセージのペイロードをファイルの最後に追記します改行(\n)を各データの最後に追加することもできます</p>
<p><code>msg.filename</code>使</p>
<p>追記を行う代わりにファイル全体を上書きするように設定することもできます例えば画像のようなバイナリデータをファイルに書き出す場合はこのオプションを指定し改行を追記するオプションを指定しないようにします</p>
<p>この他ファイルの削除を行うことも可能です</p>
</script>
<script type="text/x-red" data-help-name="file in">
<p>ファイルの内容を文字列もしくはバイナリバッファとして読み出します</p>
<h3>入力</h3>
<dl class="message-properties">
<dt class="optional">filename <span class="property-type">文字列</span></dt>
<dd>読み出し対象のファイル名をノードに設定していない場合このプロパティでファイルを指定できます</dd>
</dl>
<h3>出力</h3>
<dl class="message-properties">
<dt>payload <span class="property-type">文字列 | バッファ</span></dt>
<dd>ファイルの内容を文字列もしくはバッファで表現します</dd>
<dt class="optional">filename <span class="property-type">文字列</span></dt>
<dd>読み出し対象のファイル名をノードに設定していない場合このプロパティでファイルを指定します</dd>
<dt class="optional">error <span class="property-type">オブジェクト</span></dt>
<dd><i>非推奨</i>: <code>payload</code><code>error</code></dd>
</dl>
<h3>詳細</h3>
<p>ファイルネームは絶対パスでの指定を推奨します絶対パスを指定しない場合はNode-REDプロセスのワーキングディレクトリからの相対パスとして扱います</p>
<p>Windowsではパスの区切り文字を(例えば<code>\\ユーザー\\名前</code>)</p>
<p>テキストファイルの場合行毎に分割して各々メッセージを送信することができますまたバイナリファイルの場合小さな塊のバッファに分割して送信できますバッファの分割単位はオペレーティングシステム依存ですが一般に64k(Linux/Mac)もしくは41k(Windows)です</p>
<p>複数のメッセージに分割する場合各メッセージには<code>parts</code></p>
<h4>旧式のエラー処理</h4>
<p>Node-RED 0.17より前の版ではファイルの読み込み時にエラーが発生すると<code>payload</code><code>error</code></p>
<p>エラーはcatchードで補足して処理することを推奨します</p>
</script>

View File

@@ -5,8 +5,7 @@
"topic": "主题",
"name": "名称",
"username": "用户名",
"password": "密码",
"property": "属性"
"password": "密码"
},
"status": {
"connected": "已连接",
@@ -14,7 +13,7 @@
"disconnected": "已断开",
"connecting": "连接中",
"error": "错误",
"ok": "确"
"ok": "确"
},
"notification": {
"error": "<strong>错误</strong>: __message__",
@@ -38,17 +37,17 @@
"repeat": "重复"
},
"timestamp": "时间戳",
"none": "",
"interval": "周期性执行",
"interval-time": "定时间段周期性执行",
"time": "定时间",
"none": "空白",
"interval": "间隔",
"interval-time": "定时间内间隔",
"time": "定时间",
"seconds": "秒",
"minutes": "分钟",
"hours": "小时",
"between": "介于",
"previous": "之前数值",
"at": "在",
"and": "",
"and": "之间",
"every": "每隔",
"days": [
"星期一",
@@ -60,20 +59,18 @@
"星期天"
],
"on": "在",
"onstart": "立刻执行于",
"onceDelay": "秒后, 此后",
"tip": "<b>注意:</b> \"指定时间段周期性执行\" 和 \"指定时间\" 会使用cron系统.<br/> 详情查看信息页.",
"onstart": "运行时注入?",
"tip": "<b>注意:</b> \"特定时间内间隔\" 和 \"特定时间\" 会使用cron系统.<br/> 详情查看信息页.",
"success": "成功注入: __label__",
"errors": {
"failed": "注入失败, 请查看日志",
"toolong": "周期过长"
"failed": "注入失败, 请查看日志"
}
},
"catch": {
"catch": "监测所有节点",
"catchNodes": "监测__number__个节点",
"catch": "检测异常",
"catchNodes": "检测到 (__number__)",
"label": {
"source": "监测范围",
"source": "检测错误来自",
"node": "节点",
"type": "类型",
"selectAll": "全选",
@@ -82,14 +79,14 @@
},
"scope": {
"all": "所有节点",
"selected": "指定节点"
"selected": "已选节点"
}
},
"status": {
"status": "报告所有节点状态",
"statusNodes": "报告__number__个节点状态",
"status": "状态 (所有)",
"statusNodes": "状态显示 (__number__)",
"label": {
"source": "报告状态范围",
"source": "状态报告来自",
"node": "节点",
"type": "类型",
"selectAll": "全选",
@@ -98,7 +95,7 @@
},
"scope": {
"all": "所有节点",
"selected": "指定节点"
"selected": "已选节点"
}
},
"debug": {
@@ -107,11 +104,7 @@
"msgobj": "完整信息",
"to": "目标",
"debtab": "调试窗口",
"tabcon": "调试窗口及Console",
"toSidebar": "调试窗口",
"toConsole": "Console",
"toStatus": "节点状态 (32位字符)",
"severity": "级别",
"tabcon": "调试窗口及终端控制台",
"notification": {
"activated": "成功激活: __label__",
"deactivated": "成功取消: __label__"
@@ -121,21 +114,21 @@
"name": "名称",
"filterAll": "所有节点",
"filterSelected": "已选节点",
"filterCurrent": "前流程",
"filterCurrent": "前流程",
"debugNodes": "调试节点",
"clearLog": "清日志",
"clearLog": "清日志",
"openWindow": "在新窗口打开"
},
"messageMenu": {
"collapseAll": "折叠所有路径",
"clearPinned": "清已固定路径",
"clearPinned": "清已固定路径",
"filterNode": "过滤此节点",
"clearFilter": "清空过滤条件"
"clearFilter": "清除已设过滤"
}
},
"link": {
"linkIn": "输入",
"linkOut": "输出",
"linkIn": "连接入口",
"linkOut": "连接出口",
"label": {
"event": "事件名称",
"node": "节点名称",
@@ -151,18 +144,16 @@
"upload": "上传",
"cert": "证书",
"key": "私钥",
"passphrase": "密码",
"ca": "CA证书",
"verify-server-cert":"验证服务器证书"
},
"placeholder": {
"cert":"证书路径 (PEM 格式)",
"key":"私路径 (PEM 格式)",
"ca":"CA证书路径 (PEM 格式)",
"passphrase":"私钥密码 (可选)"
"key":"私路径 (PEM 格式)",
"ca":"CA证书路径 (PEM 格式)"
},
"error": {
"missing-file": "未提供证书/密文件"
"missing-file": "证书/密文件提供"
}
},
"exec": {
@@ -178,10 +169,10 @@
"extraparams": "额外的输入参数"
},
"opt": {
"exec": "当命令完成时 - exec模式",
"spawn": "当命令进行时 - spawn模式"
"exec": "当命令任务完成时 - exec 模式",
"spawn": "当命令任务进行时 - spawn 模式"
},
"oldrc": "使用旧式输出 (兼容模式)"
"oldrc": "使用旧式输出模式 (传统模式)"
},
"function": {
"label": {
@@ -189,7 +180,7 @@
"outputs": "输出"
},
"error": {
"inputListener":"无法在函数中监听对'注入'事件",
"inputListener":"无法在函数里面加入对‘注入事件的监视",
"non-message-returned":"函数节点尝试返回类型为 __type__ 的信息"
},
"tip": "可从信息页面查看更多关于如何编写函数的帮助"
@@ -203,8 +194,7 @@
"output": "输出为",
"mustache": "Mustache 模版",
"plain": "纯文本",
"json": "JSON",
"yaml": "YAML",
"json": "解析JSON",
"none": "无"
},
"templatevalue": "This is the payload: {{payload}} !"
@@ -214,13 +204,13 @@
"for": "时长",
"delaymsg": "延迟每一条信息",
"delayfixed": "固定延迟时间",
"delayvarmsg": "允许msg.delay写延迟时长",
"delayvarmsg": "msg.delay写延迟时长",
"randomdelay": "随机延迟",
"limitrate": "限制信息速",
"limitrate": "信息速度限制",
"limitall": "所有信息",
"limittopic": "每一个msg.topic",
"fairqueue": "依次发送每一个topic",
"timedqueue": "发所有topic",
"limittopic": "每一个 msg.topic",
"fairqueue": "轮流发每一个主题",
"timedqueue": "发所有主题",
"milisecs": "毫秒",
"secs": "秒",
"sec": "秒",
@@ -228,10 +218,10 @@
"min": "分",
"hours": "小时",
"hour": "小时",
"days": "",
"day": "",
"days": "",
"day": "",
"between": "介于",
"and": "",
"and": "",
"rate": "速度",
"msgper": "信息 每",
"dropmsg": "不传输中间信息",
@@ -255,14 +245,14 @@
"singular": "小时"
},
"day": {
"plural" : "",
"singular": ""
"plural" : "",
"singular": ""
}
}
},
"error": {
"buffer": "缓冲超过 1000 条信息",
"buffer1": "缓冲超过 10000 条信息"
"buffer": "缓冲超过 1000 条信息",
"buffer1": "缓冲超过 10000 条信息"
}
},
"trigger": {
@@ -277,9 +267,9 @@
"latest": "最新信息对象",
"nothing": "无"
},
"wait-reset": "等待重置",
"wait-reset": "等待重置",
"wait-for": "等待",
"wait-loop": "周期性重发",
"wait-loop": "重发",
"duration": {
"ms": "毫秒",
"s": "秒",
@@ -289,11 +279,11 @@
"extend": " 如有新信息,延长延迟",
"label": {
"trigger": "触发",
"trigger-block": "发并阻止",
"trigger-loop": "周期性重发",
"trigger-block": "发并阻止",
"trigger-loop": "重发",
"reset": "重置触发节点条件 如果:",
"resetMessage":"msg.reset已设置",
"resetPayload":"msg.payload等于",
"resetMessage":"msg.reset 已设置",
"resetPayload":"msg.payload 等于",
"resetprompt": "可选填"
}
},
@@ -302,7 +292,7 @@
"title": "标题",
"body": "主体"
},
"tip": "提示: 主题内容可格式化为 <a href=\"https://help.github.com/articles/markdown-basics/\" target=\"_blank\">Github风格Markdown</a>"
"tip": "提示: 主题内容可以添加格式化为 <a href=\"https://help.github.com/articles/markdown-basics/\" target=\"_blank\">Github 风格 Markdown</a>"
},
"unknown": {
"label": {
@@ -317,24 +307,24 @@
"qos": "QoS",
"clientid": "客户端ID",
"port": "端口",
"keepalive": "Keepalive计时(秒)",
"keepalive": "存货定时器(秒)",
"cleansession": "使用新的会话",
"use-tls": "使用安全连接 (SSL/TLS)",
"tls-config":"TLS 设置",
"verify-server-cert":"验证服务器证书",
"compatmode": "使用旧式MQTT 3.1支持"
"compatmode": "使用旧式 MQTT 3.1 支持"
},
"tabs-label": {
"connection": "连接",
"security": "安全",
"will": "Will信息",
"birth": "Birth信息"
"will": "终结信息",
"birth": "初始信息"
},
"placeholder": {
"clientid": "留白则自动生成",
"clientid": "留空白将会自动生成",
"clientid-nonclean":"如非新会话必须设置客户端ID",
"will-topic": "留白将禁止Will信息",
"birth-topic": "留白将禁止Birth信息"
"will-topic": "留白将禁止终止信息",
"birth-topic": "留白将禁止初始信息"
},
"state": {
"connected": "已连接到服务端: __broker__",
@@ -344,7 +334,7 @@
"retain": "保留",
"true": "是",
"false": "否",
"tip": "提示: 若希望通过msg属性对topic(信息), qos及retain(保留)进行设置, 则将上述项留白",
"tip": "提示: 如果你想用msg属性来设置主题qos 或者是否保存,请将这几个区域留空",
"errors": {
"not-defined": "主题未设置",
"missing-config": "未设置服务端",
@@ -354,13 +344,13 @@
},
"httpin": {
"label": {
"method": "请求方式",
"method": "方法",
"url": "URL",
"doc": "文档",
"return": "返回",
"upload": "接受文件上传?",
"status": "状态码",
"headers": "Header",
"headers": "头子段",
"other": "其他"
},
"setby": "- 用 msg.method 设定 -",
@@ -368,21 +358,21 @@
"use-tls": "使用安全连接 (SSL/TLS) ",
"tls-config":"TLS 设置",
"utf8": "UTF-8 字符串",
"binary": "二进制数据",
"json": "JSON对象",
"binary": "二进制缓冲模块",
"json": "解析JSON对象",
"tip": {
"in": "相对URL",
"res": "发送到此节点的消息<b>必须</b>来自<i>http input</i>节点",
"res": "发送到此节点的消息<b>必须</b>来自 <i>http input</i> 节点",
"req": "提示如果JSON解析失败则获取的字符串将按原样返回."
},
"httpreq": "http 请求",
"errors": {
"not-created": "当httpNodeRoot为否时无法创建http-in节点",
"not-created": "当httpNodeRoot为否时无法创建 http-in 节点",
"missing-path": "无路径",
"no-response": "无响应对象",
"json-error": "JSON 解析错误",
"no-url": "未设定 URL",
"deprecated-call":"__method__方法已弃用",
"deprecated-call":"__method__ 方法已弃用",
"invalid-transport":"非HTTP传输请求"
},
"status": {
@@ -397,14 +387,13 @@
},
"listenon": "监听",
"connectto": "连接",
"sendrec": "发送/接受",
"payload": "有效载荷",
"message": "完整信息",
"payload": "发送/接受 有效载荷",
"message": "发送/接受 完整信息",
"tip": {
"path1": "默认情况下,<code>payload</code>将包含要发送或从Websocket接收的数据。侦听器可以配置为以JSON格式的字符串发送或接收整个消息对象.",
"path1": "默认情况下,<code> payload </code>将包含要发送或从Websocket接收的数据。侦听器可以配置为以JSON格式的字符串发送或接收整个消息对象.",
"path2": "这条路径将相对于 ",
"url1": "URL 应该使用ws:&#47;&#47;或者wss:&#47;&#47;方案并指向现有的websocket侦听器.",
"url2": "默认情况下,<code>payload</code> 将包含要发送或从Websocket接收的数据。可以将客户端配置为以JSON格式的字符串发送或接收整个消息对象."
"url1": "URL 应该使用 ws:&#47;&#47; 或者 wss:&#47;&#47; 方案并指向现有的websocket侦听器.",
"url2": "默认情况下,<code> payload </code>将包含要发送或从Websocket接收的数据。可以将客户端配置为以JSON格式的字符串发送或接收整个消息对象."
},
"errors": {
"connect-error": "ws连接发生了错误: ",
@@ -414,8 +403,8 @@
},
"watch": {
"label": {
"files": "文件",
"recursive": "递归所有子文件夹"
"files": "文件(s)",
"recursive": "递归查看文件夹"
},
"placeholder": {
"files": "逗号分开文件或文件夹"
@@ -427,8 +416,8 @@
"type": "类型",
"output": "输出",
"port": "端口",
"host": "主机地址",
"payload": "有效载荷",
"host": "主服务器",
"payload": "有效载荷(s)",
"delimited": "分隔符号",
"close-connection": "是否在成功发送每条信息后断开连接?",
"decode-base64": "用 Base64 解码信息?",
@@ -440,19 +429,19 @@
"type": {
"listen": "监听",
"connect": "连接",
"reply": "响应 TCP"
"reply": "回应到 TCP"
},
"output": {
"stream": "字串流",
"single": "单一",
"buffer": "Buffer",
"buffer": "缓冲模块",
"string": "字符串",
"base64": "Base64 字符串"
},
"return": {
"timeout": "定时间后",
"character": "当收到某个字符",
"number": "指定字符",
"timeout": "在固定时间超时后",
"character": "当收到某个字符",
"number": "固定数目的字符",
"never": "永不 - 保持连接",
"immed": "马上 - 不需要等待回复"
},
@@ -463,8 +452,8 @@
"stopped-listening": "已停止监听端口",
"connection-from": "连接来自 __host__:__port__",
"connection-closed": "连接已关闭 __host__:__port__",
"connections": "__count__ 连接",
"connections_plural": "__count__ 连接"
"connections": "__count__ 连接",
"connections_plural": "__count__ 连接"
},
"errors": {
@@ -474,7 +463,7 @@
"error": "错误: __error__",
"socket-error": "套接字连接错误来自 __host__:__port__",
"no-host": "主机地址或端口未设定",
"no-host": "主服务器和/或者端口未设定",
"connect-timeout": "连接超时",
"connect-fail": "连接失败"
}
@@ -487,23 +476,23 @@
"output": "输出",
"group": "组",
"interface": "本地IP",
"interfaceprompt": "(可选)本地 IP 绑定到",
"interfaceprompt": "(可选)本地 IP 绑定到",
"send": "发送一个",
"toport": "到端口",
"address": "地址",
"decode-base64": "是否解码Base64编码的信息?"
"decode-base64": "是否解码编码为Base64的信息?"
},
"placeholder": {
"interface": "可选eth0的IP地址",
"address": "目标IP地址"
"interface": "(可选eth0 的 ip 地址",
"address": "目的地 ip 地址"
},
"udpmsgs": "udp信息",
"udpmsgs": "udp 信息",
"mcmsgs": "组播信息",
"udpmsg": "udp信息",
"udpmsg": "udp 信息",
"bcmsg": "广播信息",
"mcmsg": "组播信息",
"output": {
"buffer": "Buffer",
"buffer": "缓冲模块",
"string": "字符串",
"base64": "Base64编码字符串"
},
@@ -514,8 +503,8 @@
},
"tip": {
"in": "提示:确保您的防火墙将允许数据进入",
"out": "提示:如果要使用<code>msg.ip</code>和<code>msg.port</code>设置,请将地址和端口留空",
"port": "在使用端口: "
"out": "提示:如果要使用<code> msg.ip </code>和<code> msg.port </code>设置,请将地址和端口留空",
"port": "端口已在使用: "
},
"status": {
"listener-at": "udp 监听器正在监听 __host__:__port__",
@@ -525,79 +514,72 @@
"mc-ready": "udp 组播已准备好: __outport__ -> __host__:__port__",
"bc-ready": "udp 广播已准备好: __outport__ -> __host__:__port__",
"ready": "udp 已准备好: __outport__ -> __host__:__port__",
"ready-nolocal": "udp 已准备好: __host__:__port__",
"re-use": "udp 重用套接字: __outport__ -> __host__:__port__"
"ready-nolocal": "udp 已准备好: __host__:__port__"
},
"errors": {
"access-error": "UDP 访问错误, 你可能需要root权限才能接入1024以下的端口",
"error": "错误: __error__",
"bad-mcaddress": "无效的组播地址",
"interface": "必须是指定接口的IP地址",
"ip-notset": "udp: IP地址未设定",
"interface": "必须是需要接口的 ip 地址",
"ip-notset": "udp: ip 地址未设定",
"port-notset": "udp: 端口未设定",
"port-invalid": "udp: 无效端口号码",
"alreadyused": "udp: 端口已被占用"
"alreadyused": "udp: 端口已经在使用"
}
},
"switch": {
"label": {
"property": "属性",
"rule": "规",
"repair" : "重建信息队列"
"rule": "规"
},
"and": "",
"and": "",
"checkall": "全选所有规则",
"stopfirst": "接受第一条匹配信息后停止",
"ignorecase": "忽大小写",
"ignorecase": "忽大小写",
"rules": {
"btwn":"在之间",
"cont":"包含",
"regex":"匹配正则表达式",
"true":"为真",
"false":"为假",
"null":"为空",
"nnull":"非空",
"head":"head",
"tail":"tail",
"index":"index between",
"exp":"JSONata表达式",
"null":"为空",
"nnull":"非空",
"else":"除此以外"
},
"errors": {
"invalid-expr": "无效JSONata表达: __error__",
"too-many" : "Switch节点中有太多待定信息"
"invalid-expr": "无效 JSONata 表达: __error__"
}
},
"change": {
"label": {
"rules": "规",
"rule": "规",
"rules": "规",
"rule": "规",
"set": "设定 __property__",
"change": "改 __property__",
"change": "改 __property__",
"delete": "删除 __property__",
"move": "移动 __property__",
"changeCount": "改: __count__条规矩",
"regex": "使用正则表达式"
"changeCount": "改: __count__ 条规矩",
"regex": "用正则表达式"
},
"action": {
"set": "设定",
"change": "改",
"change": "改",
"delete": "删除",
"move": "转移",
"to": "到",
"search": "搜索",
"replace": "替代为"
"replace": "更改为"
},
"errors": {
"invalid-from": "无效的'from'属性: __error__",
"invalid-json": "无效的'to'JSON 属性",
"invalid-expr": "无效JSONata表达式: __error__"
"invalid-from": "无效来源 from 属性: __error__",
"invalid-json": "无效 to 属性",
"invalid-expr": "无效 JSONata 表示: __error__"
}
},
"range": {
"label": {
"action": "操作",
"inputrange": "映射输入数据",
"action": "行为作用",
"inputrange": "映射输入数据范围",
"resultrange": "至目标范围",
"from": "从",
"to": "到",
@@ -609,28 +591,26 @@
"maxout": "e.g. 255"
},
"scale": {
"payload": "按比例msg.payload",
"payload": "按比例 msg.payload",
"limit": "按比例并设定界限至目标范围",
"wrap": "按比例并包含在目标范围内"
},
"tip": "提示: 此节点仅对数字有效",
"errors": {
"notnumber": "不是一个数"
"notnumber": "不是一个数"
}
},
"csv": {
"label": {
"columns": "列",
"separator": "分隔符",
"c2o": "CSV至对象",
"o2c": "对象至CSV",
"separator": "分隔符",
"c2o": "CSV 至对象选项",
"o2c": "对象至 to CSV 选项",
"input": "输入",
"skip-s": "忽略前",
"skip-e": "行",
"firstrow": "第一行包含列名",
"output": "输出",
"includerow": "包含列名行",
"newline": "换行符"
"newline": "新的一行"
},
"placeholder": {
"columns": "用逗号分割列名"
@@ -645,8 +625,8 @@
"other": "其他..."
},
"output": {
"row": "每行一条信息",
"array": "一条信息 [数组]"
"row": "每行包含一条信息",
"array": "一条单独信息 [数组]"
},
"newline": {
"linux": "Linux (\\n)",
@@ -654,8 +634,8 @@
"windows": "Windows (\\r\\n)"
},
"errors": {
"csv_js": "此节点仅处理CSV字符串或JS对象",
"obj_csv": "对象->CSV转换未设定列模版"
"csv_js": "此节点仅处理 CSV 字符串或 js 对象",
"obj_csv": "对象 -> CSV 转换未设定列模版"
}
},
"html": {
@@ -664,13 +644,13 @@
"output": "输出"
},
"output": {
"html": "选定元素的html内容",
"html": "选定元素的 html 内容",
"text": "选定元素的纯文本内容",
"attr": "包含选定元素的所有属性对象"
"attr": "选定元素的所有属性对象"
},
"format": {
"single": "一条信息 [数组]",
"multi": "多条信息,每一个元素"
"single": "由一个单独信息包含一个数组",
"multi": "多条信息,每一条包含一个元素"
}
},
"json": {
@@ -680,15 +660,8 @@
"dropped-error": "转换有效负载失败"
},
"label": {
"o2j": "对象至JSON",
"pretty": "格式化JSON字符串",
"action": "操作",
"property": "属性",
"actions": {
"toggle": "JSON字符串与对象互转",
"str":"总是转为JSON字符串",
"obj":"总是转为JS对象"
}
"o2j": "对象至 JSON 选项",
"pretty": "格式化 JSON 字符串"
}
},
"yaml": {
@@ -714,14 +687,14 @@
"gpiopin": "GPIO",
"selectpin": "选择引脚",
"resistor": "电阻?",
"readinitial": "在部署/重时读取引脚的初始状态?",
"readinitial": "在部署/重新启动时读取引脚的初始状态?",
"type": "类型",
"initpin": "初始化引脚状态?",
"debounce": "去抖动",
"freq": "频率",
"button": "按钮",
"pimouse": "Pi鼠标",
"pikeyboard": "Pi键盘",
"pimouse": "Pi 鼠标",
"pikeyboard": "Pi 键盘",
"left": "左",
"right": "右",
"middle": "中"
@@ -732,21 +705,21 @@
"pulldown": "下拉电阻"
},
"digout": "数字输出",
"pwmout": "PWM输出",
"pwmout": "PWM 输出",
"servo": "伺服输出",
"initpin0": "初始引脚电平 - 低(0)",
"initpin1": "初始引脚电平 - 高(1)",
"initpin0": "初始引脚电平 - 低 (0)",
"initpin1": "初始引脚电平 - 高 (1)",
"left": "左",
"right": "右",
"middle": "中",
"any": "任何",
"pinname": "引脚",
"alreadyuse": "已被使用",
"alreadyset": "已被设为",
"alreadyuse": "已经在用",
"alreadyset": "已经设定为",
"tip": {
"pin": "<b>在使用引脚</b>: ",
"in": "提示: 仅接受数字输入 - 输出必须为0或1.",
"dig": "提示: 如用数字输出 - 输入必须为0或1.",
"pin": "<b>引脚在使用</b>: ",
"in": "提示: 仅接受数字输入 - 输出必须为 0 或 1.",
"dig": "提示: 如用数字输出 - 输入必须为 0 或 1.",
"pwm": "提示: 如用PWM输出 - 输入必须为0至100之间; 如用高频率可能会比预期占用更多CPU资源.",
"ser": "<b>提示</b>: 如用伺服输出 - 输入必须为0至100之间. 50为中间值."
},
@@ -755,7 +728,7 @@
"input": "输入",
"pullup": "含有上拉电阻的输入",
"pulldown": "含有下拉电阻的输入",
"pwmout": "PWM输出",
"pwmout": "PWM 输出",
"servo": "伺服输出"
},
"status": {
@@ -767,27 +740,27 @@
"ignorenode": "忽略树莓派的特定节点",
"version": "版本命令失败",
"sawpitype": "查看Pi类型",
"libnotfound": "找不到树莓派RPi.GPIOpython库",
"alreadyset": "GPIO引脚 __pin__ 已经被设定为类型: __type__",
"invalidpin": "无效GPIO引脚",
"libnotfound": "找不到树莓派 RPi.GPIO python库",
"alreadyset": "GPIO 引脚 __pin__ 已经被设定为类型: __type__",
"invalidpin": "无效 GPIO 引脚",
"invalidinput": "无效输入",
"needtobeexecutable": "__command__为可运行命令",
"mustbeexecutable": "nrgpio为可运行",
"commandnotfound": "nrgpio命令不存在",
"commandnotexecutable": "nrgpio命令不可运行",
"needtobeexecutable": "__command__ 需要为可运行命令",
"mustbeexecutable": "nrgpio 需要为可运行",
"commandnotfound": "nrgpio 命令不存在",
"commandnotexecutable": "nrgpio 命令无法运行",
"error": "错误: __error__",
"pythoncommandnotfound": "nrpgio python命令未处于运行状态"
"pythoncommandnotfound": "nrpgio python 命令不运行"
}
},
"tail": {
"label": {
"filename": "文件名",
"type": "文件类型",
"splitlines": "以\\n来拆分行?"
"splitlines": "拆分线 \\n?"
},
"action": {
"text": "文本 - 返回字符串",
"binary": "二进制 - 返回Buffer"
"binary": "二进制 - 返回缓冲区"
},
"errors": {
"windowsnotsupport": "Windows目前不支持."
@@ -797,7 +770,7 @@
"label": {
"filename": "文件名",
"action": "行为",
"addnewline": "向每个有效载荷添加换行符(\\n?",
"addnewline": "向每个有效载荷添加换行符(\\ n?",
"createdir": "创建目录(如果不存在)?",
"outputas": "输出",
"breakchunks": "分拆成块",
@@ -808,14 +781,14 @@
},
"action": {
"append": "追加至文件",
"overwrite": "写文件",
"overwrite": "写文件",
"delete": "删除文件"
},
"output": {
"utf8": "一utf8字符串",
"buffer": "一个Buffer对象",
"utf8": "一条单独 utf8 字符串",
"buffer": "一条单独缓冲区对象",
"lines": "每行一条信息",
"stream": "一个Buffer流"
"stream": "缓冲区流"
},
"status": {
"wrotefile": "写入至文件: __file__",
@@ -833,99 +806,41 @@
"tip": "提示: 文件名应该是绝对路径否则它将相对于Node-RED进程的工作目录。"
},
"split": {
"intro":"基于以下类型拆分<code>msg.payload</code>:",
"intro":"分<code>msg.payload</code> 基于类型:",
"object":"<b>对象</b>",
"objectSend":"每个键值对作为单个消息发送",
"strBuff":"<b>字符串</b> / <b>Buffer</b>",
"objectSend":"发送每个键/值对的消息",
"strBuff":"<b>字符串</b> / <b>缓冲区</b>",
"array":"<b>数组</b>",
"splitUsing":"拆分使用",
"splitLength":"固定长度",
"stream":"为消息流处理",
"stream":"处理为消息流",
"addname":" 复制键到 "
},
"join":{
"mode":{
"mode":"模式",
"auto":"自动",
"merge":"合并序列",
"reduce":"缩减序列",
"custom":"手动"
},
"combine":"合并每个",
"create":"输出",
"combine":"结合每一个",
"create":"创建输出",
"type":{
"string":"字符串",
"array":"数组",
"buffer":"Buffer",
"object":"键值对象",
"buffer":"缓冲区",
"object":"键/值对象",
"merged":"合并对象"
},
"using":"使用值",
"key":"作键",
"using":"使用值",
"key":"作键",
"joinedUsing":"合并符号",
"send":"发送信息:",
"afterCount":"达到一定数的信息时",
"count":"数",
"afterCount":"达到一定数的信息部件时",
"count":"数",
"subsequent":"和每个后续的消息",
"afterTimeout":"第一条消息的若干时间后",
"afterTimeout":"第一条消息的超时后",
"seconds":"秒",
"complete":"在收到存在<code>msg.complete</code>的消息后",
"tip":"此模式假定此节点与<i>split</i>相连, 或者接收到的消息有正确配置的<code>msg.parts</code>属性.",
"too-many" : "join节点中有太多待定信息",
"merge": {
"topics-label":"合并主题",
"topics":"主题",
"topic" : "主题",
"on-change":"当收到一个新主题时发送已合并信息"
},
"reduce": {
"exp": "Reduce表达式",
"exp-value": "exp",
"init": "初始值",
"right": "反向求值(从后往前)",
"fixup": "Fix-up exp"
},
"errors": {
"invalid-expr": "无效的JSONata表达式: __error__"
}
},
"sort" : {
"target" : "排序属性",
"seq" : "信息队列",
"key" : "键值",
"elem" : "元素值",
"order" : "顺序",
"ascending" : "升序",
"descending" : "降序",
"as-number" : "作为数值",
"invalid-exp" : "sort节点中存在无效的JSONata表达式",
"too-many" : "sort节点中有太多待定信息",
"clear" : "清空sort节点中的待定信息"
},
"batch" : {
"mode": {
"label" : "模式",
"num-msgs" : "按指定数量分组",
"interval" : "按时间间隔分组",
"concat" : "按主题分组"
},
"count": {
"label" : "分组数量",
"overlap" : "队末队首重叠数量",
"count" : "数量",
"invalid" : "无效的分组数量或重叠数量"
},
"interval": {
"label" : "时间间隔",
"seconds" : "秒",
"empty" : "无数据到达时发送空信息"
},
"concat": {
"topics-label": "主题",
"topic" : "主题"
},
"too-many" : "batch节点中有太多待定信息",
"unexpected" : "未知模式",
"no-parts" : "信息中没有parts属性"
"complete":"在使用<code> msg.complete </ code>属性设置的消息后",
"tip":"此模式假定此节点与 <i>split</i> 或者接收到的消息将具有正确配置的 <code>msg.parts</code> 属性."
}
}

View File

@@ -65,7 +65,7 @@
that are part of a sequence.</p>
<p>The <b>recreate message sequences</b> option can be enabled to generate new message sequences
for each rule that matches. In this mode, the node will buffer the entire incoming
sequence before sending the new sequences on. The runtime setting <code>nodeMessageBufferMaxLength</code>
sequence before sending the new sequences on. The runtime setting `nodeMessageBufferMaxLength`
can be used to limit how many messages nodes will buffer.</p>
</script>
@@ -85,7 +85,6 @@
{v:"false",t:"switch.rules.false",kind:'V'},
{v:"null",t:"switch.rules.null",kind:'V'},
{v:"nnull",t:"switch.rules.nnull",kind:'V'},
{v:"istype",t:"switch.rules.istype",kind:'V'},
{v:"head",t:"switch.rules.head",kind:'S'},
{v:"index",t:"switch.rules.index",kind:'S'},
{v:"tail",t:"switch.rules.tail",kind:'S'},
@@ -141,7 +140,7 @@
},
icon: "switch.png",
label: function() {
return this.name||this._("switch.switch");
return this.name||"switch";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
@@ -161,7 +160,6 @@
var selectField = rule.find("select");
var type = selectField.val()||"";
var valueField = rule.find(".node-input-rule-value");
var typeField = rule.find(".node-input-rule-type-value");
var numField = rule.find(".node-input-rule-num-value");
var expField = rule.find(".node-input-rule-exp-value");
var btwnField1 = rule.find(".node-input-rule-btwn-value");
@@ -182,8 +180,6 @@
numField.typedInput("width",(newWidth-selectWidth-70));
} else if (type === "jsonata_exp") {
expField.typedInput("width",(newWidth-selectWidth-70));
} else if (type === "istype") {
typeField.typedInput("width",(newWidth-selectWidth-70));
} else {
if (type === "true" || type === "false" || type === "null" || type === "nnull" || type === "else") {
// valueField.hide();
@@ -203,7 +199,7 @@
rule.t = 'eq';
}
if (!opt.hasOwnProperty('i')) {
opt._i = Math.floor((0x99999-0x10000)*Math.random()).toString();
opt._i = Math.floor((0x99999-0x10000)*Math.random()).toString(16);
}
container.css({
overflow: 'hidden',
@@ -236,18 +232,6 @@
var btwnValueField = $('<input/>',{class:"node-input-rule-btwn-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata',previousValueType]});
var btwnAndLabel = $('<span/>',{class:"node-input-rule-btwn-label"}).text(" "+andLabel+" ").appendTo(row3);
var btwnValue2Field = $('<input/>',{class:"node-input-rule-btwn-value2",type:"text",style:"margin-left:2px;"}).appendTo(row3).typedInput({default:'num',types:['msg','flow','global','str','num','jsonata',previousValueType]});
var typeValueField = $('<input/>',{class:"node-input-rule-type-value",type:"text",style:"margin-left: 5px;"}).appendTo(row)
.typedInput({default:'string',types:[
{value:"string",label:"string",hasValue:false},
{value:"number",label:"number",hasValue:false},
{value:"boolean",label:"boolean",hasValue:false},
{value:"array",label:"array",hasValue:false},
{value:"buffer",label:"buffer",hasValue:false},
{value:"object",label:"object",hasValue:false},
{value:"json",label:"JSON string",hasValue:false},
{value:"undefined",label:"undefined",hasValue:false},
{value:"null",label:"null",hasValue:false}
]});
var finalspan = $('<span/>',{style:"float: right;margin-top: 6px;"}).appendTo(row);
finalspan.append(' &#8594; <span class="node-input-rule-index">'+(i+1)+'</span> ');
var caseSensitive = $('<input/>',{id:"node-input-rule-case-"+i,class:"node-input-rule-case",type:"checkbox",style:"width:auto;vertical-align:top"}).appendTo(row2);
@@ -259,39 +243,26 @@
valueField.typedInput('hide');
expValueField.typedInput('hide');
numValueField.typedInput('hide');
typeValueField.typedInput('hide');
btwnValueField.typedInput('show');
} else if ((type === "head") || (type === "tail")) {
btwnValueField.typedInput('hide');
btwnValue2Field.typedInput('hide');
expValueField.typedInput('hide');
numValueField.typedInput('show');
typeValueField.typedInput('hide');
valueField.typedInput('hide');
} else if (type === "jsonata_exp") {
btwnValueField.typedInput('hide');
btwnValue2Field.typedInput('hide');
expValueField.typedInput('show');
numValueField.typedInput('hide');
typeValueField.typedInput('hide');
valueField.typedInput('hide');
} else {
btwnValueField.typedInput('hide');
expValueField.typedInput('hide');
numValueField.typedInput('hide');
typeValueField.typedInput('hide');
valueField.typedInput('hide');
if (type === "true" || type === "false" || type === "null" || type === "nnull" || type === "else") {
valueField.typedInput('hide');
typeValueField.typedInput('hide');
}
else
if (type === "istype") {
valueField.typedInput('hide');
typeValueField.typedInput('show');
}
else {
typeValueField.typedInput('hide');
} else {
valueField.typedInput('show');
}
}
@@ -316,9 +287,6 @@
} else if ((rule.t === "head") || (rule.t === "tail")) {
numValueField.typedInput('value',rule.v);
numValueField.typedInput('type',rule.vt||'num');
} else if (rule.t === "istype") {
typeValueField.typedInput('value',rule.vt);
typeValueField.typedInput('type',rule.vt);
} else if (rule.t === "jsonata_exp") {
expValueField.typedInput('value',rule.v);
expValueField.typedInput('type',rule.vt||'jsonata');
@@ -391,9 +359,6 @@
} else if ((type === "head") || (type === "tail")) {
r.v = rule.find(".node-input-rule-num-value").typedInput('value');
r.vt = rule.find(".node-input-rule-num-value").typedInput('type');
} else if (type === "istype") {
r.v = rule.find(".node-input-rule-type-value").typedInput('type');
r.vt = rule.find(".node-input-rule-type-value").typedInput('type');
} else if (type === "jsonata_exp") {
r.v = rule.find(".node-input-rule-exp-value").typedInput('value');
r.vt = rule.find(".node-input-rule-exp-value").typedInput('type');

View File

@@ -31,16 +31,6 @@ module.exports = function(RED) {
'false': function(a) { return a === false; },
'null': function(a) { return (typeof a == "undefined" || a === null); },
'nnull': function(a) { return (typeof a != "undefined" && a !== null); },
'istype': function(a, b) {
if (b === "array") { return Array.isArray(a); }
else if (b === "buffer") { return Buffer.isBuffer(a); }
else if (b === "json") {
try { JSON.parse(a); return true; } // or maybe ??? a !== null; }
catch(e) { return false;}
}
else if (b === "null") { return a === null; }
else { return typeof a === b && !Array.isArray(a) && !Buffer.isBuffer(a) && a !== null; }
},
'head': function(a, b, c, d, parts) {
var count = Number(b);
return (parts.index < count);
@@ -302,10 +292,6 @@ module.exports = function(RED) {
node.error(RED._("switch.errors.invalid-expr",{error:err.message}));
return;
}
} else if (rule.vt === 'json') {
v1 = "json";
} else if (rule.vt === 'null') {
v1 = "null";
} else {
try {
v1 = RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg);

View File

@@ -76,8 +76,7 @@
outputs: 1,
icon: "range.png",
label: function() {
if (this.minout !== "" && this.maxout !== "") { return this.name||this.minout + " - " + this.maxout; }
else { return this.name||this._("range.range"); }
return this.name || "range";
},
labelStyle: function() {
return this.name ? "node_label_italic" : "";

View File

@@ -112,7 +112,7 @@
outputs:1,
icon: "split.png",
label: function() {
return this.name||this._("split.split");
return this.name||"split";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
@@ -337,7 +337,7 @@
</p>
<h4>Storing messages</h4>
<p>This node will buffer messages internally in order to work across sequences. The
runtime setting <code>nodeMessageBufferMaxLength</code> can be used to limit how many messages nodes
runtime setting `nodeMessageBufferMaxLength` can be used to limit how many messages nodes
will buffer.</p>
</script>
@@ -367,7 +367,7 @@
outputs:1,
icon: "join.png",
label: function() {
return this.name||this._("join.join");
return this.name||"join";
},
labelStyle: function() {
return this.name?"node_label_italic":"";

View File

@@ -103,7 +103,7 @@
outputs:1,
icon: "sort.png",
label: function() {
return this.name||this._("sort.sort");
return this.name || "sort";
},
labelStyle: function() {
return this.name ? "node_label_italic" : "";

View File

@@ -85,11 +85,12 @@
must have a <code>msg.topic</code> property and a <code>msg.parts</code> property
identifying its sequence. The node is configured with a list of <code>topic</code>
values to identify the order sequences are concatenated.
</dd>
</dd>
</dl>
<h4>Storing messages</h4>
<p>This node will buffer messages internally in order to work across sequences. The
runtime setting <code>nodeMessageBufferMaxLength</code> can be used to limit how many messages nodes
runtime setting `nodeMessageBufferMaxLength` can be used to limit how many messages nodes
will buffer.</p>
</script>
@@ -110,7 +111,7 @@
outputs:1,
icon: "batch.png",
label: function() {
return this.name||this._("batch.batch");;
return this.name || "batch";
},
labelStyle: function() {
return this.name ? "node_label_italic" : "";

View File

@@ -116,7 +116,7 @@ module.exports = function(RED) {
for (var topic of topics) {
remove_topic(pending, topic);
}
send_msgs(node, msgs, true);
send_msgs(node, msgs, false);
node.pending_count -= msgs.length;
}

View File

@@ -2,7 +2,7 @@
<script type="text/x-red" data-template-name="html">
<div class="form-row">
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
<input type="text" id="node-input-property" style="width:70%">
<input type="text" id="node-input-property" style="width:70%;"/>
</div>
<div class="form-row">
<label for="node-input-tag"><i class="fa fa-filter"></i> <span data-i18n="html.label.select"></span></label>
@@ -24,10 +24,6 @@
<option value="multi" data-i18n="html.format.multi"></option>
</select>
</div>
<div class="form-row">
<label for="node-input-outproperty">&nbsp;</label>
<span data-i18n="html.label.in" style="padding-left:8px; padding-right:2px; vertical-align:-1px;"></span> <input type="text" id="node-input-outproperty" style="width:64%">
</div>
<br/>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
@@ -62,8 +58,6 @@
color:"#DEBD5C",
defaults: {
name: {value:""},
property: {value:"payload"},
outproperty: {value:"payload"},
tag: {value:""},
ret: {value:"html"},
as: {value:"single"}
@@ -76,10 +70,6 @@
},
labelStyle: function() {
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
$("#node-input-property").typedInput({default:'msg',types:['msg']});
$("#node-input-outproperty").typedInput({default:'msg',types:['msg']});
}
});
</script>

View File

@@ -21,7 +21,6 @@ module.exports = function(RED) {
function CheerioNode(n) {
RED.nodes.createNode(this,n);
this.property = n.property||"payload";
this.outproperty = n.outproperty||this.property||"payload";
this.tag = n.tag;
this.ret = n.ret || "html";
this.as = n.as || "single";
@@ -49,7 +48,7 @@ module.exports = function(RED) {
/* istanbul ignore else */
if (pay2) {
var new_msg = RED.util.cloneMessage(msg);
RED.util.setMessageProperty(new_msg,node.outproperty,pay2);
RED.util.setMessageProperty(new_msg,node.property,pay2);
new_msg.parts = {
id: msg._msgid,
index: index,
@@ -69,7 +68,7 @@ module.exports = function(RED) {
index++;
});
if (node.as === "single") { // Always return an array - even if blank
RED.util.setMessageProperty(msg,node.outproperty,pay);
RED.util.setMessageProperty(msg,node.property,pay);
node.send(msg);
}
}

View File

@@ -46,7 +46,7 @@
outputs:1,
icon: "file.png",
label: function() {
return this.name||this.filename||this._("tail.tail");
return this.name||this.filename||"tail";
},
labelStyle: function() {
return this.name?"node_label_italic":"";

View File

@@ -1,117 +1,114 @@
{
"name": "node-red",
"version": "0.18.5",
"description": "A visual tool for wiring the Internet of Things",
"homepage": "http://nodered.org",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/node-red/node-red.git"
},
"main": "red/red.js",
"scripts": {
"start": "node red.js",
"test": "grunt",
"build": "grunt build"
},
"bin": {
"node-red": "./red.js",
"node-red-pi": "bin/node-red-pi"
},
"contributors": [
{
"name": "Nick O'Leary"
"name": "node-red",
"version": "0.18.1",
"description": "A visual tool for wiring the Internet of Things",
"homepage": "http://nodered.org",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/node-red/node-red.git"
},
{
"name": "Dave Conway-Jones"
"main": "red/red.js",
"scripts": {
"start": "node red.js",
"test": "grunt",
"build": "grunt build"
},
"bin": {
"node-red": "./red.js",
"node-red-pi": "bin/node-red-pi"
},
"contributors": [
{
"name": "Nick O'Leary"
},
{
"name": "Dave Conway-Jones"
}
],
"keywords": [
"editor",
"messaging",
"iot",
"flow"
],
"dependencies": {
"basic-auth": "2.0.0",
"bcryptjs": "2.4.3",
"body-parser": "1.18.2",
"cheerio": "0.22.0",
"clone": "2.1.1",
"cookie": "0.3.1",
"cookie-parser": "1.4.3",
"cors": "2.8.4",
"cron": "1.3.0",
"express": "4.16.2",
"express-session": "1.15.6",
"follow-redirects": "1.3.0",
"fs-extra": "5.0.0",
"fs.notify": "0.0.4",
"hash-sum": "1.0.2",
"i18next": "1.10.6",
"is-utf8": "0.2.1",
"js-yaml": "3.10.0",
"json-stringify-safe": "5.0.1",
"jsonata": "1.5.0",
"media-typer": "0.3.0",
"memorystore": "1.6.0",
"mqtt": "2.15.1",
"multer": "1.3.0",
"mustache": "2.3.0",
"node-red-node-email": "0.1.*",
"node-red-node-feedparser": "0.1.*",
"node-red-node-rbe": "0.1.*",
"node-red-node-twitter": "0.1.*",
"nopt": "4.0.1",
"oauth2orize": "1.11.0",
"on-headers": "1.0.1",
"passport": "0.4.0",
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
"raw-body": "2.3.2",
"semver": "5.4.1",
"sentiment": "2.1.0",
"uglify-js": "3.3.6",
"when": "3.7.8",
"ws": "1.1.5",
"xml2js": "0.4.19"
},
"optionalDependencies": {
"bcrypt": "~1.0.3"
},
"devDependencies": {
"chromedriver": "^2.33.2",
"grunt": "~1.0.1",
"grunt-chmod": "~1.1.1",
"grunt-cli": "~1.2.0",
"grunt-concurrent": "~2.3.1",
"grunt-contrib-clean": "~1.1.0",
"grunt-contrib-compress": "~1.4.0",
"grunt-contrib-concat": "~1.0.1",
"grunt-contrib-copy": "~1.0.0",
"grunt-contrib-jshint": "~1.1.0",
"grunt-contrib-uglify": "~3.3.0",
"grunt-contrib-watch": "~1.0.0",
"grunt-jsonlint": "~1.1.0",
"grunt-mocha-istanbul": "5.0.2",
"grunt-nodemon": "~0.4.2",
"grunt-sass": "~2.0.0",
"grunt-simple-mocha": "~0.4.1",
"grunt-webdriver": "^2.0.3",
"istanbul": "0.4.5",
"mocha": "~3.4.2",
"should": "^8.4.0",
"sinon": "1.17.7",
"supertest": "3.0.0",
"wdio-chromedriver-service": "^0.1.1",
"wdio-mocha-framework": "^0.5.11",
"wdio-spec-reporter": "^0.1.3",
"webdriverio": "^4.9.11"
},
"engines": {
"node": ">=4"
}
],
"keywords": [
"editor",
"messaging",
"iot",
"flow"
],
"dependencies": {
"basic-auth": "2.0.0",
"bcryptjs": "2.4.3",
"body-parser": "1.18.2",
"cheerio": "0.22.0",
"clone": "2.1.1",
"cookie": "0.3.1",
"cookie-parser": "1.4.3",
"cors": "2.8.4",
"cron": "1.3.0",
"express": "4.16.3",
"express-session": "1.15.6",
"follow-redirects": "1.4.1",
"fs-extra": "5.0.0",
"fs.notify": "0.0.4",
"hash-sum": "1.0.2",
"i18next": "1.10.6",
"is-utf8": "0.2.1",
"js-yaml": "3.11.0",
"json-stringify-safe": "5.0.1",
"jsonata": "1.5.3",
"media-typer": "0.3.0",
"memorystore": "1.6.0",
"mqtt": "2.17.0",
"multer": "1.3.0",
"mustache": "2.3.0",
"node-red-node-email": "0.1.*",
"node-red-node-feedparser": "0.1.*",
"node-red-node-rbe": "0.2.*",
"node-red-node-twitter": "0.1.*",
"nopt": "4.0.1",
"oauth2orize": "1.11.0",
"on-headers": "1.0.1",
"passport": "0.4.0",
"passport-http-bearer": "1.0.1",
"passport-oauth2-client-password": "0.1.2",
"raw-body": "2.3.3",
"semver": "5.5.0",
"sentiment": "2.1.0",
"uglify-js": "3.3.24",
"when": "3.7.8",
"ws": "1.1.5",
"xml2js": "0.4.19"
},
"optionalDependencies": {
"bcrypt": "~1.0.3"
},
"devDependencies": {
"chromedriver": "^2.33.2",
"grunt": "~1.0.1",
"grunt-chmod": "~1.1.1",
"grunt-cli": "~1.2.0",
"grunt-concurrent": "~2.3.1",
"grunt-contrib-clean": "~1.1.0",
"grunt-contrib-compress": "~1.4.0",
"grunt-contrib-concat": "~1.0.1",
"grunt-contrib-copy": "~1.0.0",
"grunt-contrib-jshint": "~1.1.0",
"grunt-contrib-uglify": "~3.3.0",
"grunt-contrib-watch": "~1.0.0",
"grunt-jsonlint": "~1.1.0",
"grunt-mocha-istanbul": "5.0.2",
"grunt-nodemon": "~0.4.2",
"grunt-sass": "~2.0.0",
"grunt-simple-mocha": "~0.4.1",
"grunt-webdriver": "^2.0.3",
"http-proxy": "^1.16.2",
"istanbul": "0.4.5",
"mocha": "^5.1.1",
"should": "^8.4.0",
"sinon": "1.17.7",
"stoppable": "^1.0.6",
"supertest": "3.0.0",
"wdio-chromedriver-service": "^0.1.1",
"wdio-mocha-framework": "^0.5.11",
"wdio-spec-reporter": "^0.1.3",
"webdriverio": "^4.9.11",
"node-red-node-test-helper": "^0.1.7"
},
"engines": {
"node": ">=4"
}
}

4
red.js
View File

@@ -192,7 +192,7 @@ try {
if (err.code == "unsupported_version") {
console.log("Unsupported version of node.js:",process.version);
console.log("Node-RED requires node.js v4 or later");
} else if (err.code == "not_built") {
} else if (err.code == "not_built") {
console.log("Node-RED has not been built. See README.md for details");
} else {
console.log("Failed to start server:");
@@ -276,7 +276,7 @@ function getListenPath() {
}
var listenPath = 'http'+(settings.https?'s':'')+'://'+
(settings.uiHost == '::'?'localhost':(settings.uiHost == '0.0.0.0'?'127.0.0.1':settings.uiHost))+
(settings.uiHost == '0.0.0.0'?'127.0.0.1':settings.uiHost)+
':'+port;
if (settings.httpAdminRoot !== false) {
listenPath += settings.httpAdminRoot;

View File

@@ -16,9 +16,11 @@
var log;
var redNodes;
var settings;
module.exports = {
init: function(runtime) {
settings = runtime.settings;
redNodes = runtime.nodes;
log = runtime.log;
},

Some files were not shown because too many files have changed in this diff Show More