Compare commits

...

47 Commits

Author SHA1 Message Date
Dave Conway-Jones
b60fd36c6e Fix CSV node to handle \n when outputting text fields
and add tests
2022-06-28 10:14:12 +01:00
Nick O'Leary
4467c0df31 Merge pull request #3714 from kazuhitoyokoi/master-fixdefaulticonbutton
Fix use default button for node icon
2022-06-27 20:36:05 +01:00
Kazuhito Yokoi
ab1e38dde8 Fix use default button for node icon 2022-06-27 23:56:24 +09:00
Nick O'Leary
dd0d1e700e Merge pull request #3669 from dschmidt/patch-1
Import default export if node is a transpiled es module
2022-06-27 14:31:43 +01:00
Nick O'Leary
51ebb2579f Merge pull request #3670 from node-red/join-reduce-keep-msg
Join node in reduce mode doesn't keep existing msg properties
2022-06-27 14:29:41 +01:00
Nick O'Leary
d1d3b805f6 Merge pull request #3690 from cow0w/env_evalulating_in_template
Add support for evalulating {{env.<var>}} within a template node
2022-06-27 14:28:17 +01:00
Nick O'Leary
a6e247326b Merge pull request #3698 from bonanitech/fix-select-box-alignment
Fix select boxes vertical alignment
2022-06-27 14:18:34 +01:00
Nick O'Leary
823b7e2989 Merge pull request #3704 from bonanitech/monaco-default-theme
Leave Monaco theme commented out by default
2022-06-27 14:16:49 +01:00
Nick O'Leary
5f40dc37a2 Merge pull request #3708 from Steve-Mcl/fix-undo-drop-still-dirty
Ensure workspace clean after undoing dropped node
2022-06-27 14:12:50 +01:00
Nick O'Leary
5e5c05f0c6 Merge pull request #3710 from Steve-Mcl/fix-config-node-text-underflow
Use solid colour as config node icon background to hide text overflow
2022-06-27 14:11:09 +01:00
Nick O'Leary
ab1340d213 Merge pull request #3711 from Steve-Mcl/quick-add-height
Increase quick-add height to reveal 2 most recent entries
2022-06-27 14:09:38 +01:00
Stephen McLaughlin
cc5a0a436c Merge pull request #3702 from node-red/default-monaco
Set default editor to monaco in absence of user preference
2022-06-27 09:43:07 +01:00
Steve-Mcl
125b37e98f increase quick-add height to reveal 2 most recent
fixes #3568
2022-06-26 12:16:39 +01:00
Steve-Mcl
f8ad75329d use $node-port-background as config node icon background
Makse sense since it contrasts the $node-port-label-color used for icon text
Also, only show pointer if node icon has count
2022-06-26 11:52:55 +01:00
Steve-Mcl
78327716a4 ensure workspace clean after undoing dropped node 2022-06-26 09:08:26 +01:00
Mauricio Bonani
5393fa81b9 Leave Monaco theme commented out by default 2022-06-25 20:27:32 -04:00
Nick O'Leary
d2e84925f7 Set default editor to monaco in absence of user preference 2022-06-22 21:43:25 +01:00
Mauricio Bonani
2ea10206fa Fix select box alignment 2022-06-21 11:43:02 -04:00
Nick O'Leary
1f5588b803 Merge pull request #3696 from node-red/right-click-menu-fix
Fix clicking on node in workspace to hide context menu
2022-06-21 09:04:55 +01:00
Nick O'Leary
202102ebf7 Fix clicking on node in workspace to hide context menu 2022-06-20 20:51:31 +01:00
Nick O'Leary
71714733ad Merge pull request #3688 from kazuhitoyokoi/master-addjpn
Add Japanese translations for v3.0-beta.3
2022-06-20 16:30:12 +01:00
Kazuhito Yokoi
ad0a08ea0e Add Japanese translations in action list for project feature 2022-06-20 00:44:20 +09:00
Kazuhito Yokoi
5e592427e9 Add Japanese translation in action list for junction 2022-06-19 01:56:59 +09:00
Kazuhito Yokoi
643541eebd Remove unnecessary spaces 2022-06-19 01:37:55 +09:00
Kazuhito Yokoi
13885493ac Update Japanese translations in welcome tour 2022-06-19 01:26:48 +09:00
Kazuhito Yokoi
75c9353cbd Fix keys to insert junction 2022-06-19 01:23:28 +09:00
cow0w
01d9affe61 Add support for evalulating {{env.<var>}} within a template node 2022-06-17 22:18:14 +03:00
Kazuhito Yokoi
3ad95bec3c Add Japanese translation for file nodes 2022-06-18 00:57:30 +09:00
Kazuhito Yokoi
418b3ee7d6 Fix Japanese translations to be same as others 2022-06-18 00:56:34 +09:00
Kazuhito Yokoi
0000f2a34d Support i18n in context menu 2022-06-18 00:51:05 +09:00
Nick O'Leary
fc5a5f1b73 Merge pull request #3687 from node-red/space-in-strings
Fix handling of spacebar inside JSON visual editor
2022-06-17 10:05:12 +01:00
Nick O'Leary
226ab406b2 Merge pull request #3686 from node-red/fix-menu-padding
Fix menu padding to handle both icons and submenus
2022-06-17 10:05:01 +01:00
Nick O'Leary
9eaf5d82b6 Merge pull request #3685 from node-red/quick-add-offset
Include scroll offset when positioning quick-add dialog
2022-06-16 23:31:38 +01:00
Nick O'Leary
e3d6d242ac Fix handling of spacebar inside JSON visual editor
Fixes #3682

The treeList keyboard handling was consuming the event - used
to select the item in the list.

The fix here adds a 'selectable' flag on the treeList that can
be used to disabled (=false) the keyboard selection of items.
2022-06-16 23:29:46 +01:00
Nick O'Leary
53184715bc Fix menu padding to handle both icons and submenus
Fixes #3683
2022-06-16 23:18:02 +01:00
Nick O'Leary
1844633ff1 Include scroll offset when positioning quick-add dialog
Fixes #3684
2022-06-16 22:57:23 +01:00
Nick O'Leary
7d7682b34e Merge pull request #3681 from node-red/30-release
3.0.0-beta.3 release
2022-06-16 17:23:01 +01:00
Nick O'Leary
83655a749c Update changelog 2022-06-16 17:01:11 +01:00
Nick O'Leary
b9444e8197 Merge pull request #3679 from node-red/update-deps
Update dependencies
2022-06-16 16:03:37 +01:00
Nick O'Leary
5ff70b2a36 Merge pull request #3680 from node-red/300-tour
Update tour for 3.0-beta.3
2022-06-16 16:03:18 +01:00
Nick O'Leary
4ed559af95 Update changelog and version for 3-beta.3 2022-06-16 15:44:51 +01:00
Nick O'Leary
ce529a9b9f Update module dependencies 2022-06-16 15:39:42 +01:00
Nick O'Leary
31e472145c Merge pull request #3678 from node-red/right-click-menu
Right click menu
2022-06-16 15:38:58 +01:00
Nick O'Leary
1664428429 Update tour for 3.0-beta.3 2022-06-16 15:37:07 +01:00
Nick O'Leary
1780cb9b91 Update dependencies 2022-06-16 14:47:11 +01:00
Dave Conway-Jones
6c0d6c5425 Join-reduce keep existing msg properties
see https://discourse.nodered.org/t/no-response-object-after-split-join/63919
2022-06-15 10:16:12 +01:00
Dominik Schmidt
326f346936 Import default export if node is a transpiled es module 2022-06-14 22:54:00 +02:00
39 changed files with 266 additions and 88 deletions

View File

@@ -1,3 +1,42 @@
#### 3.0.0-beta.3: Beta Release
Editor
- Add Right-Click content menu (#3678) @knolleary
- Fix disable junction (#3671) @HiroyasuNishiyama
- Add Japanese translations for v2.2.3 (#3672) @kazuhitoyokoi
- Reset mouse state when switching tabs (#3643) @knolleary
- Fix uncorrect fix of junction to subflow conversion (#3666) @HiroyasuNishiyama
- Fix undoing junction to subflow (#3653) @HiroyasuNishiyama
- Fix conversion of junction to subflow (#3652) @HiroyasuNishiyama
- Fix to include junction to exported nodes (#3650) @HiroyasuNishiyama
- Fix z-index value for shade to cover nodes in palette (#3649) @kazuhitoyokoi
- Fix to extend escaped subflow category characters (#3647) @HiroyasuNishiyama
- Fix to sanitize tab name (#3646) @HiroyasuNishiyama
- Fix selector placement (#3644) @bonanitech
- Add Japanese translations for v3.0-beta.2 (#3622) @kazuhitoyokoi
- Fix new folder menu of save to library dialog (#3633) @HiroyasuNishiyama
- Fix layer of palette node (#3638) @HiroyasuNishiyama
- Fix to place a node dragged from palette within the workspace (#3637) @HiroyasuNishiyama
- Fix typo in CSS (#3628) @bonanitech
- Use the correct variable for the gutter text color (#3615) @bonanitech
Runtime
- Support loading node modules from `nodesdir` (#3676) @Steve-Mcl
- fix buffer parse error message of evaluateNodeProperty (#3624) @HiroyasuNishiyama
Nodes
- File: Further simplify file node filename entry UX (v3) (#3677) @Steve-Mcl
- Function: Fix initial cursor position of init/finalize tab of function node (#3674) @HiroyasuNishiyama
- Function: Fix ESM module loading in Function node (#3645) @knolleary
- Inject: Fix JSONata evaluation of inject button (#3632) @HiroyasuNishiyama
- TCP: Dont delete TCP socket twice (#3630) @Steve-Mcl
- MQTT Node: define noproxy variable (#3626) @Steve-Mcl
- Debug: i18n debug sidebar node label (#3623) @HiroyasuNishiyama
#### 3.0.0-beta.2: Beta Release #### 3.0.0-beta.2: Beta Release
**Migration from 2.x** **Migration from 2.x**

View File

@@ -1,6 +1,6 @@
{ {
"name": "node-red", "name": "node-red",
"version": "3.0.0-beta.2", "version": "3.0.0-beta.3",
"description": "Low-code programming for event-driven applications", "description": "Low-code programming for event-driven applications",
"homepage": "http://nodered.org", "homepage": "http://nodered.org",
"license": "Apache-2.0", "license": "Apache-2.0",
@@ -49,7 +49,7 @@
"hash-sum": "2.0.0", "hash-sum": "2.0.0",
"hpagent": "1.0.0", "hpagent": "1.0.0",
"https-proxy-agent": "5.0.1", "https-proxy-agent": "5.0.1",
"i18next": "21.8.2", "i18next": "21.8.10",
"iconv-lite": "0.6.3", "iconv-lite": "0.6.3",
"is-utf8": "0.2.1", "is-utf8": "0.2.1",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
@@ -62,7 +62,7 @@
"moment": "2.29.3", "moment": "2.29.3",
"moment-timezone": "0.5.34", "moment-timezone": "0.5.34",
"mqtt": "4.3.7", "mqtt": "4.3.7",
"multer": "1.4.4", "multer": "1.4.5-lts.1",
"mustache": "4.2.0", "mustache": "4.2.0",
"node-red-admin": "^3.0.0", "node-red-admin": "^3.0.0",
"node-watch": "0.7.3", "node-watch": "0.7.3",
@@ -76,7 +76,7 @@
"semver": "7.3.7", "semver": "7.3.7",
"tar": "6.1.11", "tar": "6.1.11",
"tough-cookie": "4.0.0", "tough-cookie": "4.0.0",
"uglify-js": "3.15.5", "uglify-js": "3.16.0",
"uuid": "8.3.2", "uuid": "8.3.2",
"ws": "7.5.6", "ws": "7.5.6",
"xml2js": "0.4.23" "xml2js": "0.4.23"
@@ -105,16 +105,16 @@
"grunt-sass": "~3.1.0", "grunt-sass": "~3.1.0",
"grunt-simple-mocha": "~0.4.1", "grunt-simple-mocha": "~0.4.1",
"grunt-simple-nyc": "^3.0.1", "grunt-simple-nyc": "^3.0.1",
"i18next-http-backend": "1.4.0", "i18next-http-backend": "1.4.1",
"jquery-i18next": "1.2.1", "jquery-i18next": "1.2.1",
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template", "jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
"marked": "4.0.15", "marked": "4.0.17",
"minami": "1.2.3", "minami": "1.2.3",
"mocha": "9.2.2", "mocha": "9.2.2",
"node-red-node-test-helper": "^0.2.7", "node-red-node-test-helper": "^0.2.7",
"nodemon": "2.0.16", "nodemon": "2.0.16",
"proxy": "^1.0.2", "proxy": "^1.0.2",
"sass": "1.51.0", "sass": "1.52.3",
"should": "13.2.3", "should": "13.2.3",
"sinon": "11.1.2", "sinon": "11.1.2",
"stoppable": "^1.1.0", "stoppable": "^1.1.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/editor-api", "name": "@node-red/editor-api",
"version": "3.0.0-beta.2", "version": "3.0.0-beta.3",
"license": "Apache-2.0", "license": "Apache-2.0",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {
@@ -16,8 +16,8 @@
} }
], ],
"dependencies": { "dependencies": {
"@node-red/util": "3.0.0-beta.2", "@node-red/util": "3.0.0-beta.3",
"@node-red/editor-client": "3.0.0-beta.2", "@node-red/editor-client": "3.0.0-beta.3",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"body-parser": "1.20.0", "body-parser": "1.20.0",
"clone": "2.1.2", "clone": "2.1.2",
@@ -26,7 +26,7 @@
"express": "4.18.1", "express": "4.18.1",
"memorystore": "1.6.7", "memorystore": "1.6.7",
"mime": "3.0.0", "mime": "3.0.0",
"multer": "1.4.4", "multer": "1.4.5-lts.1",
"mustache": "4.2.0", "mustache": "4.2.0",
"oauth2orize": "1.11.1", "oauth2orize": "1.11.1",
"passport-http-bearer": "1.0.1", "passport-http-bearer": "1.0.1",

View File

@@ -1187,5 +1187,11 @@
"missing-config": "__prop__: missing configuration node", "missing-config": "__prop__: missing configuration node",
"validation-error": "__prop__: validation error: __node__, __id__: __error__" "validation-error": "__prop__: validation error: __node__, __id__: __error__"
} }
},
"contextMenu": {
"insert": "Insert",
"node": "Node",
"junction": "Junction",
"linkNodes": "Link Nodes"
} }
} }

View File

@@ -1188,6 +1188,12 @@
"validation-error": "__prop__: チェックエラー: __node__, __id__: __error__" "validation-error": "__prop__: チェックエラー: __node__, __id__: __error__"
} }
}, },
"contextMenu": {
"insert": "挿入",
"node": "ノード",
"junction": "分岐点",
"linkNodes": "Linkード"
},
"action-list": { "action-list": {
"toggle-show-tips": "ヒント表示切替", "toggle-show-tips": "ヒント表示切替",
"show-about": "Node-REDの説明を表示", "show-about": "Node-REDの説明を表示",
@@ -1302,7 +1308,7 @@
"search": "検索", "search": "検索",
"search-previous": "前を検索", "search-previous": "前を検索",
"search-next": "次を検索", "search-next": "次を検索",
"show-action-list": "アクション一覧を表示", "show-action-list": "動作一覧を表示",
"confirm-edit-tray": "編集を完了", "confirm-edit-tray": "編集を完了",
"cancel-edit-tray": "編集をキャンセル", "cancel-edit-tray": "編集をキャンセル",
"show-remote-diff": "リモートとの変更差分を表示", "show-remote-diff": "リモートとの変更差分を表示",
@@ -1324,6 +1330,11 @@
"zoom-out": "ズームアウト", "zoom-out": "ズームアウト",
"zoom-reset": "ズームリセット", "zoom-reset": "ズームリセット",
"toggle-navigator": "ナビゲータ表示切替", "toggle-navigator": "ナビゲータ表示切替",
"show-system-info": "システムインフォメーション" "show-system-info": "システム情報",
"split-wires-with-junctions": "分岐点によりワイヤーを分割",
"new-project": "新しいプロジェクト",
"open-project": "プロジェクトを開く",
"show-project-settings": "プロジェクト設定を表示",
"show-version-control-tab": "バージョンコントロールタブを表示"
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/editor-client", "name": "@node-red/editor-client",
"version": "3.0.0-beta.2", "version": "3.0.0-beta.3",
"license": "Apache-2.0", "license": "Apache-2.0",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@@ -133,6 +133,8 @@ RED.menu = (function() {
if (opt.options) { if (opt.options) {
item.addClass("red-ui-menu-dropdown-submenu"+(opt.direction!=='right'?" pull-left":"")); item.addClass("red-ui-menu-dropdown-submenu"+(opt.direction!=='right'?" pull-left":""));
var submenu = $('<ul id="'+opt.id+'-submenu" class="red-ui-menu-dropdown"></ul>').appendTo(item); var submenu = $('<ul id="'+opt.id+'-submenu" class="red-ui-menu-dropdown"></ul>').appendTo(item);
var hasIcons = false
var hasSubmenus = false
for (var i=0;i<opt.options.length;i++) { for (var i=0;i<opt.options.length;i++) {
@@ -144,6 +146,8 @@ RED.menu = (function() {
opt.options[i].onpostselect = opt.onpostselect opt.options[i].onpostselect = opt.onpostselect
} }
opt.options[i].direction = opt.direction opt.options[i].direction = opt.direction
hasIcons = hasIcons || (opt.options[i].icon);
hasSubmenus = hasSubmenus || (opt.options[i].options);
} }
var li = createMenuItem(opt.options[i]); var li = createMenuItem(opt.options[i]);
@@ -151,6 +155,14 @@ RED.menu = (function() {
li.appendTo(submenu); li.appendTo(submenu);
} }
} }
if (!hasIcons) {
submenu.addClass("red-ui-menu-dropdown-noicons")
}
if (hasSubmenus) {
submenu.addClass("red-ui-menu-dropdown-submenus")
}
} }
if (opt.disabled) { if (opt.disabled) {
item.addClass("disabled"); item.addClass("disabled");
@@ -191,6 +203,8 @@ RED.menu = (function() {
} }
var lastAddedSeparator = false; var lastAddedSeparator = false;
var hasSubmenus = false;
var hasIcons = false;
for (var i=0;i<options.options.length;i++) { for (var i=0;i<options.options.length;i++) {
var opt = options.options[i]; var opt = options.options[i];
if (opt) { if (opt) {
@@ -203,6 +217,8 @@ RED.menu = (function() {
opt.direction = options.direction || 'left' opt.direction = options.direction || 'left'
} }
if (opt !== null || !lastAddedSeparator) { if (opt !== null || !lastAddedSeparator) {
hasIcons = hasIcons || (opt && opt.icon);
hasSubmenus = hasSubmenus || (opt && opt.options);
var li = createMenuItem(opt); var li = createMenuItem(opt);
if (li) { if (li) {
li.appendTo(topMenu); li.appendTo(topMenu);
@@ -210,7 +226,12 @@ RED.menu = (function() {
} }
} }
} }
if (!hasIcons) {
topMenu.addClass("red-ui-menu-dropdown-noicons")
}
if (hasSubmenus) {
topMenu.addClass("red-ui-menu-dropdown-submenus")
}
return topMenu; return topMenu;
} }

View File

@@ -21,6 +21,7 @@
* - multi : boolean - if true, .selected will return an array of results * - multi : boolean - if true, .selected will return an array of results
* otherwise, returns the first selected item * otherwise, returns the first selected item
* - sortable: boolean/string - TODO: see editableList * - sortable: boolean/string - TODO: see editableList
* - selectable: boolean - default true - whether individual items can be selected
* - rootSortable: boolean - if 'sortable' is set, then setting this to * - rootSortable: boolean - if 'sortable' is set, then setting this to
* false, prevents items being sorted to the * false, prevents items being sorted to the
* top level of the tree * top level of the tree
@@ -118,6 +119,7 @@
switch(evt.keyCode) { switch(evt.keyCode) {
case 32: // SPACE case 32: // SPACE
case 13: // ENTER case 13: // ENTER
if (!that.options.selectable) { return }
if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) { if (evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey) {
return return
} }

View File

@@ -48,10 +48,10 @@ RED.contextMenu = (function() {
const menuItems = [ const menuItems = [
{ onselect: 'core:show-action-list', onpostselect: function() {} }, { onselect: 'core:show-action-list', onpostselect: function() {} },
{ {
label: 'Insert', label: RED._("contextMenu.insert"),
options: [ options: [
{ {
label: 'Node', label: RED._("contextMenu.node"),
onselect: function() { onselect: function() {
RED.view.showQuickAddDialog({ RED.view.showQuickAddDialog({
position: [ options.x - offset.left, options.y - offset.top ], position: [ options.x - offset.left, options.y - offset.top ],
@@ -62,12 +62,12 @@ RED.contextMenu = (function() {
} }
}, },
{ {
label: 'Junction', label: RED._("contextMenu.junction"),
onselect: 'core:split-wires-with-junctions', onselect: 'core:split-wires-with-junctions',
disabled: hasSelection || !hasLinks disabled: hasSelection || !hasLinks
}, },
{ {
label: 'Link Nodes', label: RED._("contextMenu.linkNodes"),
onselect: 'core:split-wire-with-link-nodes', onselect: 'core:split-wire-with-link-nodes',
disabled: hasSelection || !hasLinks disabled: hasSelection || !hasLinks
} }
@@ -170,6 +170,7 @@ RED.contextMenu = (function() {
} }
return { return {
show: show show: show,
hide: disposeMenu
} }
})() })()

View File

@@ -21,7 +21,7 @@
const MONACO = "monaco"; const MONACO = "monaco";
const ACE = "ace"; const ACE = "ace";
const defaultEditor = ACE; const defaultEditor = MONACO;
const DEFAULT_SETTINGS = { lib: defaultEditor, options: {} }; const DEFAULT_SETTINGS = { lib: defaultEditor, options: {} };
var selectedCodeEditor = null; var selectedCodeEditor = null;
var initialised = false; var initialised = false;
@@ -48,12 +48,12 @@
} }
function create(options) { function create(options) {
//TODO: (quandry - for consideration) //TODO: (quandry - for consideration)
// Below, I had to create a hidden element if options.id || options.element is not in the DOM // Below, I had to create a hidden element if options.id || options.element is not in the DOM
// I have seen 1 node calling `this.editor = RED.editor.createEditor()` with an // I have seen 1 node calling `this.editor = RED.editor.createEditor()` with an
// invalid (non existing html element selector) (e.g. node-red-contrib-components does this) // invalid (non existing html element selector) (e.g. node-red-contrib-components does this)
// This causes monaco to throw an error when attempting to hook up its events to the dom & the rest of the 'oneditperapre' // This causes monaco to throw an error when attempting to hook up its events to the dom & the rest of the 'oneditperapre'
// code is thus skipped. // code is thus skipped.
// In ACE mode, creating an ACE editor (with an invalid ID) allows the editor to be created (but obviously there is no UI) // In ACE mode, creating an ACE editor (with an invalid ID) allows the editor to be created (but obviously there is no UI)
// Because one (or more) contrib nodes have left this bad code in place, how would we handle this? // Because one (or more) contrib nodes have left this bad code in place, how would we handle this?
// For compatibility, I have decided to create a hidden element so that at least an editor is created & errors do not occur. // For compatibility, I have decided to create a hidden element so that at least an editor is created & errors do not occur.
@@ -79,7 +79,7 @@
return this.editor.create(options);//fallback to ACE return this.editor.create(options);//fallback to ACE
} }
} }
return { return {
init: init, init: init,
/** /**
@@ -91,7 +91,7 @@
}, },
/** /**
* Get user selected code editor * Get user selected code editor
* @return {string} Returns * @return {string} Returns
* @memberof RED.editor.codeEditor * @memberof RED.editor.codeEditor
*/ */
get editor() { get editor() {
@@ -104,4 +104,4 @@
*/ */
create: create create: create
} }
})(); })();

View File

@@ -534,6 +534,7 @@
var container = $("#red-ui-editor-type-json-tab-ui-container").css({"height":"100%"}); var container = $("#red-ui-editor-type-json-tab-ui-container").css({"height":"100%"});
var filterDepth = Infinity; var filterDepth = Infinity;
var list = $('<div class="red-ui-debug-msg-payload red-ui-editor-type-json-editor">').appendTo(container).treeList({ var list = $('<div class="red-ui-debug-msg-payload red-ui-editor-type-json-editor">').appendTo(container).treeList({
selectable: false,
rootSortable: false, rootSortable: false,
sortable: ".red-ui-editor-type-json-editor-item-handle", sortable: ".red-ui-editor-type-json-editor-item-handle",
}).on("treelistchangeparent", function(event, evt) { }).on("treelistchangeparent", function(event, evt) {

View File

@@ -37,8 +37,7 @@
if (!node._def.defaults || !node._def.defaults.hasOwnProperty("icon")) { if (!node._def.defaults || !node._def.defaults.hasOwnProperty("icon")) {
var icon = $("#red-ui-editor-node-icon").val()||""; var icon = $("#red-ui-editor-node-icon").val()||"";
if (!this.isDefaultIcon) { if (!this.isDefaultIcon) {
if ((icon !== node.icon) && if ((node.icon && icon !== node.icon) || (!node.icon && icon !== "")) {
(icon !== "")) {
editState.changes.icon = node.icon; editState.changes.icon = node.icon;
node.icon = icon; node.icon = icon;
editState.changed = true; editState.changed = true;

View File

@@ -979,13 +979,14 @@ RED.view.tools = (function() {
* - it uses `<paletteLabel> <N>` - where N is the next available integer that * - it uses `<paletteLabel> <N>` - where N is the next available integer that
* doesn't clash with any existing nodes of that type * doesn't clash with any existing nodes of that type
* @param {Object} node The node to set the name of - if not provided, uses current selection * @param {Object} node The node to set the name of - if not provided, uses current selection
* @param {{ renameBlank: boolean, renameClash: boolean, generateHistory: boolean }} options Possible options are `renameBlank`, `renameClash` and `generateHistory`
*/ */
function generateNodeNames(node, options) { function generateNodeNames(node, options) {
options = options || { options = Object.assign({
renameBlank: true, renameBlank: true,
renameClash: true, renameClash: true,
generateHistory: true generateHistory: true
} }, options)
let nodes = node; let nodes = node;
if (node) { if (node) {
if (!Array.isArray(node)) { if (!Array.isArray(node)) {

View File

@@ -988,6 +988,7 @@ RED.view = (function() {
if (RED.view.DEBUG) { if (RED.view.DEBUG) {
console.warn("canvasMouseDown", { mouse_mode, point: d3.mouse(this), event: d3.event }); console.warn("canvasMouseDown", { mouse_mode, point: d3.mouse(this), event: d3.event });
} }
RED.contextMenu.hide();
if (mouse_mode === RED.state.SELECTING_NODE) { if (mouse_mode === RED.state.SELECTING_NODE) {
d3.event.stopPropagation(); d3.event.stopPropagation();
return; return;
@@ -1071,8 +1072,8 @@ RED.view = (function() {
var oy = point[1]; var oy = point[1];
const offset = $("#red-ui-workspace-chart").offset() const offset = $("#red-ui-workspace-chart").offset()
var clientX = ox + offset.left var clientX = ox + offset.left - $("#red-ui-workspace-chart").scrollLeft()
var clientY = oy + offset.top var clientY = oy + offset.top - $("#red-ui-workspace-chart").scrollTop()
if (RED.settings.get("editor").view['view-snap-grid']) { if (RED.settings.get("editor").view['view-snap-grid']) {
// eventLayer.append("circle").attr("cx",point[0]).attr("cy",point[1]).attr("r","2").attr('fill','red') // eventLayer.append("circle").attr("cx",point[0]).attr("cy",point[1]).attr("r","2").attr('fill','red')
@@ -1779,6 +1780,9 @@ RED.view = (function() {
} }
var i; var i;
var historyEvent; var historyEvent;
if (d3.event.button === 2) {
return
}
if (mouse_mode === RED.state.PANNING) { if (mouse_mode === RED.state.PANNING) {
resetMouseVars(); resetMouseVars();
return return
@@ -2903,6 +2907,7 @@ RED.view = (function() {
function portMouseDown(d,portType,portIndex, evt) { function portMouseDown(d,portType,portIndex, evt) {
if (RED.view.DEBUG) { console.warn("portMouseDown", mouse_mode,d,portType,portIndex); } if (RED.view.DEBUG) { console.warn("portMouseDown", mouse_mode,d,portType,portIndex); }
RED.contextMenu.hide();
evt = evt || d3.event; evt = evt || d3.event;
if (evt === 1) { if (evt === 1) {
return; return;
@@ -3411,6 +3416,7 @@ RED.view = (function() {
function nodeMouseDown(d) { function nodeMouseDown(d) {
if (RED.view.DEBUG) { console.warn("nodeMouseDown", mouse_mode,d); } if (RED.view.DEBUG) { console.warn("nodeMouseDown", mouse_mode,d); }
focusView(); focusView();
RED.contextMenu.hide();
if (d3.event.button === 1) { if (d3.event.button === 1) {
return; return;
} }
@@ -3793,6 +3799,7 @@ RED.view = (function() {
if (RED.view.DEBUG) { if (RED.view.DEBUG) {
console.warn("linkMouseDown", { mouse_mode, point: d3.mouse(this), event: d3.event }); console.warn("linkMouseDown", { mouse_mode, point: d3.mouse(this), event: d3.event });
} }
RED.contextMenu.hide();
if (mouse_mode === RED.state.SELECTING_NODE) { if (mouse_mode === RED.state.SELECTING_NODE) {
d3.event.stopPropagation(); d3.event.stopPropagation();
return; return;
@@ -3852,6 +3859,9 @@ RED.view = (function() {
} }
function groupMouseUp(g) { function groupMouseUp(g) {
if (RED.view.DEBUG) {
console.warn("groupMouseUp", { mouse_mode, event: d3.event });
}
if (dblClickPrimed && mousedown_group == g && clickElapsed > 0 && clickElapsed < dblClickInterval) { if (dblClickPrimed && mousedown_group == g && clickElapsed > 0 && clickElapsed < dblClickInterval) {
mouse_mode = RED.state.DEFAULT; mouse_mode = RED.state.DEFAULT;
RED.editor.editGroup(g); RED.editor.editGroup(g);
@@ -3867,6 +3877,10 @@ RED.view = (function() {
// return // return
// } // }
if (RED.view.DEBUG) {
console.warn("groupMouseDown", { mouse_mode, point: mouse, event: d3.event });
}
RED.contextMenu.hide();
focusView(); focusView();
if (d3.event.button === 1) { if (d3.event.button === 1) {
return; return;
@@ -5858,6 +5872,7 @@ RED.view = (function() {
* @private * @private
*/ */
function createNode(type, x, y, z) { function createNode(type, x, y, z) {
const wasDirty = RED.nodes.dirty()
var m = /^subflow:(.+)$/.exec(type); var m = /^subflow:(.+)$/.exec(type);
var activeSubflow = z ? RED.nodes.subflow(z) : null; var activeSubflow = z ? RED.nodes.subflow(z) : null;
if (activeSubflow && m) { if (activeSubflow && m) {
@@ -5916,7 +5931,7 @@ RED.view = (function() {
var historyEvent = { var historyEvent = {
t: "add", t: "add",
nodes: [nn.id], nodes: [nn.id],
dirty: RED.nodes.dirty() dirty: wasDirty
} }
if (activeSubflow) { if (activeSubflow) {
var subflowRefresh = RED.subflow.refresh(true); var subflowRefresh = RED.subflow.refresh(true);

View File

@@ -46,7 +46,7 @@
& > li > a, & > li > a,
& > li > a:focus { & > li > a:focus {
display: block; display: block;
padding: 4px 20px 4px 12px; padding: 4px 12px 4px 32px;
clear: both; clear: both;
font-weight: normal; font-weight: normal;
line-height: 20px; line-height: 20px;
@@ -58,6 +58,18 @@
& > li.pull-left > a:focus { & > li.pull-left > a:focus {
padding: 4px 12px 4px 32px; padding: 4px 12px 4px 32px;
} }
&.red-ui-menu-dropdown-noicons > li > a,
&.red-ui-menu-dropdown-noicons > li > a:focus {
padding: 4px 12px 4px 12px;
}
&.red-ui-menu-dropdown-submenus > li > a,
&.red-ui-menu-dropdown-submenus > li > a:focus {
padding-right: 20px;
}
& > .active > a, & > .active > a,
& > .active > a:hover, & > .active > a:hover,
& > .active > a:focus { & > .active > a:focus {

View File

@@ -54,7 +54,7 @@
} }
.red-ui-search-results-container { .red-ui-search-results-container {
display: none; display: none;
height: 150px; height: 195px;
.red-ui-editableList-container { .red-ui-editableList-container {
border: 1px dashed $primary-border-color; border: 1px dashed $primary-border-color;
border-top: 1px solid $secondary-border-color; border-top: 1px solid $secondary-border-color;

View File

@@ -37,7 +37,7 @@ ul.red-ui-sidebar-node-config-list {
} }
.red-ui-palette-node { .red-ui-palette-node {
overflow: hidden; overflow: hidden;
cursor: default;
&.selected { &.selected {
border-color: transparent; border-color: transparent;
box-shadow: 0 0 0 2px $node-selected-color; box-shadow: 0 0 0 2px $node-selected-color;
@@ -58,7 +58,7 @@ ul.red-ui-sidebar-node-config-list {
.red-ui-palette-icon-container { .red-ui-palette-icon-container {
font-size: 12px; font-size: 12px;
line-height: 30px; line-height: 30px;
background-color: $node-icon-background-color; background-color: $node-port-background;
border-top-right-radius: 4px; border-top-right-radius: 4px;
border-bottom-right-radius: 4px; border-bottom-right-radius: 4px;
a { a {
@@ -68,6 +68,7 @@ ul.red-ui-sidebar-node-config-list {
left: 0; left: 0;
right: 0; right: 0;
color: $node-port-label-color; color: $node-port-label-color;
cursor: pointer;
&:hover { &:hover {
text-decoration: none; text-decoration: none;
background: $node-port-background-hover; background: $node-port-background-hover;

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -1,15 +1,30 @@
export default { export default {
version: "3.0.0-beta.1", version: "3.0.0-beta.3",
steps: [ steps: [
{ {
titleIcon: "fa fa-map-o", titleIcon: "fa fa-map-o",
title: { title: {
"en-US": "Welcome to Node-RED 3.0 Beta 1!", "en-US": "Welcome to Node-RED 3.0 Beta 3!",
"ja": "Node-RED 3.0 ベータ1へようこそ!" "ja": "Node-RED 3.0 ベータ3へようこそ!"
}, },
description: { description: {
"en-US": "<p>This is the first Beta release of Node-RED 3.0. It contains just about everything we have planned for the final release.</p><p>Let's take a moment to discover the new features in this release.</p>", "en-US": "<p>This is the final beta release of Node-RED 3.0.</p><p>Let's take a moment to discover the new features in this release.</p>",
"ja": "<p>これはNode-RED 3.0の最のベータリリースです。これには、最終リリースで計画しているほぼ全ての機能が含まれています。</p><p>本リリースの新機能を見つけてみましょう。</p>" "ja": "<p>これはNode-RED 3.0の最のベータリリースです。</p><p>本リリースの新機能を見つけてみましょう。</p>"
}
},
{
title: {
"en-US": "Context Menu",
"ja": "コンテキストメニュー"
},
image: 'images/context-menu.png',
description: {
"en-US": `<p>The editor now has its own context menu when you
right-click in the workspace.</p>
<p>This makes many of the built-in actions much easier
to access.</p>`,
"ja": `<p>ワークスペースで右クリックすると、エディタに独自のコンテキストメニューが表示されるようになりました。</p>
<p>これによって多くの組み込み動作を、より簡単に利用できます。</p>`
} }
}, },
{ {
@@ -19,12 +34,13 @@ export default {
}, },
image: 'images/junction-slice.gif', image: 'images/junction-slice.gif',
description: { description: {
"en-US": `<p>To make it easier to route wires around your flows, it is now possible to "en-US": `<p>To make it easier to route wires around your flows,
add junction nodes that give you more control.</p> it is now possible to add junction nodes that give
<p>Junctions can be added to wires by holding the Shift key, then click and drag with you more control.</p>
the right-hand mouse button across the wires.</p>`, <p>Junctions can be added to wires by holding both the Alt key and the Shift key
then click and drag the mouse across the wires.</p>`,
"ja": `<p>フローのワイヤーの経路をより制御しやすくするために、分岐点ノードを追加できるようになりました。</p> "ja": `<p>フローのワイヤーの経路をより制御しやすくするために、分岐点ノードを追加できるようになりました。</p>
<p>シフトキーを押しながらマウスの右ボタンをクリックし、ワイヤーを横切るようにドラッグすることで、分岐点を追加できます。</p>` <p>Altキーとシフトキーを押しながらマウスをクリックし、ワイヤーを横切るようにドラッグすることで、分岐点を追加できます。</p>`
}, },
}, },
{ {

View File

@@ -118,7 +118,7 @@
.inject-time-row { .inject-time-row {
padding-left: 110px; padding-left: 110px;
} }
.inject-time-row select { .inject-time-row:not(#inject-time-row-interval) select {
margin: 3px 0; margin: 3px 0;
} }
.inject-time-days label { .inject-time-days label {

View File

@@ -558,7 +558,7 @@
onadd: function() { onadd: function() {
if (this.name === '_DEFAULT_') { if (this.name === '_DEFAULT_') {
this.name = '' this.name = ''
RED.actions.invoke("core:generate-node-names", this) RED.actions.invoke("core:generate-node-names", this, {generateHistory: false})
} }
} }
}); });

View File

@@ -221,7 +221,7 @@
function onAdd() { function onAdd() {
if (this.name === '_DEFAULT_') { if (this.name === '_DEFAULT_') {
this.name = '' this.name = ''
RED.actions.invoke("core:generate-node-names", this) RED.actions.invoke("core:generate-node-names", this, {generateHistory: false})
} }
for (var i=0;i<this.links.length;i++) { for (var i=0;i<this.links.length;i++) {
var n = RED.nodes.node(this.links[i]); var n = RED.nodes.node(this.links[i]);

View File

@@ -639,7 +639,7 @@
onadd: function() { onadd: function() {
if (this.name === '_DEFAULT_') { if (this.name === '_DEFAULT_') {
this.name = '' this.name = ''
RED.actions.invoke("core:generate-node-names", this) RED.actions.invoke("core:generate-node-names", this, {generateHistory: false})
} }
} }
}); });

View File

@@ -44,6 +44,14 @@ module.exports = function(RED) {
return undefined; return undefined;
} }
function parseEnv(key) {
var match = /^env\.(.+)/.exec(key);
if (match) {
return match[1];
}
return undefined;
}
/** /**
* Custom Mustache Context capable to collect message property and node * Custom Mustache Context capable to collect message property and node
* flow and global context * flow and global context
@@ -74,6 +82,11 @@ module.exports = function(RED) {
return value; return value;
} }
// try env
if (parseEnv(name)) {
return this.cachedContextTokens[name];
}
// try flow/global context: // try flow/global context:
var context = parseContext(name); var context = parseContext(name);
if (context) { if (context) {
@@ -156,6 +169,17 @@ module.exports = function(RED) {
var tokens = extractTokens(mustache.parse(template)); var tokens = extractTokens(mustache.parse(template));
var resolvedTokens = {}; var resolvedTokens = {};
tokens.forEach(function(name) { tokens.forEach(function(name) {
var env_name = parseEnv(name);
if (env_name) {
var promise = new Promise((resolve, reject) => {
var val = RED.util.evaluateNodeProperty(env_name, 'env', node)
resolvedTokens[name] = val;
resolve();
});
promises.push(promise);
return;
}
var context = parseContext(name); var context = parseContext(name);
if (context) { if (context) {
var type = context.type; var type = context.type;

View File

@@ -89,6 +89,9 @@ module.exports = function(RED) {
else if (msg.payload[s][t].toString().indexOf(node.sep) !== -1) { // add quotes if any "commas" else if (msg.payload[s][t].toString().indexOf(node.sep) !== -1) { // add quotes if any "commas"
msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo; msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo;
} }
else if (msg.payload[s][t].toString().indexOf("\n") !== -1) { // add quotes if any "\n"
msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo;
}
} }
ou += msg.payload[s].join(node.sep) + node.ret; ou += msg.payload[s].join(node.sep) + node.ret;
} }
@@ -112,7 +115,7 @@ module.exports = function(RED) {
q = q.replace(/"/g, '""'); q = q.replace(/"/g, '""');
ou += node.quo + q + node.quo + node.sep; ou += node.quo + q + node.quo + node.sep;
} }
else if (q.indexOf(node.sep) !== -1) { // add quotes if any "commas" else if (q.indexOf(node.sep) !== -1 || p.indexOf("\n") !== -1) { // add quotes if any "commas" or "\n"
ou += node.quo + q + node.quo + node.sep; ou += node.quo + q + node.quo + node.sep;
} }
else { ou += q + node.sep; } // otherwise just add else { ou += q + node.sep; } // otherwise just add
@@ -134,7 +137,7 @@ module.exports = function(RED) {
p = p.replace(/"/g, '""'); p = p.replace(/"/g, '""');
ou += node.quo + p + node.quo + node.sep; ou += node.quo + p + node.quo + node.sep;
} }
else if (p.indexOf(node.sep) !== -1) { // add quotes if any "commas" else if (p.indexOf(node.sep) !== -1 || p.indexOf("\n") !== -1) { // add quotes if any "commas" or "\n"
ou += node.quo + p + node.quo + node.sep; ou += node.quo + p + node.quo + node.sep;
} }
else { ou += p + node.sep; } // otherwise just add else { ou += p + node.sep; } // otherwise just add

View File

@@ -314,11 +314,13 @@ module.exports = function(RED) {
if (err) { if (err) {
return done(err); return done(err);
} }
msgInfo.send({payload: result}); msgInfo.msg.payload = result;
msgInfo.send(msgInfo.msg);
done(); done();
}); });
} else { } else {
msgInfo.send({payload: result}); msgInfo.msg.payload = result;
msgInfo.send(msgInfo.msg);
done(); done();
} }
} else { } else {

View File

@@ -28,7 +28,7 @@
<p>返却/sendの対象は次のとおりです:</p> <p>返却/sendの対象は次のとおりです:</p>
<ul> <ul>
<li>単一メッセージオブジェクト - 最初の出力に接続されたノードに渡されます</li> <li>単一メッセージオブジェクト - 最初の出力に接続されたノードに渡されます</li>
<li>メッセージオブジェクトの配列 - 対応する出力に接続されたノードに渡されます</li> <li>メッセージオブジェクトの配列 - 対応する出力に接続されたノードに渡されます</li>
</ul> </ul>
<p>: 初期化処理の実行はノードの初期化中に行われますそのため初期化処理タブにsendを記述した場合に後続ードでメッセージを受け取れないことがあります</p> <p>: 初期化処理の実行はノードの初期化中に行われますそのため初期化処理タブにsendを記述した場合に後続ードでメッセージを受け取れないことがあります</p>
<p>配列要素が配列の場合には複数のメッセージを対応する出力に送出します</p> <p>配列要素が配列の場合には複数のメッセージを対応する出力に送出します</p>

View File

@@ -928,6 +928,7 @@
"write": "write file", "write": "write file",
"read": "read file", "read": "read file",
"filename": "ファイル名", "filename": "ファイル名",
"path": "パス",
"action": "動作", "action": "動作",
"addnewline": "メッセージの入力のたびに改行を追加", "addnewline": "メッセージの入力のたびに改行を追加",
"createdir": "ディレクトリが存在しない場合は作成", "createdir": "ディレクトリが存在しない場合は作成",

View File

@@ -89,7 +89,7 @@
<dt class="optional">userProperties <span class="property-type">オブジェクト</span></dt> <dt class="optional">userProperties <span class="property-type">オブジェクト</span></dt>
<dd><b>MQTTv5</b>: </dd> <dd><b>MQTTv5</b>: </dd>
<dt class="optional">messageExpiryInterval <span class="property-type">数値</span></dt> <dt class="optional">messageExpiryInterval <span class="property-type">数値</span></dt>
<dd><b>MQTTv5</b>: </dd> <dd><b>MQTTv5</b>: </dd>
<dt class="optional">topicAlias <span class="property-type">数値</span></dt> <dt class="optional">topicAlias <span class="property-type">数値</span></dt>
<dd><b>MQTTv5</b>: 使MQTT</dd> <dd><b>MQTTv5</b>: 使MQTT</dd>
</dl> </dl>

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/nodes", "name": "@node-red/nodes",
"version": "3.0.0-beta.2", "version": "3.0.0-beta.3",
"license": "Apache-2.0", "license": "Apache-2.0",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -36,7 +36,7 @@
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"media-typer": "1.1.0", "media-typer": "1.1.0",
"mqtt": "4.3.7", "mqtt": "4.3.7",
"multer": "1.4.4", "multer": "1.4.5-lts.1",
"mustache": "4.2.0", "mustache": "4.2.0",
"node-watch": "0.7.3", "node-watch": "0.7.3",
"on-headers": "1.0.2", "on-headers": "1.0.2",

View File

@@ -359,6 +359,7 @@ function loadNodeSet(node) {
try { try {
var loadPromise = null; var loadPromise = null;
var r = require(node.file); var r = require(node.file);
r = r.__esModule ? r.default : r
if (typeof r === "function") { if (typeof r === "function") {
var red = registryUtil.createNodeApi(node); var red = registryUtil.createNodeApi(node);

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/registry", "name": "@node-red/registry",
"version": "3.0.0-beta.2", "version": "3.0.0-beta.3",
"license": "Apache-2.0", "license": "Apache-2.0",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {
@@ -16,11 +16,11 @@
} }
], ],
"dependencies": { "dependencies": {
"@node-red/util": "3.0.0-beta.2", "@node-red/util": "3.0.0-beta.3",
"clone": "2.1.2", "clone": "2.1.2",
"fs-extra": "10.1.0", "fs-extra": "10.1.0",
"semver": "7.3.7", "semver": "7.3.7",
"tar": "6.1.11", "tar": "6.1.11",
"uglify-js": "3.15.5" "uglify-js": "3.16.0"
} }
} }

View File

@@ -91,7 +91,7 @@ var api = module.exports = {
safeSettings.context = runtime.nodes.listContextStores(); safeSettings.context = runtime.nodes.listContextStores();
if (runtime.settings.editorTheme && runtime.settings.editorTheme.codeEditor) { if (runtime.settings.editorTheme && runtime.settings.editorTheme.codeEditor) {
safeSettings.codeEditor = runtime.settings.editorTheme.codeEditor || {}; safeSettings.codeEditor = runtime.settings.editorTheme.codeEditor || {};
safeSettings.codeEditor.lib = safeSettings.codeEditor.lib || "ace"; safeSettings.codeEditor.lib = safeSettings.codeEditor.lib || "monaco";
safeSettings.codeEditor.options = safeSettings.codeEditor.options || {}; safeSettings.codeEditor.options = safeSettings.codeEditor.options || {};
} }
safeSettings.libraries = runtime.library.getLibraries(); safeSettings.libraries = runtime.library.getLibraries();

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/runtime", "name": "@node-red/runtime",
"version": "3.0.0-beta.2", "version": "3.0.0-beta.3",
"license": "Apache-2.0", "license": "Apache-2.0",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {
@@ -16,8 +16,8 @@
} }
], ],
"dependencies": { "dependencies": {
"@node-red/registry": "3.0.0-beta.2", "@node-red/registry": "3.0.0-beta.3",
"@node-red/util": "3.0.0-beta.2", "@node-red/util": "3.0.0-beta.3",
"async-mutex": "0.3.2", "async-mutex": "0.3.2",
"clone": "2.1.2", "clone": "2.1.2",
"express": "4.18.1", "express": "4.18.1",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@node-red/util", "name": "@node-red/util",
"version": "3.0.0-beta.2", "version": "3.0.0-beta.3",
"license": "Apache-2.0", "license": "Apache-2.0",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -16,7 +16,7 @@
], ],
"dependencies": { "dependencies": {
"fs-extra": "10.1.0", "fs-extra": "10.1.0",
"i18next": "21.8.2", "i18next": "21.8.10",
"json-stringify-safe": "5.0.1", "json-stringify-safe": "5.0.1",
"jsonata": "1.8.6", "jsonata": "1.8.6",
"lodash.clonedeep": "^4.5.0", "lodash.clonedeep": "^4.5.0",

View File

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

View File

@@ -401,7 +401,7 @@ module.exports = {
* packages/node_modules/@node-red/editor-client/src/vendor/monaco/dist/theme * packages/node_modules/@node-red/editor-client/src/vendor/monaco/dist/theme
* e.g. "tomorrow-night", "upstream-sunburst", "github", "my-theme" * e.g. "tomorrow-night", "upstream-sunburst", "github", "my-theme"
*/ */
theme: "vs", // theme: "vs",
/** other overrides can be set e.g. fontSize, fontFamily, fontLigatures etc. /** other overrides can be set e.g. fontSize, fontFamily, fontLigatures etc.
* for the full list, see https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IStandaloneEditorConstructionOptions.html * for the full list, see https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.IStandaloneEditorConstructionOptions.html
*/ */

View File

@@ -144,6 +144,28 @@ describe('template node', function() {
}); });
}); });
describe('env var', function() {
before(function() {
process.env.TEST = 'xyzzy';
})
after(function() {
delete process.env.TEST;
})
it('should modify payload from env variable', function(done) {
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{env.TEST}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
helper.load(templateNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
msg.should.have.property('payload', 'payload=xyzzy');
done();
});
n1.receive({payload:"foo",topic: "bar"});
});
});
});
it('should modify payload from flow context', function(done) { it('should modify payload from flow context', function(done) {
var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{flow.value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}]; var flow = [{id:"n1",z:"t1", type:"template", field:"payload", template:"payload={{flow.value}}",wires:[["n2"]]},{id:"n2",z:"t1",type:"helper"}];
helper.load(templateNode, flow, function() { helper.load(templateNode, flow, function() {

View File

@@ -693,19 +693,19 @@ describe('CSV node', function() {
describe('json object to csv', function() { describe('json object to csv', function() {
it('should convert a simple object back to a csv', function(done) { it('should convert a simple object back to a csv', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,,e", wires:[["n2"]] }, var flow = [ { id:"n1", type:"csv", temp:"a,b,c,,e,f", wires:[["n2"]] },
{id:"n2", type:"helper"} ]; {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() { helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1"); var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2"); var n2 = helper.getNode("n2");
n2.on("input", function(msg) { n2.on("input", function(msg) {
try { try {
msg.should.have.property('payload', '4,foo,true,,0\n'); msg.should.have.property('payload', '4,foo,true,,0,"Hello\nWorld"\n');
done(); done();
} }
catch(e) { done(e); } catch(e) { done(e); }
}); });
var testJson = { e:0, d:1, b:"foo", c:true, a:4 }; var testJson = { e:0, d:1, b:"foo", c:true, a:4, f:"Hello\nWorld" };
n1.emit("input", {payload:testJson}); n1.emit("input", {payload:testJson});
}); });
}); });
@@ -777,7 +777,7 @@ describe('CSV node', function() {
} }
catch(e) { done(e); } catch(e) { done(e); }
}); });
var testJson = [{ d: 1, b: 3, c: 2, a: 4 },{d:4,a:1,c:3,b:2}]; var testJson = [{ d:1, b:3, c:2, a:4 },{d:4, a:1, c:3, b:2}];
n1.emit("input", {payload:testJson}); n1.emit("input", {payload:testJson});
}); });
}); });
@@ -790,12 +790,12 @@ describe('CSV node', function() {
var n2 = helper.getNode("n2"); var n2 = helper.getNode("n2");
n2.on("input", function(msg) { n2.on("input", function(msg) {
try { try {
msg.should.have.property('payload', 'a,b,c,d\n4,3,2,1\n1,2,3,4\n'); msg.should.have.property('payload', 'a,b,c,d\n4,3,2,1\n1,2,3,"a\nb"\n');
done(); done();
} }
catch(e) { done(e); } catch(e) { done(e); }
}); });
var testJson = [{ d: 1, b: 3, c: 2, a: 4 },{d:4,a:1,c:3,b:2}]; var testJson = [{ d:1, b:3, c:2, a:4 },{d:"a\nb", a:1, c:3, b:2}];
n1.emit("input", {payload:testJson}); n1.emit("input", {payload:testJson});
}); });
}); });
@@ -826,12 +826,12 @@ describe('CSV node', function() {
var n2 = helper.getNode("n2"); var n2 = helper.getNode("n2");
n2.on("input", function(msg) { n2.on("input", function(msg) {
try { try {
msg.should.have.property('payload', 'd,b,c,a\n1,3,2,4\n4,2,3,1\n'); msg.should.have.property('payload', 'd,b,c,a\n1,3,2,4\n4,"f\ng",3,1\n');
done(); done();
} }
catch(e) { done(e); } catch(e) { done(e); }
}); });
var testJson = [{ d: 1, b: 3, c: 2, a: 4 },{d:4,a:1,c:3,b:2}]; var testJson = [{ d: 1, b: 3, c: 2, a: 4 },{d:4,a:1,c:3,b:"f\ng"}];
n1.emit("input", {payload:testJson}); n1.emit("input", {payload:testJson});
}); });
}); });
@@ -844,12 +844,12 @@ describe('CSV node', function() {
var n2 = helper.getNode("n2"); var n2 = helper.getNode("n2");
n2.on("input", function(msg) { n2.on("input", function(msg) {
try { try {
msg.should.have.property('payload', ',0,1,foo,"ba""r","di,ng"\n'); msg.should.have.property('payload', ',0,1,foo,"ba""r","di,ng","fa\nba"\n');
done(); done();
} }
catch(e) { done(e); } catch(e) { done(e); }
}); });
var testJson = ["",0,1,"foo",'ba"r','di,ng']; var testJson = ["",0,1,"foo",'ba"r','di,ng',"fa\nba"];
n1.emit("input", {payload:testJson}); n1.emit("input", {payload:testJson});
}); });
}); });
@@ -898,12 +898,12 @@ describe('CSV node', function() {
var n2 = helper.getNode("n2"); var n2 = helper.getNode("n2");
n2.on("input", function(msg) { n2.on("input", function(msg) {
try { try {
msg.should.have.property('payload', 'col1,col2,col3,col4\r\nH1,H2,H3,H4\r\nA,B,,\r\nA,,C,\r\nA,,,D\r\n'); msg.should.have.property('payload', 'col1,col2,col3,col4\r\nH1,H2,H3,H4\r\nA,B,,\r\nA,,C,\r\nA,,,"D\nE"\r\n');
done(); done();
} }
catch(e) { done(e); } catch(e) { done(e); }
}); });
var testJson = [{"col1":"H1","col2":"H2","col3":"H3","col4":"H4"},{"col1":"A","col2":"B"},{"col1":"A","col3":"C"},{"col1":"A","col4":"D"}]; var testJson = [{"col1":"H1","col2":"H2","col3":"H3","col4":"H4"},{"col1":"A","col2":"B"},{"col1":"A","col3":"C"},{"col1":"A","col4":"D\nE"}];
n1.emit("input", {payload:testJson}); n1.emit("input", {payload:testJson});
}); });
}); });