mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge branch 'dev' into dev
This commit is contained in:
commit
422ed371f7
36
CHANGELOG.md
36
CHANGELOG.md
@ -1,3 +1,39 @@
|
|||||||
|
#### 1.0.3: Maintenance Release
|
||||||
|
|
||||||
|
Runtime
|
||||||
|
- Increase timeouts in Subflow tests to minimise false positives
|
||||||
|
- Update grunt-sass and add node-sass for node12 support
|
||||||
|
- Fix timings of Delay node tests
|
||||||
|
- #2340 Update JSONata to 1.7.0
|
||||||
|
- Bump https-proxy-agent version
|
||||||
|
- #2332 Fix error handling of nodes with multiple input handlers
|
||||||
|
- Add script to generate npm publish script
|
||||||
|
- #2371 Ensure folder is present before write (e.g. flows file not in user folder)
|
||||||
|
- #2371 Handle windows UNC '\\' paths
|
||||||
|
- #2366 Handle logging of non-JSON encodable objects
|
||||||
|
|
||||||
|
Editor
|
||||||
|
- #2328 Fix language handling in subflow node
|
||||||
|
- Use default language if lng param not set in i18n req
|
||||||
|
- #2326 Fix palette editor search visualization
|
||||||
|
- #2375 Subflow status not showing i18n version of contained core nodes status
|
||||||
|
- Fix inverse of 'replace' editor event
|
||||||
|
- #2376 Fallback to base language files if present
|
||||||
|
- #2373 Support UI testing on the latest Google Chrome
|
||||||
|
- #2364 Add tooltip to expand button in markdown editor
|
||||||
|
- #2363 Support ctrl key to select tabs for Windows
|
||||||
|
- #2356 Make JSONata help initially shown in expression editor
|
||||||
|
- #2355 Prohibit line break in type menu of typedInput
|
||||||
|
|
||||||
|
Nodes
|
||||||
|
- Delay: Fix delay to not pass through .reset and .flush props consistently
|
||||||
|
- #2352 File: Using the ‘a msg per line’ the last line does not get msg.topic passed
|
||||||
|
- #2339 HTTP Request: Check auth type on opening
|
||||||
|
- HTTP Request: add units info
|
||||||
|
- #2372 MQTT/WS: Improved proxy support for MQTT and WebSocket nodes
|
||||||
|
- #2370 MQTT: Add clarification that MQTT Out requires payload to send msg
|
||||||
|
|
||||||
|
|
||||||
#### 1.0.2: Maintenance Release
|
#### 1.0.2: Maintenance Release
|
||||||
|
|
||||||
Runtime
|
Runtime
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
var fs = require("fs-extra");
|
var fs = require("fs-extra");
|
||||||
|
var sass = require("node-sass");
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
|
|
||||||
@ -220,6 +221,7 @@ module.exports = function(grunt) {
|
|||||||
sass: {
|
sass: {
|
||||||
build: {
|
build: {
|
||||||
options: {
|
options: {
|
||||||
|
implementation: sass,
|
||||||
outputStyle: 'compressed'
|
outputStyle: 'compressed'
|
||||||
},
|
},
|
||||||
files: [{
|
files: [{
|
||||||
|
25
package.json
25
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red",
|
"name": "node-red",
|
||||||
"version": "1.0.2",
|
"version": "1.0.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",
|
||||||
@ -34,20 +34,20 @@
|
|||||||
"cookie": "0.4.0",
|
"cookie": "0.4.0",
|
||||||
"cookie-parser": "1.4.4",
|
"cookie-parser": "1.4.4",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"cron": "1.7.1",
|
"cron": "1.7.2",
|
||||||
"denque": "1.4.1",
|
"denque": "1.4.1",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"express-session": "1.16.2",
|
"express-session": "1.17.0",
|
||||||
"fs-extra": "8.1.0",
|
"fs-extra": "8.1.0",
|
||||||
"fs.notify": "0.0.4",
|
"fs.notify": "0.0.4",
|
||||||
"hash-sum": "2.0.0",
|
"hash-sum": "2.0.0",
|
||||||
"https-proxy-agent": "2.2.2",
|
"https-proxy-agent": "2.2.4",
|
||||||
"i18next": "15.1.2",
|
"i18next": "15.1.2",
|
||||||
"iconv-lite": "0.5.0",
|
"iconv-lite": "0.5.0",
|
||||||
"is-utf8": "0.2.1",
|
"is-utf8": "0.2.1",
|
||||||
"js-yaml": "3.13.1",
|
"js-yaml": "3.13.1",
|
||||||
"json-stringify-safe": "5.0.1",
|
"json-stringify-safe": "5.0.1",
|
||||||
"jsonata": "1.6.5",
|
"jsonata": "1.7.0",
|
||||||
"media-typer": "1.1.0",
|
"media-typer": "1.1.0",
|
||||||
"memorystore": "1.6.1",
|
"memorystore": "1.6.1",
|
||||||
"mime": "2.4.4",
|
"mime": "2.4.4",
|
||||||
@ -66,10 +66,10 @@
|
|||||||
"raw-body": "2.4.1",
|
"raw-body": "2.4.1",
|
||||||
"request": "2.88.0",
|
"request": "2.88.0",
|
||||||
"semver": "6.3.0",
|
"semver": "6.3.0",
|
||||||
"uglify-js": "3.6.0",
|
"uglify-js": "3.6.9",
|
||||||
"when": "3.7.8",
|
"when": "3.7.8",
|
||||||
"ws": "6.2.1",
|
"ws": "6.2.1",
|
||||||
"xml2js": "0.4.19"
|
"xml2js": "0.4.22"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"bcrypt": "3.0.6"
|
"bcrypt": "3.0.6"
|
||||||
@ -93,19 +93,20 @@
|
|||||||
"grunt-mocha-istanbul": "5.0.2",
|
"grunt-mocha-istanbul": "5.0.2",
|
||||||
"grunt-nodemon": "~0.4.2",
|
"grunt-nodemon": "~0.4.2",
|
||||||
"grunt-npm-command": "~0.1.2",
|
"grunt-npm-command": "~0.1.2",
|
||||||
"grunt-sass": "~2.0.0",
|
"grunt-sass": "~3.1.0",
|
||||||
"grunt-simple-mocha": "~0.4.1",
|
"grunt-simple-mocha": "~0.4.1",
|
||||||
"http-proxy": "^1.16.2",
|
"http-proxy": "1.18.0",
|
||||||
"istanbul": "0.4.5",
|
"istanbul": "0.4.5",
|
||||||
|
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
|
||||||
"minami": "1.2.3",
|
"minami": "1.2.3",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"mosca": "^2.8.3",
|
"mosca": "^2.8.3",
|
||||||
|
"node-red-node-test-helper": "^0.2.3",
|
||||||
|
"node-sass": "^4.13.0",
|
||||||
"should": "^8.4.0",
|
"should": "^8.4.0",
|
||||||
"sinon": "1.17.7",
|
"sinon": "1.17.7",
|
||||||
"stoppable": "^1.1.0",
|
"stoppable": "^1.1.0",
|
||||||
"supertest": "3.4.2",
|
"supertest": "3.4.2"
|
||||||
"node-red-node-test-helper": "^0.2.3",
|
|
||||||
"jsdoc-nr-template": "node-red/jsdoc-nr-template"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
|
@ -44,6 +44,7 @@ module.exports = {
|
|||||||
user: req.user,
|
user: req.user,
|
||||||
module: req.body.module,
|
module: req.body.module,
|
||||||
version: req.body.version,
|
version: req.body.version,
|
||||||
|
url: req.body.url,
|
||||||
req: apiUtils.getRequestLogObject(req)
|
req: apiUtils.getRequestLogObject(req)
|
||||||
}
|
}
|
||||||
runtimeAPI.nodes.addModule(opts).then(function(info) {
|
runtimeAPI.nodes.addModule(opts).then(function(info) {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
**/
|
**/
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
//var apiUtil = require('../util');
|
// var apiUtil = require('../util');
|
||||||
|
|
||||||
var i18n = require("@node-red/util").i18n; // TODO: separate module
|
var i18n = require("@node-red/util").i18n; // TODO: separate module
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ module.exports = {
|
|||||||
var namespace = req.params[0];
|
var namespace = req.params[0];
|
||||||
var lngs = req.query.lng;
|
var lngs = req.query.lng;
|
||||||
namespace = namespace.replace(/\.json$/,"");
|
namespace = namespace.replace(/\.json$/,"");
|
||||||
var lang = req.query.lng; //apiUtil.determineLangFromHeaders(req.acceptsLanguages() || []);
|
var lang = req.query.lng || i18n.defaultLang; //apiUtil.determineLangFromHeaders(req.acceptsLanguages() || []);
|
||||||
var prevLang = i18n.i.language;
|
var prevLang = i18n.i.language;
|
||||||
// Trigger a load from disk of the language if it is not the default
|
// Trigger a load from disk of the language if it is not the default
|
||||||
i18n.i.changeLanguage(lang, function(){
|
i18n.i.changeLanguage(lang, function(){
|
||||||
|
@ -42,7 +42,7 @@ var editor;
|
|||||||
/**
|
/**
|
||||||
* Initialise the module.
|
* Initialise the module.
|
||||||
* @param {Object} settings The runtime settings
|
* @param {Object} settings The runtime settings
|
||||||
* @param {HTTPServer} server An instance of HTTP Server
|
* @param {HTTPServer} _server An instance of HTTP Server
|
||||||
* @param {Storage} storage An instance of Node-RED Storage
|
* @param {Storage} storage An instance of Node-RED Storage
|
||||||
* @param {Runtime} runtimeAPI An instance of Node-RED Runtime
|
* @param {Runtime} runtimeAPI An instance of Node-RED Runtime
|
||||||
* @memberof @node-red/editor-api
|
* @memberof @node-red/editor-api
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/editor-api",
|
"name": "@node-red/editor-api",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@ -16,13 +16,13 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/util": "1.0.2",
|
"@node-red/util": "1.0.3",
|
||||||
"@node-red/editor-client": "1.0.2",
|
"@node-red/editor-client": "1.0.3",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"body-parser": "1.19.0",
|
"body-parser": "1.19.0",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"express-session": "1.16.2",
|
"express-session": "1.17.0",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"memorystore": "1.6.1",
|
"memorystore": "1.6.1",
|
||||||
"mime": "2.4.4",
|
"mime": "2.4.4",
|
||||||
|
@ -15,6 +15,17 @@
|
|||||||
"next": "Next",
|
"next": "Next",
|
||||||
"clone": "Clone project",
|
"clone": "Clone project",
|
||||||
"cont": "Continue"
|
"cont": "Continue"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"string": "string",
|
||||||
|
"number": "number",
|
||||||
|
"boolean": "boolean",
|
||||||
|
"array": "array",
|
||||||
|
"buffer": "buffer",
|
||||||
|
"object": "object",
|
||||||
|
"jsonString": "JSON string",
|
||||||
|
"undefined": "undefined",
|
||||||
|
"null": "null"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
@ -792,10 +803,14 @@
|
|||||||
"copyPath": "Copy path to item",
|
"copyPath": "Copy path to item",
|
||||||
"expandItems": "Expand items",
|
"expandItems": "Expand items",
|
||||||
"collapseItems": "Collapse items",
|
"collapseItems": "Collapse items",
|
||||||
"duplicate": "Duplicate"
|
"duplicate": "Duplicate",
|
||||||
|
"error": {
|
||||||
|
"invalidJSON": "Invalid JSON: "
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"markdownEditor": {
|
"markdownEditor": {
|
||||||
"title": "Markdown editor",
|
"title": "Markdown editor",
|
||||||
|
"expand": "Expand",
|
||||||
"format": "Formatted with markdown",
|
"format": "Formatted with markdown",
|
||||||
"heading1": "Heading 1",
|
"heading1": "Heading 1",
|
||||||
"heading2": "Heading 2",
|
"heading2": "Heading 2",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$string": {
|
"$string": {
|
||||||
"args": "arg",
|
"args": "arg[, prettify]",
|
||||||
"desc": "Casts the *arg* parameter to a string using the following casting rules:\n\n - Strings are unchanged\n - Functions are converted to an empty string\n - Numeric infinity and NaN throw an error because they cannot be represented as a JSON number\n - All other values are converted to a JSON string using the `JSON.stringify` function"
|
"desc": "Casts the `arg` parameter to a string using the following casting rules:\n\n - Strings are unchanged\n - Functions are converted to an empty string\n - Numeric infinity and NaN throw an error because they cannot be represented as a JSON number\n - All other values are converted to a JSON string using the `JSON.stringify` function. If `prettify` is true, then \"prettified\" JSON is produced. i.e One line per field and lines will be indented based on the field depth."
|
||||||
},
|
},
|
||||||
"$length": {
|
"$length": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
@ -185,7 +185,7 @@
|
|||||||
},
|
},
|
||||||
"$reduce": {
|
"$reduce": {
|
||||||
"args":"array, function [, init]",
|
"args":"array, function [, init]",
|
||||||
"desc":"Returns an aggregated value derived from applying the `function` parameter successively to each value in `array` in combination with the result of the previous application of the function.\n\nThe function must accept two arguments, and behaves like an infix operator between each value within the `array`.\n\nThe optional `init` parameter is used as the initial value in the aggregation."
|
"desc":"Returns an aggregated value derived from applying the `function` parameter successively to each value in `array` in combination with the result of the previous application of the function.\n\nThe function must accept two arguments, and behaves like an infix operator between each value within the `array`. The signature of `function` must be of the form: `myfunc($accumulator, $value[, $index[, $array]])`\n\nThe optional `init` parameter is used as the initial value in the aggregation."
|
||||||
},
|
},
|
||||||
"$flowContext": {
|
"$flowContext": {
|
||||||
"args": "string[, string]",
|
"args": "string[, string]",
|
||||||
@ -230,6 +230,37 @@
|
|||||||
"$parseInteger": {
|
"$parseInteger": {
|
||||||
"args": "string, picture",
|
"args": "string, picture",
|
||||||
"desc": "Parses the contents of the `string` parameter to an integer (as a JSON number) using the format specified by the `picture` string. The `picture` string parameter has the same format as `$formatInteger`."
|
"desc": "Parses the contents of the `string` parameter to an integer (as a JSON number) using the format specified by the `picture` string. The `picture` string parameter has the same format as `$formatInteger`."
|
||||||
|
},
|
||||||
|
"$error": {
|
||||||
|
"args": "[str]",
|
||||||
|
"desc": "Throws an error with a message. The optional `str` will replace the default message of `$error() function evaluated`"
|
||||||
|
},
|
||||||
|
"$assert": {
|
||||||
|
"args": "arg, str",
|
||||||
|
"desc": "If `arg` is true the function returns undefined. If `arg` is false an exception is thrown with `str` as the message of the exception."
|
||||||
|
},
|
||||||
|
"$single": {
|
||||||
|
"args": "array, function",
|
||||||
|
"desc": "Returns the one and only value in the `array` parameter that satisfies the `function` predicate (i.e. the `function` returns Boolean `true` when passed the value). Throws an exception if the number of matching values is not exactly one.\n\nThe function should be supplied in the following signature: `function(value [, index [, array]])` where value is each input of the array, index is the position of that value and the whole array is passed as the third argument"
|
||||||
|
},
|
||||||
|
"$encodeUrl": {
|
||||||
|
"args": "str",
|
||||||
|
"desc": "Encodes a Uniform Resource Locator (URL) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character.\n\nExample: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
||||||
|
},
|
||||||
|
"$encodeUrlComponent": {
|
||||||
|
"args": "str",
|
||||||
|
"desc": "Encodes a Uniform Resource Locator (URL) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character. \n\nExample: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
||||||
|
},
|
||||||
|
"$decodeUrl": {
|
||||||
|
"args": "str",
|
||||||
|
"desc": "Decodes a Uniform Resource Locator (URL) component previously created by encodeUrlComponent. \n\nExample: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
||||||
|
},
|
||||||
|
"$decodeUrlComponent": {
|
||||||
|
"args": "str",
|
||||||
|
"desc": "Decodes a Uniform Resource Locator (URL) previously created by encodeUrl. \n\nExample: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
||||||
|
},
|
||||||
|
"$distinct": {
|
||||||
|
"args": "array",
|
||||||
|
"desc": "Returns an array with duplicate values removed from `array`"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,17 @@
|
|||||||
"next": "進む",
|
"next": "進む",
|
||||||
"clone": "プロジェクトをクローン",
|
"clone": "プロジェクトをクローン",
|
||||||
"cont": "続ける"
|
"cont": "続ける"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"string": "文字列",
|
||||||
|
"number": "数値",
|
||||||
|
"boolean": "真偽値",
|
||||||
|
"array": "配列",
|
||||||
|
"buffer": "バッファ",
|
||||||
|
"object": "オブジェクト",
|
||||||
|
"jsonString": "JSON文字列",
|
||||||
|
"undefined": "undefined",
|
||||||
|
"null": "null"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
@ -791,10 +802,14 @@
|
|||||||
"copyPath": "要素のパスをコピー",
|
"copyPath": "要素のパスをコピー",
|
||||||
"expandItems": "要素を展開",
|
"expandItems": "要素を展開",
|
||||||
"collapseItems": "要素を折り畳む",
|
"collapseItems": "要素を折り畳む",
|
||||||
"duplicate": "複製"
|
"duplicate": "複製",
|
||||||
|
"error": {
|
||||||
|
"invalidJSON": "不正なJSON: "
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"markdownEditor": {
|
"markdownEditor": {
|
||||||
"title": "マークダウンエディタ",
|
"title": "マークダウンエディタ",
|
||||||
|
"expand": "拡大",
|
||||||
"format": "マークダウン形式で記述",
|
"format": "マークダウン形式で記述",
|
||||||
"heading1": "見出しレベル1",
|
"heading1": "見出しレベル1",
|
||||||
"heading2": "見出しレベル2",
|
"heading2": "見出しレベル2",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$string": {
|
"$string": {
|
||||||
"args": "arg",
|
"args": "arg[, prettify]",
|
||||||
"desc": "以下の型変換ルールを用いて、引数 *arg* を文字列へ型変換します。:\n\n - 文字列は変換しません。\n - 関数は空の文字列に変換します。\n - JSONの数値として表現できないため、無限大やNaNはエラーになります。\n - 他の値は `JSON.stringify` 関数を用いて、JSONの文字列へ変換します。"
|
"desc": "以下の型変換ルールを用いて、引数 *arg* を文字列へ型変換します。:\n\n - 文字列は変換しません。\n - 関数は空の文字列に変換します。\n - JSONの数値として表現できないため、無限大やNaNはエラーになります。\n - 他の値は `JSON.stringify` 関数を用いて、JSONの文字列へ変換します。`prettify`が真の場合、JSONを整形出力します。フィールドを1行毎に出力。フィールドのネスト深さによってインデントを行います。"
|
||||||
},
|
},
|
||||||
"$length": {
|
"$length": {
|
||||||
"args": "str",
|
"args": "str",
|
||||||
@ -185,7 +185,7 @@
|
|||||||
},
|
},
|
||||||
"$reduce": {
|
"$reduce": {
|
||||||
"args": "array, function [, init]",
|
"args": "array, function [, init]",
|
||||||
"desc": "配列の各要素値に関数 `function` を連続的に適用して得られる集約値を返します。 `function` の適用の際には、直前の `function` の適用結果と要素値が引数として与えられます。\n\n関数 `function` は引数を2つ取り、配列の各要素の間に配置する中置演算子のように作用しなくてはなりません。\n\n任意の引数 `init` には、集約時の初期値を設定します。"
|
"desc": "配列の各要素値に関数 `function` を連続的に適用して得られる集約値を返します。 `function` の適用の際には、直前の `function` の適用結果と要素値が引数として与えられます。\n\n関数 `function` は引数を2つ取り、配列の各要素の間に配置する中置演算子のように作用しなくてはなりません。関数`function`のシグネチャは`myfunc($accumulator, $value[, $index[, $array]])`という形式でなければなりません。\n\n任意の引数 `init` には、集約時の初期値を設定します。"
|
||||||
},
|
},
|
||||||
"$flowContext": {
|
"$flowContext": {
|
||||||
"args": "string",
|
"args": "string",
|
||||||
@ -230,5 +230,37 @@
|
|||||||
"$parseInteger": {
|
"$parseInteger": {
|
||||||
"args": "string, picture",
|
"args": "string, picture",
|
||||||
"desc": "`picture`文字列の指定に従って、`string`パラメータを整数(JSON数値)に変換します。`picture`文字列は`$formatInteger`と同じ形式です。"
|
"desc": "`picture`文字列の指定に従って、`string`パラメータを整数(JSON数値)に変換します。`picture`文字列は`$formatInteger`と同じ形式です。"
|
||||||
|
},
|
||||||
|
"$error": {
|
||||||
|
"args": "[str]",
|
||||||
|
"desc": "メッセージを指定して例外を送出します。メッセージ`str`を省略した場合は`$error() function evaluated`をメッセージとします。"
|
||||||
|
},
|
||||||
|
"$assert": {
|
||||||
|
"args": "arg, str",
|
||||||
|
"desc": "`arg`が真の場合、undefinedを返します。偽の場合、`str`をメッセージとする例外を送出します。"
|
||||||
|
},
|
||||||
|
"$single": {
|
||||||
|
"args": "array, function",
|
||||||
|
"desc": "`array`の要素のうち、条件判定関数`function`を満たす(`function`に与えた場合に真偽値`true`を返す)要素が1つのみである場合、それを返します。マッチする要素が1つのみでない場合、例外を送出します。\n\n指定する関数は`function(value [, index [, array]])`というシグネチャでなければなりません。ここで、`value`は`array`の要素値、`index`は要素の添字、第三引数には配列全体を渡します。"
|
||||||
|
},
|
||||||
|
"$encodeUrl": {
|
||||||
|
"args": "str",
|
||||||
|
"desc": "Uniform Resource Locator (URL)を構成する文字を1、2、3、もしくは、4文字エスケープシーケンスのUTF-8文字エンコーディングで置換します。\n\n例: `$encodeUrlComponent(\"?x=test\")` => `\"%3Fx%3Dtest\"`"
|
||||||
|
},
|
||||||
|
"$encodeUrlComponent": {
|
||||||
|
"args": "str",
|
||||||
|
"desc": "Uniform Resource Locator (URL)要素を構成する文字を1、2、3、もしくは、4文字エスケープシーケンスのUTF-8文字エンコーディングで置換します。\n\n例: `$encodeUrl(\"https://mozilla.org/?x=шеллы\")` => `\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\"`"
|
||||||
|
},
|
||||||
|
"$decodeUrl": {
|
||||||
|
"args": "str",
|
||||||
|
"desc": "encodeUrlComponentで置換したUniform Resource Locator (URL)をデコードします。\n\n例: `$decodeUrlComponent(\"%3Fx%3Dtest\")` => `\"?x=test\"`"
|
||||||
|
},
|
||||||
|
"$decodeUrlComponent": {
|
||||||
|
"args": "str",
|
||||||
|
"desc": "encodeUrlで置換したUniform Resource Locator (URL)要素をデコードします。 \n\n例: `$decodeUrl(\"https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B\")` => `\"https://mozilla.org/?x=шеллы\"`"
|
||||||
|
},
|
||||||
|
"$distinct": {
|
||||||
|
"args": "array",
|
||||||
|
"desc": "配列`array`から重複要素を削除した配列を返します。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/editor-client",
|
"name": "@node-red/editor-client",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -39,7 +39,7 @@ RED.history = (function() {
|
|||||||
inverseEv = {
|
inverseEv = {
|
||||||
t: 'replace',
|
t: 'replace',
|
||||||
config: RED.nodes.createCompleteNodeSet(),
|
config: RED.nodes.createCompleteNodeSet(),
|
||||||
changed: [],
|
changed: {},
|
||||||
rev: RED.nodes.version()
|
rev: RED.nodes.version()
|
||||||
};
|
};
|
||||||
RED.nodes.clear();
|
RED.nodes.clear();
|
||||||
|
@ -845,7 +845,7 @@ RED.nodes = (function() {
|
|||||||
var m = /^subflow:(.+)$/.exec(newNodes[i].type);
|
var m = /^subflow:(.+)$/.exec(newNodes[i].type);
|
||||||
if (m) {
|
if (m) {
|
||||||
var subflowId = m[1];
|
var subflowId = m[1];
|
||||||
var parent = getSubflow(newNodes[i].z || activeWorkspace);
|
var parent = getSubflow(activeWorkspace);
|
||||||
if (parent) {
|
if (parent) {
|
||||||
var err;
|
var err;
|
||||||
if (subflowId === parent.id) {
|
if (subflowId === parent.id) {
|
||||||
|
@ -218,7 +218,7 @@ RED.tabs = (function() {
|
|||||||
var thisTab = $(this).parent();
|
var thisTab = $(this).parent();
|
||||||
var fireSelectionChanged = false;
|
var fireSelectionChanged = false;
|
||||||
if (options.onselect) {
|
if (options.onselect) {
|
||||||
if (evt.metaKey) {
|
if (evt.metaKey || evt.ctrlKey) {
|
||||||
if (thisTab.hasClass("selected")) {
|
if (thisTab.hasClass("selected")) {
|
||||||
thisTab.removeClass("selected");
|
thisTab.removeClass("selected");
|
||||||
if (thisTab[0] !== currentTab[0]) {
|
if (thisTab[0] !== currentTab[0]) {
|
||||||
|
@ -2484,7 +2484,7 @@ RED.editor = (function() {
|
|||||||
editor.toolbar = customEditTypes['_markdown'].buildToolbar(toolbarRow,editor);
|
editor.toolbar = customEditTypes['_markdown'].buildToolbar(toolbarRow,editor);
|
||||||
if (options.expandable !== false) {
|
if (options.expandable !== false) {
|
||||||
var expandButton = $('<button type="button" class="red-ui-button" style="float: right;"><i class="fa fa-expand"></i></button>').appendTo(editor.toolbar);
|
var expandButton = $('<button type="button" class="red-ui-button" style="float: right;"><i class="fa fa-expand"></i></button>').appendTo(editor.toolbar);
|
||||||
|
RED.popover.tooltip(expandButton, RED._("markdownEditor.expand"));
|
||||||
expandButton.on("click", function(e) {
|
expandButton.on("click", function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var value = editor.getValue();
|
var value = editor.getValue();
|
||||||
@ -2558,7 +2558,7 @@ RED.editor = (function() {
|
|||||||
/**
|
/**
|
||||||
* Register a type editor.
|
* Register a type editor.
|
||||||
* @param {string} type - the type name
|
* @param {string} type - the type name
|
||||||
* @param {object} options - the editor definition
|
* @param {object} definition - the editor definition
|
||||||
* @function
|
* @function
|
||||||
* @memberof RED.editor
|
* @memberof RED.editor
|
||||||
*/
|
*/
|
||||||
|
@ -207,6 +207,7 @@
|
|||||||
}
|
}
|
||||||
expressionEditor.getSession().setValue(v||"",-1);
|
expressionEditor.getSession().setValue(v||"",-1);
|
||||||
});
|
});
|
||||||
|
funcSelect.change();
|
||||||
|
|
||||||
var tabs = RED.tabs.create({
|
var tabs = RED.tabs.create({
|
||||||
element: $("#red-ui-editor-type-expression-tabs"),
|
element: $("#red-ui-editor-type-expression-tabs"),
|
||||||
|
@ -302,8 +302,8 @@
|
|||||||
types:[
|
types:[
|
||||||
'str','num','bool',
|
'str','num','bool',
|
||||||
{value:"null",label:"null",hasValue:false},
|
{value:"null",label:"null",hasValue:false},
|
||||||
{value:"array",label:"array",hasValue:false},
|
{value:"array",label:RED._("common.type.array"),hasValue:false},
|
||||||
{value:"object",label:"object",hasValue:false}
|
{value:"object",label:RED._("common.type.object"),hasValue:false}
|
||||||
],
|
],
|
||||||
default: valType
|
default: valType
|
||||||
});
|
});
|
||||||
@ -577,7 +577,7 @@
|
|||||||
} catch(err) {
|
} catch(err) {
|
||||||
rootNode = null;
|
rootNode = null;
|
||||||
list.treeList('data',[{
|
list.treeList('data',[{
|
||||||
label: "Invalid JSON: "+err.toString()
|
label: RED._("jsonEditor.error.invalidJSON")+err.toString()
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,13 +75,16 @@ RED.palette.editor = (function() {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function installNodeModule(id,version,callback) {
|
function installNodeModule(id,version,url,callback) {
|
||||||
var requestBody = {
|
var requestBody = {
|
||||||
module: id
|
module: id
|
||||||
};
|
};
|
||||||
if (version) {
|
if (version) {
|
||||||
requestBody.version = version;
|
requestBody.version = version;
|
||||||
}
|
}
|
||||||
|
if (url) {
|
||||||
|
requestBody.url = url;
|
||||||
|
}
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url:"nodes",
|
url:"nodes",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
@ -622,7 +625,7 @@ RED.palette.editor = (function() {
|
|||||||
if ($(this).hasClass('disabled')) {
|
if ($(this).hasClass('disabled')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
update(entry,loadedIndex[entry.name].version,container,function(err){});
|
update(entry,loadedIndex[entry.name].version,loadedIndex[entry.name].pkg_url,container,function(err){});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -788,7 +791,7 @@ RED.palette.editor = (function() {
|
|||||||
initInstallTab();
|
initInstallTab();
|
||||||
})
|
})
|
||||||
|
|
||||||
packageList = $('<ol>',{style:"position: absolute;top: 78px;bottom: 0;left: 0;right: 0px;"}).appendTo(installTab).editableList({
|
packageList = $('<ol>',{style:"position: absolute;top: 79px;bottom: 0;left: 0;right: 0px;"}).appendTo(installTab).editableList({
|
||||||
addButton: false,
|
addButton: false,
|
||||||
scrollOnAdd: false,
|
scrollOnAdd: false,
|
||||||
addItem: function(container,i,object) {
|
addItem: function(container,i,object) {
|
||||||
@ -872,7 +875,7 @@ RED.palette.editor = (function() {
|
|||||||
|
|
||||||
$('<div id="red-ui-palette-module-install-shade" class="red-ui-palette-module-shade hide"><div class="red-ui-palette-module-shade-status"></div><img src="red/images/spin.svg" class="red-ui-palette-spinner"/></div>').appendTo(installTab);
|
$('<div id="red-ui-palette-module-install-shade" class="red-ui-palette-module-shade hide"><div class="red-ui-palette-module-shade-status"></div><img src="red/images/spin.svg" class="red-ui-palette-spinner"/></div>').appendTo(installTab);
|
||||||
}
|
}
|
||||||
function update(entry,version,container,done) {
|
function update(entry,version,url,container,done) {
|
||||||
if (RED.settings.theme('palette.editable') === false) {
|
if (RED.settings.theme('palette.editable') === false) {
|
||||||
done(new Error('Palette not editable'));
|
done(new Error('Palette not editable'));
|
||||||
return;
|
return;
|
||||||
@ -898,7 +901,7 @@ RED.palette.editor = (function() {
|
|||||||
RED.actions.invoke("core:show-event-log");
|
RED.actions.invoke("core:show-event-log");
|
||||||
});
|
});
|
||||||
RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.name+" "+version);
|
RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.name+" "+version);
|
||||||
installNodeModule(entry.name,version,function(xhr) {
|
installNodeModule(entry.name,version,url,function(xhr) {
|
||||||
spinner.remove();
|
spinner.remove();
|
||||||
if (xhr) {
|
if (xhr) {
|
||||||
if (xhr.responseJSON) {
|
if (xhr.responseJSON) {
|
||||||
@ -1023,7 +1026,7 @@ RED.palette.editor = (function() {
|
|||||||
RED.actions.invoke("core:show-event-log");
|
RED.actions.invoke("core:show-event-log");
|
||||||
});
|
});
|
||||||
RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.id+" "+entry.version);
|
RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.id+" "+entry.version);
|
||||||
installNodeModule(entry.id,entry.version,function(xhr) {
|
installNodeModule(entry.id,entry.version,entry.pkg_url,function(xhr) {
|
||||||
spinner.remove();
|
spinner.remove();
|
||||||
if (xhr) {
|
if (xhr) {
|
||||||
if (xhr.responseJSON) {
|
if (xhr.responseJSON) {
|
||||||
|
@ -19,12 +19,18 @@ RED.subflow = (function() {
|
|||||||
var currentLocale = "en-US";
|
var currentLocale = "en-US";
|
||||||
|
|
||||||
var _subflowEditTemplate = '<script type="text/x-red" data-template-name="subflow">'+
|
var _subflowEditTemplate = '<script type="text/x-red" data-template-name="subflow">'+
|
||||||
'<div class="form-row"><label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label><input type="text" id="node-input-name"></div>'+
|
'<div class="form-row">'+
|
||||||
|
'<label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label>'+
|
||||||
|
'<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">'+
|
||||||
|
'</div>'+
|
||||||
'<div id="subflow-input-ui"></div>'+
|
'<div id="subflow-input-ui"></div>'+
|
||||||
'</script>';
|
'</script>';
|
||||||
|
|
||||||
var _subflowTemplateEditTemplate = '<script type="text/x-red" data-template-name="subflow-template">'+
|
var _subflowTemplateEditTemplate = '<script type="text/x-red" data-template-name="subflow-template">'+
|
||||||
'<div class="form-row"><label for="subflow-input-name" data-i18n="[append]common.label.name"><i class="fa fa-tag"></i> </label><input type="text" id="subflow-input-name"></div>'+
|
'<div class="form-row">'+
|
||||||
|
'<label for="subflow-input-name" data-i18n="[append]common.label.name"><i class="fa fa-tag"></i> </label>'+
|
||||||
|
'<input type="text" id="subflow-input-name" data-i18n="[placeholder]common.label.name">'+
|
||||||
|
'</div>'+
|
||||||
'<div class="form-row">'+
|
'<div class="form-row">'+
|
||||||
'<ul style="margin-bottom: 20px;" id="subflow-env-tabs"></ul>'+
|
'<ul style="margin-bottom: 20px;" id="subflow-env-tabs"></ul>'+
|
||||||
'</div>'+
|
'</div>'+
|
||||||
@ -802,8 +808,8 @@ RED.subflow = (function() {
|
|||||||
}
|
}
|
||||||
$("<option/>", opt).text(item.text).appendTo(locales);
|
$("<option/>", opt).text(item.text).appendTo(locales);
|
||||||
});
|
});
|
||||||
currentLocale = RED.i18n.lang();
|
var locale = RED.i18n.lang();
|
||||||
locales.val(currentLocale);
|
locales.val(locale);
|
||||||
|
|
||||||
locales.on("change", function() {
|
locales.on("change", function() {
|
||||||
currentLocale = $(this).val();
|
currentLocale = $(this).val();
|
||||||
@ -1048,7 +1054,7 @@ RED.subflow = (function() {
|
|||||||
}
|
}
|
||||||
langs.forEach(function(l) {
|
langs.forEach(function(l) {
|
||||||
var row = $('<div>').appendTo(content);
|
var row = $('<div>').appendTo(content);
|
||||||
$('<span>').css({display:"inline-block",width:"50px"}).text(l+(l===currentLocale?"*":"")).appendTo(row);
|
$('<span>').css({display:"inline-block",width:"120px"}).text(RED._("languages."+l)+(l===currentLocale?"*":"")).appendTo(row);
|
||||||
$('<span>').text(ui.label[l]||"").appendTo(row);
|
$('<span>').text(ui.label[l]||"").appendTo(row);
|
||||||
});
|
});
|
||||||
return content;
|
return content;
|
||||||
@ -1371,7 +1377,8 @@ RED.subflow = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var labels = ui.label || {};
|
var labels = ui.label || {};
|
||||||
var labelText = lookupLabel(labels, labels["en-US"]||tenv.name, currentLocale);
|
var locale = RED.i18n.lang();
|
||||||
|
var labelText = lookupLabel(labels, labels["en-US"]||tenv.name, locale);
|
||||||
var label = $('<label>').appendTo(row);
|
var label = $('<label>').appendTo(row);
|
||||||
var labelContainer = $('<span></span>').appendTo(label);
|
var labelContainer = $('<span></span>').appendTo(label);
|
||||||
if (ui.icon) {
|
if (ui.icon) {
|
||||||
@ -1423,7 +1430,7 @@ RED.subflow = (function() {
|
|||||||
input = $('<select>').css('width','70%').appendTo(row);
|
input = $('<select>').css('width','70%').appendTo(row);
|
||||||
if (ui.opts.opts) {
|
if (ui.opts.opts) {
|
||||||
ui.opts.opts.forEach(function(o) {
|
ui.opts.opts.forEach(function(o) {
|
||||||
$('<option>').val(o.v).text(lookupLabel(o.l, o.l['en-US']||o.v, currentLocale)).appendTo(input);
|
$('<option>').val(o.v).text(lookupLabel(o.l, o.l['en-US']||o.v, locale)).appendTo(input);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
input.val(val.value);
|
input.val(val.value);
|
||||||
|
@ -164,7 +164,7 @@ RED.workspaces = (function() {
|
|||||||
var dialogForm = $('<form id="dialog-form" class="form-horizontal"></form>').appendTo(trayBody);
|
var dialogForm = $('<form id="dialog-form" class="form-horizontal"></form>').appendTo(trayBody);
|
||||||
$('<div class="form-row">'+
|
$('<div class="form-row">'+
|
||||||
'<label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label>'+
|
'<label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label>'+
|
||||||
'<input type="text" id="node-input-name">'+
|
'<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">'+
|
||||||
'</div>').appendTo(dialogForm);
|
'</div>').appendTo(dialogForm);
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@
|
|||||||
border: 1px solid $primary-border-color;
|
border: 1px solid $primary-border-color;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background: $secondary-background;
|
background: $secondary-background;
|
||||||
|
white-space: nowrap;
|
||||||
z-index: 2000;
|
z-index: 2000;
|
||||||
a {
|
a {
|
||||||
padding: 6px 18px 6px 6px;
|
padding: 6px 18px 6px 6px;
|
||||||
|
@ -109,6 +109,7 @@
|
|||||||
{
|
{
|
||||||
'$abs':{ args:[ 'number' ]},
|
'$abs':{ args:[ 'number' ]},
|
||||||
'$append':{ args:[ 'array1', 'array2' ]},
|
'$append':{ args:[ 'array1', 'array2' ]},
|
||||||
|
'$assert':{ args: [ 'arg', 'str' ]},
|
||||||
'$average':{ args:[ 'array' ]},
|
'$average':{ args:[ 'array' ]},
|
||||||
'$base64decode':{ args:[ ]},
|
'$base64decode':{ args:[ ]},
|
||||||
'$base64encode':{ args:[ ]},
|
'$base64encode':{ args:[ ]},
|
||||||
@ -116,8 +117,14 @@
|
|||||||
'$ceil':{ args:[ 'number' ]},
|
'$ceil':{ args:[ 'number' ]},
|
||||||
'$contains':{ args:[ 'str', 'pattern' ]},
|
'$contains':{ args:[ 'str', 'pattern' ]},
|
||||||
'$count':{ args:[ 'array' ]},
|
'$count':{ args:[ 'array' ]},
|
||||||
|
'$decodeUrl':{ args:[ 'str' ]},
|
||||||
|
'$decodeUrlComponent':{ args:[ 'str' ]},
|
||||||
|
'$distinct':{ args:[ 'array' ]},
|
||||||
'$each':{ args:[ 'object', 'function' ]},
|
'$each':{ args:[ 'object', 'function' ]},
|
||||||
|
'$encodeUrl':{ args: ['str'] },
|
||||||
|
'$encodeUrlComponent':{ args:[ 'str' ]},
|
||||||
'$env': { args:[ 'arg' ]},
|
'$env': { args:[ 'arg' ]},
|
||||||
|
'$error':{ args:[ 'str' ]},
|
||||||
'$eval': { args: ['expr', 'context']},
|
'$eval': { args: ['expr', 'context']},
|
||||||
'$exists':{ args:[ 'arg' ]},
|
'$exists':{ args:[ 'arg' ]},
|
||||||
'$filter':{ args:[ 'array', 'function' ]},
|
'$filter':{ args:[ 'array', 'function' ]},
|
||||||
@ -151,12 +158,13 @@
|
|||||||
'$reverse':{ args:[ 'array' ]},
|
'$reverse':{ args:[ 'array' ]},
|
||||||
'$round':{ args:[ 'number', 'precision' ]},
|
'$round':{ args:[ 'number', 'precision' ]},
|
||||||
'$shuffle':{ args:[ 'array' ]},
|
'$shuffle':{ args:[ 'array' ]},
|
||||||
'$sift':{ args:[ 'object', 'function' ]},
|
'$sift':{ args: ['object', 'function'] },
|
||||||
|
'$single':{ args: ['array', 'function'] },
|
||||||
'$sort':{ args:[ 'array', 'function' ]},
|
'$sort':{ args:[ 'array', 'function' ]},
|
||||||
'$split':{ args:[ 'str', 'separator', 'limit' ]},
|
'$split':{ args:[ 'str', 'separator', 'limit' ]},
|
||||||
'$spread':{ args:[ 'object' ]},
|
'$spread':{ args:[ 'object' ]},
|
||||||
'$sqrt':{ args:[ 'number' ]},
|
'$sqrt':{ args:[ 'number' ]},
|
||||||
'$string':{ args:[ 'arg' ]},
|
'$string':{ args:[ 'arg', 'prettify' ]},
|
||||||
'$substring':{ args:[ 'str', 'start', 'length' ]},
|
'$substring':{ args:[ 'str', 'start', 'length' ]},
|
||||||
'$substringAfter':{ args:[ 'str', 'chars' ]},
|
'$substringAfter':{ args:[ 'str', 'chars' ]},
|
||||||
'$substringBefore':{ args:[ 'str', 'chars' ]},
|
'$substringBefore':{ args:[ 'str', 'chars' ]},
|
||||||
|
@ -30,16 +30,16 @@
|
|||||||
<!-- (with the 'node-input-' prefix). -->
|
<!-- (with the 'node-input-' prefix). -->
|
||||||
<!-- The available icon classes are defined Font Awesome Icons (FA Icons) -->
|
<!-- The available icon classes are defined Font Awesome Icons (FA Icons) -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-topic"><i class="fa fa-tasks"></i> Topic</label>
|
<label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="common.label.topic"></span></label>
|
||||||
<input type="text" id="node-input-topic" placeholder="Topic">
|
<input type="text" id="node-input-topic" data-i18n="[placeholder]common.label.topic">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
<!-- By convention, most nodes have a 'name' property. The following div -->
|
<!-- By convention, most nodes have a 'name' property. The following div -->
|
||||||
<!-- provides the necessary field. Should always be the last option -->
|
<!-- provides the necessary field. Should always be the last option -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<input type="text" id="node-input-name" placeholder="Name">
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<script type="text/x-red" data-template-name="comment">
|
<script type="text/x-red" data-template-name="comment">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
||||||
<input type="text" id="node-input-name">
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row node-text-editor-row">
|
<div class="form-row node-text-editor-row">
|
||||||
<input type="hidden" id="node-input-info" autofocus="autofocus">
|
<input type="hidden" id="node-input-info" autofocus="autofocus">
|
||||||
|
@ -127,7 +127,7 @@
|
|||||||
},
|
},
|
||||||
oneditprepare: function() {
|
oneditprepare: function() {
|
||||||
var node = this;
|
var node = this;
|
||||||
var previousValueType = {value:"prev",label:this._("inject.previous"),hasValue:false};
|
var previousValueType = {value:"prev",label:this._("switch.previous"),hasValue:false};
|
||||||
|
|
||||||
$("#node-input-property").typedInput({default:this.propertyType||'msg',types:['msg','flow','global','jsonata','env']});
|
$("#node-input-property").typedInput({default:this.propertyType||'msg',types:['msg','flow','global','jsonata','env']});
|
||||||
var outputCount = $("#node-input-outputs").val("{}");
|
var outputCount = $("#node-input-outputs").val("{}");
|
||||||
@ -237,15 +237,15 @@
|
|||||||
|
|
||||||
function createTypeValueField(){
|
function createTypeValueField(){
|
||||||
return $('<input/>',{class:"node-input-rule-type-value",type:"text",style:"margin-left: 5px;"}).appendTo(row).typedInput({default:'string',types:[
|
return $('<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:"string",label:RED._("common.type.string"),hasValue:false,icon:"red/images/typedInput/az.png"},
|
||||||
{value:"number",label:"number",hasValue:false},
|
{value:"number",label:RED._("common.type.number"),hasValue:false,icon:"red/images/typedInput/09.png"},
|
||||||
{value:"boolean",label:"boolean",hasValue:false},
|
{value:"boolean",label:RED._("common.type.boolean"),hasValue:false,icon:"red/images/typedInput/bool.png"},
|
||||||
{value:"array",label:"array",hasValue:false},
|
{value:"array",label:RED._("common.type.array"),hasValue:false,icon:"red/images/typedInput/json.png"},
|
||||||
{value:"buffer",label:"buffer",hasValue:false},
|
{value:"buffer",label:RED._("common.type.buffer"),hasValue:false,icon:"red/images/typedInput/bin.png"},
|
||||||
{value:"object",label:"object",hasValue:false},
|
{value:"object",label:RED._("common.type.object"),hasValue:false,icon:"red/images/typedInput/json.png"},
|
||||||
{value:"json",label:"JSON string",hasValue:false},
|
{value:"json",label:RED._("common.type.jsonString"),hasValue:false,icon:"red/images/typedInput/json.png"},
|
||||||
{value:"undefined",label:"undefined",hasValue:false},
|
{value:"undefined",label:RED._("common.type.undefined"),hasValue:false},
|
||||||
{value:"null",label:"null",hasValue:false}
|
{value:"null",label:RED._("common.type.null"),hasValue:false}
|
||||||
]});
|
]});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,15 +153,24 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
else if (node.pauseType === "rate") {
|
else if (node.pauseType === "rate") {
|
||||||
node.on("input", function(msg) {
|
node.on("input", function(msg) {
|
||||||
|
if (msg.hasOwnProperty("reset")) {
|
||||||
|
if (node.intervalID !== -1 ) {
|
||||||
|
clearInterval(node.intervalID);
|
||||||
|
node.intervalID = -1;
|
||||||
|
}
|
||||||
|
node.buffer = [];
|
||||||
|
node.status({text:"reset"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!node.drop) {
|
if (!node.drop) {
|
||||||
|
var m = RED.util.cloneMessage(msg);
|
||||||
|
delete m.flush;
|
||||||
if (node.intervalID !== -1) {
|
if (node.intervalID !== -1) {
|
||||||
if (!msg.hasOwnProperty("flush")) {
|
node.buffer.push(m);
|
||||||
node.buffer.push(msg);
|
node.reportDepth();
|
||||||
node.reportDepth();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node.send(msg);
|
node.send(m);
|
||||||
node.reportDepth();
|
node.reportDepth();
|
||||||
node.intervalID = setInterval(function() {
|
node.intervalID = setInterval(function() {
|
||||||
if (node.buffer.length === 0) {
|
if (node.buffer.length === 0) {
|
||||||
@ -174,6 +183,12 @@ module.exports = function(RED) {
|
|||||||
node.reportDepth();
|
node.reportDepth();
|
||||||
}, node.rate);
|
}, node.rate);
|
||||||
}
|
}
|
||||||
|
if (msg.hasOwnProperty("flush")) {
|
||||||
|
while (node.buffer.length > 0) {
|
||||||
|
node.send(node.buffer.shift());
|
||||||
|
}
|
||||||
|
node.status({});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var timeSinceLast;
|
var timeSinceLast;
|
||||||
@ -189,18 +204,6 @@ module.exports = function(RED) {
|
|||||||
node.send(msg);
|
node.send(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (msg.hasOwnProperty("reset")) {
|
|
||||||
clearInterval(node.intervalID);
|
|
||||||
node.intervalID = -1;
|
|
||||||
node.buffer = [];
|
|
||||||
node.status({text:"reset"});
|
|
||||||
}
|
|
||||||
if (msg.hasOwnProperty("flush")) {
|
|
||||||
while (node.buffer.length > 0) {
|
|
||||||
node.send(node.buffer.shift());
|
|
||||||
}
|
|
||||||
node.status({});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
node.on("close", function() {
|
node.on("close", function() {
|
||||||
clearInterval(node.intervalID);
|
clearInterval(node.intervalID);
|
||||||
|
@ -111,9 +111,13 @@ module.exports = function(RED) {
|
|||||||
if (typeof this.cleansession === 'undefined') {
|
if (typeof this.cleansession === 'undefined') {
|
||||||
this.cleansession = true;
|
this.cleansession = true;
|
||||||
}
|
}
|
||||||
var prox;
|
|
||||||
if (process.env.http_proxy != null) { prox = process.env.http_proxy; }
|
var prox, noprox;
|
||||||
if (process.env.HTTP_PROXY != null) { prox = process.env.HTTP_PROXY; }
|
if (process.env.http_proxy) { prox = process.env.http_proxy; }
|
||||||
|
if (process.env.HTTP_PROXY) { prox = process.env.HTTP_PROXY; }
|
||||||
|
if (process.env.no_proxy) { noprox = process.env.no_proxy.split(","); }
|
||||||
|
if (process.env.NO_PROXY) { noprox = process.env.NO_PROXY.split(","); }
|
||||||
|
|
||||||
|
|
||||||
// Create the URL to pass in to the MQTT.js library
|
// Create the URL to pass in to the MQTT.js library
|
||||||
if (this.brokerurl === "") {
|
if (this.brokerurl === "") {
|
||||||
@ -121,9 +125,15 @@ module.exports = function(RED) {
|
|||||||
if (this.broker.indexOf("://") > -1) {
|
if (this.broker.indexOf("://") > -1) {
|
||||||
this.brokerurl = this.broker;
|
this.brokerurl = this.broker;
|
||||||
// Only for ws or wss, check if proxy env var for additional configuration
|
// Only for ws or wss, check if proxy env var for additional configuration
|
||||||
if (this.brokerurl.indexOf("wss://") > -1 || this.brokerurl.indexOf("ws://") > -1 )
|
if (this.brokerurl.indexOf("wss://") > -1 || this.brokerurl.indexOf("ws://") > -1 ) {
|
||||||
// check if proxy is set in env
|
// check if proxy is set in env
|
||||||
if (prox) {
|
var noproxy;
|
||||||
|
if (noprox) {
|
||||||
|
for (var i = 0; i < noprox.length; i += 1) {
|
||||||
|
if (this.brokerurl.indexOf(noprox[i].trim()) !== -1) { noproxy=true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (prox && !noproxy) {
|
||||||
var parsedUrl = url.parse(this.brokerurl);
|
var parsedUrl = url.parse(this.brokerurl);
|
||||||
var proxyOpts = url.parse(prox);
|
var proxyOpts = url.parse(prox);
|
||||||
// true for wss
|
// true for wss
|
||||||
@ -134,9 +144,11 @@ module.exports = function(RED) {
|
|||||||
agent: agent
|
agent: agent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.brokerurl.indexOf("mqtts://") > -1 && (!this.usetls || !n.tls))
|
}
|
||||||
|
if (this.brokerurl.indexOf("mqtts://") > -1 && (!this.usetls || !n.tls)) {
|
||||||
// Default to validating the server cert
|
// Default to validating the server cert
|
||||||
this.verifyservercert = true;
|
this.verifyservercert = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// construct the std mqtt:// url
|
// construct the std mqtt:// url
|
||||||
if (this.usetls) {
|
if (this.usetls) {
|
||||||
|
@ -170,6 +170,7 @@
|
|||||||
if (this.authType) {
|
if (this.authType) {
|
||||||
$('#node-input-useAuth').prop('checked', true);
|
$('#node-input-useAuth').prop('checked', true);
|
||||||
$("#node-input-authType-select").val(this.authType);
|
$("#node-input-authType-select").val(this.authType);
|
||||||
|
$("#node-input-authType-select").change();
|
||||||
} else {
|
} else {
|
||||||
$('#node-input-useAuth').prop('checked', false);
|
$('#node-input-useAuth').prop('checked', false);
|
||||||
}
|
}
|
||||||
|
@ -39,10 +39,10 @@ module.exports = function(RED) {
|
|||||||
else { this.reqTimeout = 120000; }
|
else { this.reqTimeout = 120000; }
|
||||||
|
|
||||||
var prox, noprox;
|
var prox, noprox;
|
||||||
if (process.env.http_proxy != null) { prox = process.env.http_proxy; }
|
if (process.env.http_proxy) { prox = process.env.http_proxy; }
|
||||||
if (process.env.HTTP_PROXY != null) { prox = process.env.HTTP_PROXY; }
|
if (process.env.HTTP_PROXY) { prox = process.env.HTTP_PROXY; }
|
||||||
if (process.env.no_proxy != null) { noprox = process.env.no_proxy.split(","); }
|
if (process.env.no_proxy) { noprox = process.env.no_proxy.split(","); }
|
||||||
if (process.env.NO_PROXY != null) { noprox = process.env.NO_PROXY.split(","); }
|
if (process.env.NO_PROXY) { noprox = process.env.NO_PROXY.split(","); }
|
||||||
|
|
||||||
var proxyConfig = null;
|
var proxyConfig = null;
|
||||||
if (n.proxy) {
|
if (n.proxy) {
|
||||||
@ -88,8 +88,13 @@ module.exports = function(RED) {
|
|||||||
if (msg.method && n.method && (n.method === "use")) {
|
if (msg.method && n.method && (n.method === "use")) {
|
||||||
method = msg.method.toUpperCase(); // use the msg parameter
|
method = msg.method.toUpperCase(); // use the msg parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isHttps = (/^https/i.test(url));
|
||||||
|
|
||||||
var opts = {};
|
var opts = {};
|
||||||
opts.url = url;
|
opts.url = url;
|
||||||
|
// set defaultport, else when using HttpsProxyAgent, it's defaultPort of 443 will be used :(.
|
||||||
|
opts.defaultPort = isHttps?443:80;
|
||||||
opts.timeout = node.reqTimeout;
|
opts.timeout = node.reqTimeout;
|
||||||
opts.method = method;
|
opts.method = method;
|
||||||
opts.headers = {};
|
opts.headers = {};
|
||||||
@ -284,9 +289,10 @@ module.exports = function(RED) {
|
|||||||
opts.headers[clSet] = opts.headers['content-length'];
|
opts.headers[clSet] = opts.headers['content-length'];
|
||||||
delete opts.headers['content-length'];
|
delete opts.headers['content-length'];
|
||||||
}
|
}
|
||||||
|
|
||||||
var noproxy;
|
var noproxy;
|
||||||
if (noprox) {
|
if (noprox) {
|
||||||
for (var i in noprox) {
|
for (var i = 0; i < noprox.length; i += 1) {
|
||||||
if (url.indexOf(noprox[i]) !== -1) { noproxy=true; }
|
if (url.indexOf(noprox[i]) !== -1) { noproxy=true; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ module.exports = function(RED) {
|
|||||||
var ws = require("ws");
|
var ws = require("ws");
|
||||||
var inspect = require("util").inspect;
|
var inspect = require("util").inspect;
|
||||||
var url = require("url");
|
var url = require("url");
|
||||||
|
var HttpsProxyAgent = require('https-proxy-agent');
|
||||||
|
|
||||||
|
|
||||||
var serverUpgradeAdded = false;
|
var serverUpgradeAdded = false;
|
||||||
function handleServerUpgrade(request, socket, head) {
|
function handleServerUpgrade(request, socket, head) {
|
||||||
@ -55,7 +57,28 @@ module.exports = function(RED) {
|
|||||||
|
|
||||||
function startconn() { // Connect to remote endpoint
|
function startconn() { // Connect to remote endpoint
|
||||||
node.tout = null;
|
node.tout = null;
|
||||||
|
var prox, noprox;
|
||||||
|
if (process.env.http_proxy) { prox = process.env.http_proxy; }
|
||||||
|
if (process.env.HTTP_PROXY) { prox = process.env.HTTP_PROXY; }
|
||||||
|
if (process.env.no_proxy) { noprox = process.env.no_proxy.split(","); }
|
||||||
|
if (process.env.NO_PROXY) { noprox = process.env.NO_PROXY.split(","); }
|
||||||
|
|
||||||
|
var noproxy = false;
|
||||||
|
if (noprox) {
|
||||||
|
for (var i in noprox) {
|
||||||
|
if (node.path.indexOf(noprox[i].trim()) !== -1) { noproxy=true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var agent = undefined;
|
||||||
|
if (prox && !noproxy) {
|
||||||
|
agent = new HttpsProxyAgent(prox);
|
||||||
|
}
|
||||||
|
|
||||||
var options = {};
|
var options = {};
|
||||||
|
if (agent) {
|
||||||
|
options.agent = agent;
|
||||||
|
}
|
||||||
if (node.tls) {
|
if (node.tls) {
|
||||||
var tlsNode = RED.nodes.getNode(node.tls);
|
var tlsNode = RED.nodes.getNode(node.tls);
|
||||||
if (tlsNode) {
|
if (tlsNode) {
|
||||||
|
@ -371,7 +371,6 @@ module.exports = function(RED) {
|
|||||||
var server = net.createServer(function (socket) {
|
var server = net.createServer(function (socket) {
|
||||||
socket.setKeepAlive(true,120000);
|
socket.setKeepAlive(true,120000);
|
||||||
if (socketTimeout !== null) { socket.setTimeout(socketTimeout); }
|
if (socketTimeout !== null) { socket.setTimeout(socketTimeout); }
|
||||||
var remoteDetails = socket.remoteAddress+":"+socket.remotePort;
|
|
||||||
node.log(RED._("tcpin.status.connection-from",{host:socket.remoteAddress, port:socket.remotePort}));
|
node.log(RED._("tcpin.status.connection-from",{host:socket.remoteAddress, port:socket.remotePort}));
|
||||||
connectedSockets.push(socket);
|
connectedSockets.push(socket);
|
||||||
node.status({text:RED._("tcpin.status.connections",{count:connectedSockets.length})});
|
node.status({text:RED._("tcpin.status.connections",{count:connectedSockets.length})});
|
||||||
|
@ -230,17 +230,17 @@ module.exports = function(RED) {
|
|||||||
node.send(msg); // finally send the array
|
node.send(msg); // finally send the array
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var len = a.length;
|
var len = a.length;
|
||||||
for (var i = 0; i < len; i++) {
|
for (var i = 0; i < len; i++) {
|
||||||
var newMessage = RED.util.cloneMessage(msg);
|
var newMessage = RED.util.cloneMessage(msg);
|
||||||
newMessage.payload = a[i];
|
newMessage.payload = a[i];
|
||||||
if (!has_parts) {
|
if (!has_parts) {
|
||||||
newMessage.parts = {
|
newMessage.parts = {
|
||||||
id: msg._msgid,
|
id: msg._msgid,
|
||||||
index: i,
|
index: i,
|
||||||
count: len
|
count: len
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
newMessage.parts.index -= node.skip;
|
newMessage.parts.index -= node.skip;
|
||||||
@ -251,8 +251,8 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.send(newMessage);
|
node.send(newMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.linecount = 0;
|
node.linecount = 0;
|
||||||
}
|
}
|
||||||
catch(e) { node.error(e,msg); }
|
catch(e) { node.error(e,msg); }
|
||||||
|
@ -285,7 +285,11 @@
|
|||||||
$("#node-input-property").typedInput('types',['msg']);
|
$("#node-input-property").typedInput('types',['msg']);
|
||||||
$("#node-input-joiner").typedInput("show");
|
$("#node-input-joiner").typedInput("show");
|
||||||
} else {
|
} else {
|
||||||
$("#node-input-property").typedInput('types',['msg', {value:"full",label:"complete message",hasValue:false}]);
|
$("#node-input-property").typedInput('types', ['msg', {
|
||||||
|
value: "full",
|
||||||
|
label: RED._("node-red:join.completeMessage"),
|
||||||
|
hasValue: false
|
||||||
|
}]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -297,7 +301,11 @@
|
|||||||
|
|
||||||
$("#node-input-property").typedInput({
|
$("#node-input-property").typedInput({
|
||||||
typeField: $("#node-input-propertyType"),
|
typeField: $("#node-input-propertyType"),
|
||||||
types:['msg', {value:"full", label:"complete message", hasValue:false}]
|
types: ['msg', {
|
||||||
|
value: "full",
|
||||||
|
label: RED._("node-red:join.completeMessage"),
|
||||||
|
hasValue: false
|
||||||
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#node-input-key").typedInput({
|
$("#node-input-key").typedInput({
|
||||||
|
@ -341,6 +341,7 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
else if (node.format === "lines") {
|
else if (node.format === "lines") {
|
||||||
var m = { payload: spare,
|
var m = { payload: spare,
|
||||||
|
topic:msg.topic,
|
||||||
parts: {
|
parts: {
|
||||||
index: count,
|
index: count,
|
||||||
count: count+1,
|
count: count+1,
|
||||||
|
@ -604,33 +604,34 @@
|
|||||||
"label": {
|
"label": {
|
||||||
"property": "Property",
|
"property": "Property",
|
||||||
"rule": "rule",
|
"rule": "rule",
|
||||||
"repair" : "recreate message sequences"
|
"repair": "recreate message sequences"
|
||||||
},
|
},
|
||||||
|
"previous": "previous value",
|
||||||
"and": "and",
|
"and": "and",
|
||||||
"checkall": "checking all rules",
|
"checkall": "checking all rules",
|
||||||
"stopfirst": "stopping after first match",
|
"stopfirst": "stopping after first match",
|
||||||
"ignorecase": "ignore case",
|
"ignorecase": "ignore case",
|
||||||
"rules": {
|
"rules": {
|
||||||
"btwn":"is between",
|
"btwn": "is between",
|
||||||
"cont":"contains",
|
"cont": "contains",
|
||||||
"regex":"matches regex",
|
"regex": "matches regex",
|
||||||
"true":"is true",
|
"true": "is true",
|
||||||
"false":"is false",
|
"false": "is false",
|
||||||
"null":"is null",
|
"null": "is null",
|
||||||
"nnull":"is not null",
|
"nnull": "is not null",
|
||||||
"istype":"is of type",
|
"istype": "is of type",
|
||||||
"empty":"is empty",
|
"empty": "is empty",
|
||||||
"nempty":"is not empty",
|
"nempty": "is not empty",
|
||||||
"head":"head",
|
"head": "head",
|
||||||
"tail":"tail",
|
"tail": "tail",
|
||||||
"index":"index between",
|
"index": "index between",
|
||||||
"exp":"JSONata exp",
|
"exp": "JSONata exp",
|
||||||
"else":"otherwise",
|
"else": "otherwise",
|
||||||
"hask":"has key"
|
"hask": "has key"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"invalid-expr": "Invalid JSONata expression: __error__",
|
"invalid-expr": "Invalid JSONata expression: __error__",
|
||||||
"too-many" : "too many pending messages in switch node"
|
"too-many": "too many pending messages in switch node"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"change": {
|
"change": {
|
||||||
@ -848,41 +849,42 @@
|
|||||||
"stream":"Handle as a stream of messages",
|
"stream":"Handle as a stream of messages",
|
||||||
"addname":" Copy key to "
|
"addname":" Copy key to "
|
||||||
},
|
},
|
||||||
"join":{
|
"join": {
|
||||||
"join": "join",
|
"join": "join",
|
||||||
"mode":{
|
"mode": {
|
||||||
"mode":"Mode",
|
"mode": "Mode",
|
||||||
"auto":"automatic",
|
"auto": "automatic",
|
||||||
"merge":"merge sequences",
|
"merge": "merge sequences",
|
||||||
"reduce":"reduce sequence",
|
"reduce": "reduce sequence",
|
||||||
"custom":"manual"
|
"custom": "manual"
|
||||||
},
|
},
|
||||||
"combine":"Combine each",
|
"combine": "Combine each",
|
||||||
"create":"to create",
|
"completeMessage": "complete message",
|
||||||
"type":{
|
"create": "to create",
|
||||||
"string":"a String",
|
"type": {
|
||||||
"array":"an Array",
|
"string": "a String",
|
||||||
"buffer":"a Buffer",
|
"array": "an Array",
|
||||||
"object":"a key/value Object",
|
"buffer": "a Buffer",
|
||||||
"merged":"a merged Object"
|
"object": "a key/value Object",
|
||||||
|
"merged": "a merged Object"
|
||||||
},
|
},
|
||||||
"using":"using the value of",
|
"using": "using the value of",
|
||||||
"key":"as the key",
|
"key": "as the key",
|
||||||
"joinedUsing":"joined using",
|
"joinedUsing": "joined using",
|
||||||
"send":"Send the message:",
|
"send": "Send the message:",
|
||||||
"afterCount":"After a number of message parts",
|
"afterCount": "After a number of message parts",
|
||||||
"count":"count",
|
"count": "count",
|
||||||
"subsequent":"and every subsequent message.",
|
"subsequent": "and every subsequent message.",
|
||||||
"afterTimeout":"After a timeout following the first message",
|
"afterTimeout": "After a timeout following the first message",
|
||||||
"seconds":"seconds",
|
"seconds": "seconds",
|
||||||
"complete":"After a message with the <code>msg.complete</code> property set",
|
"complete": "After a message with the <code>msg.complete</code> property set",
|
||||||
"tip":"This mode assumes this node is either paired with a <i>split</i> node or the received messages will have a properly configured <code>msg.parts</code> property.",
|
"tip": "This mode assumes this node is either paired with a <i>split</i> node or the received messages will have a properly configured <code>msg.parts</code> property.",
|
||||||
"too-many" : "too many pending messages in join node",
|
"too-many": "too many pending messages in join node",
|
||||||
"merge": {
|
"merge": {
|
||||||
"topics-label":"Merged Topics",
|
"topics-label": "Merged Topics",
|
||||||
"topics":"topics",
|
"topics": "topics",
|
||||||
"topic" : "topic",
|
"topic": "topic",
|
||||||
"on-change":"Send merged message on arrival of a new topic"
|
"on-change": "Send merged message on arrival of a new topic"
|
||||||
},
|
},
|
||||||
"reduce": {
|
"reduce": {
|
||||||
"exp": "Reduce exp",
|
"exp": "Reduce exp",
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
<h3>Inputs</h3>
|
<h3>Inputs</h3>
|
||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
<dt>payload <span class="property-type">string | buffer</span></dt>
|
<dt>payload <span class="property-type">string | buffer</span></dt>
|
||||||
<dd> most users prefer simple text payloads, but binary buffers can also be published.</dd>
|
<dd> the payload to publish. If this property is not set, no message will be sent. To send a blank message, set this property to an empty String.</dd>
|
||||||
|
|
||||||
<dt class="optional">topic <span class="property-type">string</span></dt>
|
<dt class="optional">topic <span class="property-type">string</span></dt>
|
||||||
<dd> the MQTT topic to publish to.</dd>
|
<dd> the MQTT topic to publish to.</dd>
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
<dt class="optional">followRedirects</dt>
|
<dt class="optional">followRedirects</dt>
|
||||||
<dd>If set to <code>false</code> prevent following Redirect (HTTP 301).<code>true</code> by default</dd>
|
<dd>If set to <code>false</code> prevent following Redirect (HTTP 301).<code>true</code> by default</dd>
|
||||||
<dt class="optional">requestTimeout</dt>
|
<dt class="optional">requestTimeout</dt>
|
||||||
<dd>If set to a positive number, will override the globally set <code>httpRequestTimeout</code> parameter.</dd>
|
<dd>If set to a positive number of milliseconds, will override the globally set <code>httpRequestTimeout</code> parameter.</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<h3>Outputs</h3>
|
<h3>Outputs</h3>
|
||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
|
@ -604,6 +604,7 @@
|
|||||||
"rule": "条件",
|
"rule": "条件",
|
||||||
"repair": "メッセージ列の補正"
|
"repair": "メッセージ列の補正"
|
||||||
},
|
},
|
||||||
|
"previous": "前回の値",
|
||||||
"and": "~",
|
"and": "~",
|
||||||
"checkall": "全ての条件を適用",
|
"checkall": "全ての条件を適用",
|
||||||
"stopfirst": "最初に合致した条件で終了",
|
"stopfirst": "最初に合致した条件で終了",
|
||||||
@ -856,6 +857,7 @@
|
|||||||
"custom": "手動"
|
"custom": "手動"
|
||||||
},
|
},
|
||||||
"combine": "結合",
|
"combine": "結合",
|
||||||
|
"completeMessage": "メッセージ全体",
|
||||||
"create": "出力",
|
"create": "出力",
|
||||||
"type": {
|
"type": {
|
||||||
"string": "文字列",
|
"string": "文字列",
|
||||||
|
@ -33,6 +33,8 @@
|
|||||||
<dd><code>false</code>をセットすると、自己署名証明書を使用するhttpsサイトへのリクエストを許可します。</dd>
|
<dd><code>false</code>をセットすると、自己署名証明書を使用するhttpsサイトへのリクエストを許可します。</dd>
|
||||||
<dt class="optional">followRedirects</dt>
|
<dt class="optional">followRedirects</dt>
|
||||||
<dd><code>false</code>をセットすると、リダイレクトを行いません。デフォルトは<code>true</code>です。</dd>
|
<dd><code>false</code>をセットすると、リダイレクトを行いません。デフォルトは<code>true</code>です。</dd>
|
||||||
|
<dt class="optional">requestTimeout</dt>
|
||||||
|
<dd>正のミリ秒数をセットすると、 グローバルに設定された<code>httpRequestTimeout</code>パラメータを上書きします。</dd>
|
||||||
</dl>
|
</dl>
|
||||||
<h3>出力</h3>
|
<h3>出力</h3>
|
||||||
<dl class="message-properties">
|
<dl class="message-properties">
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
<p>「<i>合計値</i>」には出力メッセージを送信する前に受信すべきメッセージ数を指定します。オブジェクト出力の場合、この合計値に達すると後続メッセージの到着毎にメッセージを出力するように設定することもできます。</p>
|
<p>「<i>合計値</i>」には出力メッセージを送信する前に受信すべきメッセージ数を指定します。オブジェクト出力の場合、この合計値に達すると後続メッセージの到着毎にメッセージを出力するように設定することもできます。</p>
|
||||||
<p>「<i>秒</i>」には新規メッセージを送信するまでの経過時間を設定します。</p>
|
<p>「<i>秒</i>」には新規メッセージを送信するまでの経過時間を設定します。</p>
|
||||||
<p><code>msg.complete</code>プロパティを設定したメッセージを受信すると、出力メッセージを送信します。この時、メッセージ列の数をリセットします。</p>
|
<p><code>msg.complete</code>プロパティを設定したメッセージを受信すると、出力メッセージを送信します。この時、メッセージ列の数をリセットします。</p>
|
||||||
<p><code>msg.reset</code>プロパティを設定したメッセージを受診すると、部分的に受信済みのメッセージを破棄します。これらのメッセージは送信されません。この時、メッセージ列の数をリセットします。</p>
|
<p><code>msg.reset</code>プロパティを設定したメッセージを受信すると、部分的に受信済みのメッセージを破棄します。これらのメッセージは送信されません。この時、メッセージ列の数をリセットします。</p>
|
||||||
|
|
||||||
<h4>列の集約モード</h4>
|
<h4>列の集約モード</h4>
|
||||||
<p>列の集約モードを選択すると、メッセージ列を構成する各々のメッセージに対して式を適用し、集約した値を用いて一つのメッセージを構成します。</p>
|
<p>列の集約モードを選択すると、メッセージ列を構成する各々のメッセージに対して式を適用し、集約した値を用いて一つのメッセージを構成します。</p>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/nodes",
|
"name": "@node-red/nodes",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -22,12 +22,12 @@
|
|||||||
"cookie-parser": "1.4.4",
|
"cookie-parser": "1.4.4",
|
||||||
"cookie": "0.4.0",
|
"cookie": "0.4.0",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"cron": "1.7.1",
|
"cron": "1.7.2",
|
||||||
"denque": "1.4.1",
|
"denque": "1.4.1",
|
||||||
"fs-extra": "8.1.0",
|
"fs-extra": "8.1.0",
|
||||||
"fs.notify": "0.0.4",
|
"fs.notify": "0.0.4",
|
||||||
"hash-sum": "2.0.0",
|
"hash-sum": "2.0.0",
|
||||||
"https-proxy-agent": "2.2.2",
|
"https-proxy-agent": "2.2.4",
|
||||||
"is-utf8": "0.2.1",
|
"is-utf8": "0.2.1",
|
||||||
"js-yaml": "3.13.1",
|
"js-yaml": "3.13.1",
|
||||||
"media-typer": "1.1.0",
|
"media-typer": "1.1.0",
|
||||||
@ -38,7 +38,7 @@
|
|||||||
"raw-body": "2.4.1",
|
"raw-body": "2.4.1",
|
||||||
"request": "2.88.0",
|
"request": "2.88.0",
|
||||||
"ws": "6.2.1",
|
"ws": "6.2.1",
|
||||||
"xml2js": "0.4.19",
|
"xml2js": "0.4.22",
|
||||||
"iconv-lite": "0.5.0"
|
"iconv-lite": "0.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ var paletteEditorEnabled = false;
|
|||||||
var settings;
|
var settings;
|
||||||
var moduleRe = /^(@[^/]+?[/])?[^/]+?$/;
|
var moduleRe = /^(@[^/]+?[/])?[^/]+?$/;
|
||||||
var slashRe = process.platform === "win32" ? /\\|[/]/ : /[/]/;
|
var slashRe = process.platform === "win32" ? /\\|[/]/ : /[/]/;
|
||||||
|
var pkgurlRe = /^(https?|git(|\+https?|\+ssh|\+file)):\/\//;
|
||||||
|
|
||||||
function init(runtime) {
|
function init(runtime) {
|
||||||
events = runtime.events;
|
events = runtime.events;
|
||||||
@ -76,14 +77,17 @@ function checkExistingModule(module,version) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
function installModule(module,version) {
|
function installModule(module,version,url) {
|
||||||
activePromise = activePromise.then(() => {
|
activePromise = activePromise.then(() => {
|
||||||
//TODO: ensure module is 'safe'
|
//TODO: ensure module is 'safe'
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
var installName = module;
|
var installName = module;
|
||||||
var isUpgrade = false;
|
var isUpgrade = false;
|
||||||
try {
|
try {
|
||||||
if (moduleRe.test(module)) {
|
if (url && pkgurlRe.test(url)) {
|
||||||
|
// Git remote url or Tarball url - check the valid package url
|
||||||
|
installName = url;
|
||||||
|
} else if (moduleRe.test(module)) {
|
||||||
// Simple module name - assume it can be npm installed
|
// Simple module name - assume it can be npm installed
|
||||||
if (version) {
|
if (version) {
|
||||||
installName += "@"+version;
|
installName += "@"+version;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/registry",
|
"name": "@node-red/registry",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@ -16,9 +16,9 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/util": "1.0.2",
|
"@node-red/util": "1.0.3",
|
||||||
"semver": "6.3.0",
|
"semver": "6.3.0",
|
||||||
"uglify-js": "3.6.0",
|
"uglify-js": "3.6.9",
|
||||||
"when": "3.7.8"
|
"when": "3.7.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,6 +159,7 @@ var api = module.exports = {
|
|||||||
* @param {User} opts.user - the user calling the api
|
* @param {User} opts.user - the user calling the api
|
||||||
* @param {String} opts.module - the id of the module to install
|
* @param {String} opts.module - the id of the module to install
|
||||||
* @param {String} opts.version - (optional) the version of the module to install
|
* @param {String} opts.version - (optional) the version of the module to install
|
||||||
|
* @param {String} opts.url - (optional) url to install
|
||||||
* @param {Object} opts.req - the request to log (optional)
|
* @param {Object} opts.req - the request to log (optional)
|
||||||
* @return {Promise<ModuleInfo>} - the node module info
|
* @return {Promise<ModuleInfo>} - the node module info
|
||||||
* @memberof @node-red/runtime_nodes
|
* @memberof @node-red/runtime_nodes
|
||||||
@ -183,20 +184,20 @@ var api = module.exports = {
|
|||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
runtime.nodes.installModule(opts.module,opts.version).then(function(info) {
|
runtime.nodes.installModule(opts.module,opts.version,opts.url).then(function(info) {
|
||||||
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version}, opts.req);
|
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,url:opts.url}, opts.req);
|
||||||
return resolve(info);
|
return resolve(info);
|
||||||
}).catch(function(err) {
|
}).catch(function(err) {
|
||||||
if (err.code === 404) {
|
if (err.code === 404) {
|
||||||
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:"not_found"}, opts.req);
|
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,url:opts.url,error:"not_found"}, opts.req);
|
||||||
// TODO: code/status
|
// TODO: code/status
|
||||||
err.status = 404;
|
err.status = 404;
|
||||||
} else if (err.code) {
|
} else if (err.code) {
|
||||||
err.status = 400;
|
err.status = 400;
|
||||||
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code}, opts.req);
|
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,url:opts.url,error:err.code}, opts.req);
|
||||||
} else {
|
} else {
|
||||||
err.status = 400;
|
err.status = 400;
|
||||||
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code||"unexpected_error",message:err.toString()}, opts.req);
|
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,url:opts.url,error:err.code||"unexpected_error",message:err.toString()}, opts.req);
|
||||||
}
|
}
|
||||||
return reject(err);
|
return reject(err);
|
||||||
})
|
})
|
||||||
|
@ -224,7 +224,7 @@ Node.prototype._emitInput = function(arg) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
node.error(err,msg);
|
node.error(err,arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,6 +200,9 @@ class Subflow extends Flow {
|
|||||||
self.node.status({text:text});
|
self.node.status({text:text});
|
||||||
} else if (msg.status !== undefined) {
|
} else if (msg.status !== undefined) {
|
||||||
// if msg.status exists
|
// if msg.status exists
|
||||||
|
if (msg.status.hasOwnProperty("text") && msg.status.text.indexOf("common.") === 0) {
|
||||||
|
msg.status.text = "node-red:"+msg.status.text;
|
||||||
|
}
|
||||||
self.node.status(msg.status)
|
self.node.status(msg.status)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -310,7 +313,6 @@ class Subflow extends Flow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.start(diff);
|
super.start(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,7 +437,6 @@ class Subflow extends Flow {
|
|||||||
}
|
}
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,10 +150,10 @@ function reportNodeStateChange(info,enabled) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function installModule(module,version) {
|
function installModule(module,version,url) {
|
||||||
var existingModule = registry.getModuleInfo(module);
|
var existingModule = registry.getModuleInfo(module);
|
||||||
var isUpgrade = !!existingModule;
|
var isUpgrade = !!existingModule;
|
||||||
return registry.installModule(module,version).then(function(info) {
|
return registry.installModule(module,version,url).then(function(info) {
|
||||||
if (isUpgrade) {
|
if (isUpgrade) {
|
||||||
events.emit("runtime-event",{id:"node/upgraded",retain:false,payload:{module:module,version:version}});
|
events.emit("runtime-event",{id:"node/upgraded",retain:false,payload:{module:module,version:version}});
|
||||||
} else {
|
} else {
|
||||||
|
@ -56,8 +56,9 @@ function init(_settings, _runtime) {
|
|||||||
|
|
||||||
if (settings.flowFile) {
|
if (settings.flowFile) {
|
||||||
flowsFile = settings.flowFile;
|
flowsFile = settings.flowFile;
|
||||||
// handle Unix and Windows "C:\"
|
// handle Unix and Windows "C:\" and Windows "\\" for UNC.
|
||||||
if ((flowsFile[0] == "/") || (flowsFile[1] == ":")) {
|
if (fspath.isAbsolute(flowsFile)) {
|
||||||
|
//if (((flowsFile[0] == "\\") && (flowsFile[1] == "\\")) || (flowsFile[0] == "/") || (flowsFile[1] == ":")) {
|
||||||
// Absolute path
|
// Absolute path
|
||||||
flowsFullPath = flowsFile;
|
flowsFullPath = flowsFile;
|
||||||
} else if (flowsFile.substring(0,2) === "./") {
|
} else if (flowsFile.substring(0,2) === "./") {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
var fs = require('fs-extra');
|
var fs = require('fs-extra');
|
||||||
|
var fspath = require('path');
|
||||||
var when = require('when');
|
var when = require('when');
|
||||||
var nodeFn = require('when/node/function');
|
var nodeFn = require('when/node/function');
|
||||||
|
|
||||||
@ -79,25 +80,31 @@ module.exports = {
|
|||||||
* the write hits disk.
|
* the write hits disk.
|
||||||
*/
|
*/
|
||||||
writeFile: function(path,content,backupPath) {
|
writeFile: function(path,content,backupPath) {
|
||||||
if (backupPath) {
|
if (backupPath) {
|
||||||
if (fs.existsSync(path)) {
|
if (fs.existsSync(path)) {
|
||||||
fs.renameSync(path,backupPath);
|
fs.renameSync(path,backupPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return when.promise(function(resolve,reject) {
|
return when.promise(function(resolve,reject) {
|
||||||
var stream = fs.createWriteStream(path);
|
fs.ensureDir(fspath.dirname(path), (err)=>{
|
||||||
stream.on('open',function(fd) {
|
if (err) {
|
||||||
stream.write(content,'utf8',function() {
|
reject(err);
|
||||||
fs.fsync(fd,function(err) {
|
return;
|
||||||
if (err) {
|
}
|
||||||
log.warn(log._("storage.localfilesystem.fsync-fail",{path: path, message: err.toString()}));
|
var stream = fs.createWriteStream(path);
|
||||||
}
|
stream.on('open',function(fd) {
|
||||||
stream.end(resolve);
|
stream.write(content,'utf8',function() {
|
||||||
|
fs.fsync(fd,function(err) {
|
||||||
|
if (err) {
|
||||||
|
log.warn(log._("storage.localfilesystem.fsync-fail",{path: path, message: err.toString()}));
|
||||||
|
}
|
||||||
|
stream.end(resolve);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
stream.on('error',function(err) {
|
||||||
stream.on('error',function(err) {
|
reject(err);
|
||||||
reject(err);
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/runtime",
|
"name": "@node-red/runtime",
|
||||||
"version": "1.0.2",
|
"version": "1.0.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": "1.0.2",
|
"@node-red/registry": "1.0.3",
|
||||||
"@node-red/util": "1.0.2",
|
"@node-red/util": "1.0.3",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"fs-extra": "8.1.0",
|
"fs-extra": "8.1.0",
|
||||||
|
56
packages/node_modules/@node-red/util/lib/i18n.js
vendored
56
packages/node_modules/@node-red/util/lib/i18n.js
vendored
@ -81,35 +81,55 @@ function mergeCatalog(fallback,catalog) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var MessageFileLoader = {
|
|
||||||
type: "backend",
|
function readFile(lng, ns) {
|
||||||
init: function(services, backendOptions, i18nextOptions) {},
|
return new Promise((resolve, reject) => {
|
||||||
read: function(lng, ns, callback) {
|
if (resourceCache[ns] && resourceCache[ns][lng]) {
|
||||||
if (resourceMap[ns]) {
|
resolve(resourceCache[ns][lng]);
|
||||||
var file = path.join(resourceMap[ns].basedir,lng,resourceMap[ns].file);
|
} else if (resourceMap[ns]) {
|
||||||
//console.log(file);
|
var file = path.join(resourceMap[ns].basedir, lng, resourceMap[ns].file);
|
||||||
fs.readFile(file,"utf8",function(err,content) {
|
fs.readFile(file, "utf8", function (err, content) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
resourceCache[ns] = resourceCache[ns]||{};
|
resourceCache[ns] = resourceCache[ns] || {};
|
||||||
resourceCache[ns][lng] = JSON.parse(content.replace(/^\uFEFF/, ''));
|
resourceCache[ns][lng] = JSON.parse(content.replace(/^\uFEFF/, ''));
|
||||||
//console.log(resourceCache[ns][lng]);
|
var baseLng = lng.split('-')[0];
|
||||||
if (lng !== defaultLang) {
|
if (baseLng !== lng && resourceCache[ns][baseLng]) {
|
||||||
mergeCatalog(resourceCache[ns][defaultLang],resourceCache[ns][lng]);
|
mergeCatalog(resourceCache[ns][baseLng], resourceCache[ns][lng]);
|
||||||
}
|
}
|
||||||
callback(null, resourceCache[ns][lng]);
|
if (lng !== defaultLang) {
|
||||||
} catch(e) {
|
mergeCatalog(resourceCache[ns][defaultLang], resourceCache[ns][lng]);
|
||||||
callback(e);
|
}
|
||||||
|
resolve(resourceCache[ns][lng]);
|
||||||
|
} catch (e) {
|
||||||
|
reject(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
callback(new Error("Unrecognised namespace"));
|
reject(new Error("Unrecognised namespace"));
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var MessageFileLoader = {
|
||||||
|
type: "backend",
|
||||||
|
init: function (services, backendOptions, i18nextOptions) { },
|
||||||
|
read: function (lng, ns, callback) {
|
||||||
|
readFile(lng, ns)
|
||||||
|
.then(data => callback(null, data))
|
||||||
|
.catch(err => {
|
||||||
|
if (/-/.test(lng)) {
|
||||||
|
// if reading language file fails -> try reading base language (e. g. 'fr' instead of 'fr-FR' or 'de' for 'de-DE')
|
||||||
|
var baseLng = lng.split('-')[0];
|
||||||
|
readFile(baseLng, ns).then(baseData => callback(null, baseData)).catch(err => callback(err));
|
||||||
|
} else {
|
||||||
|
callback(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentLocale() {
|
function getCurrentLocale() {
|
||||||
|
@ -84,9 +84,14 @@ var consoleLogger = function(msg) {
|
|||||||
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+msg.msg.stack);
|
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+msg.msg.stack);
|
||||||
} else {
|
} else {
|
||||||
var message = msg.msg;
|
var message = msg.msg;
|
||||||
if (typeof message === 'object' && message !== null && message.toString() === '[object Object]' && message.message) {
|
try {
|
||||||
message = message.message;
|
if (typeof message === 'object' && message !== null && message.toString() === '[object Object]' && message.message) {
|
||||||
|
message = message.message;
|
||||||
|
}
|
||||||
|
} catch(e){
|
||||||
|
message = 'Exception trying to log: '+util.inspect(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+message);
|
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
244
packages/node_modules/@node-red/util/lib/util.js
vendored
244
packages/node_modules/@node-red/util/lib/util.js
vendored
@ -652,130 +652,148 @@ function normaliseNodeTypeName(name) {
|
|||||||
* @memberof @node-red/util_util
|
* @memberof @node-red/util_util
|
||||||
*/
|
*/
|
||||||
function encodeObject(msg,opts) {
|
function encodeObject(msg,opts) {
|
||||||
var debuglength = 1000;
|
try {
|
||||||
if (opts && opts.hasOwnProperty('maxLength')) {
|
var debuglength = 1000;
|
||||||
debuglength = opts.maxLength;
|
if (opts && opts.hasOwnProperty('maxLength')) {
|
||||||
}
|
debuglength = opts.maxLength;
|
||||||
var msgType = typeof msg.msg;
|
|
||||||
if (msg.msg instanceof Error) {
|
|
||||||
msg.format = "error";
|
|
||||||
var errorMsg = {};
|
|
||||||
if (msg.msg.name) {
|
|
||||||
errorMsg.name = msg.msg.name;
|
|
||||||
}
|
}
|
||||||
if (msg.msg.hasOwnProperty('message')) {
|
var msgType = typeof msg.msg;
|
||||||
errorMsg.message = msg.msg.message;
|
if (msg.msg instanceof Error) {
|
||||||
} else {
|
msg.format = "error";
|
||||||
errorMsg.message = msg.msg.toString();
|
var errorMsg = {};
|
||||||
}
|
if (msg.msg.name) {
|
||||||
msg.msg = JSON.stringify(errorMsg);
|
errorMsg.name = msg.msg.name;
|
||||||
} else if (msg.msg instanceof Buffer) {
|
}
|
||||||
msg.format = "buffer["+msg.msg.length+"]";
|
if (msg.msg.hasOwnProperty('message')) {
|
||||||
msg.msg = msg.msg.toString('hex');
|
errorMsg.message = msg.msg.message;
|
||||||
if (msg.msg.length > debuglength) {
|
} else {
|
||||||
msg.msg = msg.msg.substring(0,debuglength);
|
errorMsg.message = msg.msg.toString();
|
||||||
}
|
}
|
||||||
} else if (msg.msg && msgType === 'object') {
|
msg.msg = JSON.stringify(errorMsg);
|
||||||
try {
|
} else if (msg.msg instanceof Buffer) {
|
||||||
msg.format = msg.msg.constructor.name || "Object";
|
msg.format = "buffer["+msg.msg.length+"]";
|
||||||
// Handle special case of msg.req/res objects from HTTP In node
|
msg.msg = msg.msg.toString('hex');
|
||||||
if (msg.format === "IncomingMessage" || msg.format === "ServerResponse") {
|
if (msg.msg.length > debuglength) {
|
||||||
|
msg.msg = msg.msg.substring(0,debuglength);
|
||||||
|
}
|
||||||
|
} else if (msg.msg && msgType === 'object') {
|
||||||
|
try {
|
||||||
|
msg.format = msg.msg.constructor.name || "Object";
|
||||||
|
// Handle special case of msg.req/res objects from HTTP In node
|
||||||
|
if (msg.format === "IncomingMessage" || msg.format === "ServerResponse") {
|
||||||
|
msg.format = "Object";
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
msg.format = "Object";
|
msg.format = "Object";
|
||||||
}
|
}
|
||||||
} catch(err) {
|
if (/error/i.test(msg.format)) {
|
||||||
msg.format = "Object";
|
msg.msg = JSON.stringify({
|
||||||
}
|
name: msg.msg.name,
|
||||||
if (/error/i.test(msg.format)) {
|
message: msg.msg.message
|
||||||
msg.msg = JSON.stringify({
|
});
|
||||||
name: msg.msg.name,
|
} else {
|
||||||
message: msg.msg.message
|
var isArray = util.isArray(msg.msg);
|
||||||
});
|
if (isArray) {
|
||||||
} else {
|
msg.format = "array["+msg.msg.length+"]";
|
||||||
var isArray = util.isArray(msg.msg);
|
if (msg.msg.length > debuglength) {
|
||||||
if (isArray) {
|
// msg.msg = msg.msg.slice(0,debuglength);
|
||||||
msg.format = "array["+msg.msg.length+"]";
|
msg.msg = {
|
||||||
if (msg.msg.length > debuglength) {
|
|
||||||
// msg.msg = msg.msg.slice(0,debuglength);
|
|
||||||
msg.msg = {
|
|
||||||
__enc__: true,
|
|
||||||
type: "array",
|
|
||||||
data: msg.msg.slice(0,debuglength),
|
|
||||||
length: msg.msg.length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isArray || (msg.format === "Object")) {
|
|
||||||
msg.msg = safeJSONStringify(msg.msg, function(key, value) {
|
|
||||||
if (key === '_req' || key === '_res') {
|
|
||||||
value = {
|
|
||||||
__enc__: true,
|
|
||||||
type: "internal"
|
|
||||||
}
|
|
||||||
} else if (value instanceof Error) {
|
|
||||||
value = value.toString()
|
|
||||||
} else if (util.isArray(value) && value.length > debuglength) {
|
|
||||||
value = {
|
|
||||||
__enc__: true,
|
__enc__: true,
|
||||||
type: "array",
|
type: "array",
|
||||||
data: value.slice(0,debuglength),
|
data: msg.msg.slice(0,debuglength),
|
||||||
length: value.length
|
length: msg.msg.length
|
||||||
}
|
|
||||||
} else if (typeof value === 'string') {
|
|
||||||
if (value.length > debuglength) {
|
|
||||||
value = value.substring(0,debuglength)+"...";
|
|
||||||
}
|
|
||||||
} else if (typeof value === 'function') {
|
|
||||||
value = {
|
|
||||||
__enc__: true,
|
|
||||||
type: "function"
|
|
||||||
}
|
|
||||||
} else if (typeof value === 'number') {
|
|
||||||
if (isNaN(value) || value === Infinity || value === -Infinity) {
|
|
||||||
value = {
|
|
||||||
__enc__: true,
|
|
||||||
type: "number",
|
|
||||||
data: value.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (value && value.constructor) {
|
|
||||||
if (value.type === "Buffer") {
|
|
||||||
value.__enc__ = true;
|
|
||||||
value.length = value.data.length;
|
|
||||||
if (value.length > debuglength) {
|
|
||||||
value.data = value.data.slice(0,debuglength);
|
|
||||||
}
|
|
||||||
} else if (value.constructor.name === "ServerResponse") {
|
|
||||||
value = "[internal]"
|
|
||||||
} else if (value.constructor.name === "Socket") {
|
|
||||||
value = "[internal]"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
}
|
||||||
}," ");
|
if (isArray || (msg.format === "Object")) {
|
||||||
} else {
|
msg.msg = safeJSONStringify(msg.msg, function(key, value) {
|
||||||
try { msg.msg = msg.msg.toString(); }
|
if (key === '_req' || key === '_res') {
|
||||||
catch(e) { msg.msg = "[Type not printable]"; }
|
value = {
|
||||||
|
__enc__: true,
|
||||||
|
type: "internal"
|
||||||
|
}
|
||||||
|
} else if (value instanceof Error) {
|
||||||
|
value = value.toString()
|
||||||
|
} else if (util.isArray(value) && value.length > debuglength) {
|
||||||
|
value = {
|
||||||
|
__enc__: true,
|
||||||
|
type: "array",
|
||||||
|
data: value.slice(0,debuglength),
|
||||||
|
length: value.length
|
||||||
|
}
|
||||||
|
} else if (typeof value === 'string') {
|
||||||
|
if (value.length > debuglength) {
|
||||||
|
value = value.substring(0,debuglength)+"...";
|
||||||
|
}
|
||||||
|
} else if (typeof value === 'function') {
|
||||||
|
value = {
|
||||||
|
__enc__: true,
|
||||||
|
type: "function"
|
||||||
|
}
|
||||||
|
} else if (typeof value === 'number') {
|
||||||
|
if (isNaN(value) || value === Infinity || value === -Infinity) {
|
||||||
|
value = {
|
||||||
|
__enc__: true,
|
||||||
|
type: "number",
|
||||||
|
data: value.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (value && value.constructor) {
|
||||||
|
if (value.type === "Buffer") {
|
||||||
|
value.__enc__ = true;
|
||||||
|
value.length = value.data.length;
|
||||||
|
if (value.length > debuglength) {
|
||||||
|
value.data = value.data.slice(0,debuglength);
|
||||||
|
}
|
||||||
|
} else if (value.constructor.name === "ServerResponse") {
|
||||||
|
value = "[internal]"
|
||||||
|
} else if (value.constructor.name === "Socket") {
|
||||||
|
value = "[internal]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}," ");
|
||||||
|
} else {
|
||||||
|
try { msg.msg = msg.msg.toString(); }
|
||||||
|
catch(e) { msg.msg = "[Type not printable]" + util.inspect(msg.msg); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (msgType === "function") {
|
||||||
|
msg.format = "function";
|
||||||
|
msg.msg = "[function]"
|
||||||
|
} else if (msgType === "boolean") {
|
||||||
|
msg.format = "boolean";
|
||||||
|
msg.msg = msg.msg.toString();
|
||||||
|
} else if (msgType === "number") {
|
||||||
|
msg.format = "number";
|
||||||
|
msg.msg = msg.msg.toString();
|
||||||
|
} else if (msg.msg === null || msgType === "undefined") {
|
||||||
|
msg.format = (msg.msg === null)?"null":"undefined";
|
||||||
|
msg.msg = "(undefined)";
|
||||||
|
} else {
|
||||||
|
msg.format = "string["+msg.msg.length+"]";
|
||||||
|
if (msg.msg.length > debuglength) {
|
||||||
|
msg.msg = msg.msg.substring(0,debuglength)+"...";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (msgType === "function") {
|
return msg;
|
||||||
msg.format = "function";
|
} catch(e) {
|
||||||
msg.msg = "[function]"
|
msg.format = "error";
|
||||||
} else if (msgType === "boolean") {
|
var errorMsg = {};
|
||||||
msg.format = "boolean";
|
if (e.name) {
|
||||||
msg.msg = msg.msg.toString();
|
errorMsg.name = e.name;
|
||||||
} else if (msgType === "number") {
|
|
||||||
msg.format = "number";
|
|
||||||
msg.msg = msg.msg.toString();
|
|
||||||
} else if (msg.msg === null || msgType === "undefined") {
|
|
||||||
msg.format = (msg.msg === null)?"null":"undefined";
|
|
||||||
msg.msg = "(undefined)";
|
|
||||||
} else {
|
|
||||||
msg.format = "string["+msg.msg.length+"]";
|
|
||||||
if (msg.msg.length > debuglength) {
|
|
||||||
msg.msg = msg.msg.substring(0,debuglength)+"...";
|
|
||||||
}
|
}
|
||||||
|
if (e.hasOwnProperty('message')) {
|
||||||
|
errorMsg.message = 'encodeObject Error: ['+e.message + '] Value: '+util.inspect(msg.msg);
|
||||||
|
} else {
|
||||||
|
errorMsg.message = 'encodeObject Error: ['+e.toString() + '] Value: '+util.inspect(msg.msg);
|
||||||
|
}
|
||||||
|
if (errorMsg.message.length > debuglength) {
|
||||||
|
errorMsg.message = errorMsg.message.substring(0,debuglength);
|
||||||
|
}
|
||||||
|
msg.msg = JSON.stringify(errorMsg);
|
||||||
|
return msg;
|
||||||
}
|
}
|
||||||
return msg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/util",
|
"name": "@node-red/util",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -18,7 +18,7 @@
|
|||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"i18next": "15.1.2",
|
"i18next": "15.1.2",
|
||||||
"json-stringify-safe": "5.0.1",
|
"json-stringify-safe": "5.0.1",
|
||||||
"jsonata": "1.6.5",
|
"jsonata": "1.7.0",
|
||||||
"when": "3.7.8"
|
"when": "3.7.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
packages/node_modules/node-red/package.json
vendored
10
packages/node_modules/node-red/package.json
vendored
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red",
|
"name": "node-red",
|
||||||
"version": "1.0.2",
|
"version": "1.0.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": "1.0.2",
|
"@node-red/editor-api": "1.0.3",
|
||||||
"@node-red/runtime": "1.0.2",
|
"@node-red/runtime": "1.0.3",
|
||||||
"@node-red/util": "1.0.2",
|
"@node-red/util": "1.0.3",
|
||||||
"@node-red/nodes": "1.0.2",
|
"@node-red/nodes": "1.0.3",
|
||||||
"basic-auth": "2.0.1",
|
"basic-auth": "2.0.1",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
|
@ -4,4 +4,4 @@ npm install --no-save \
|
|||||||
wdio-mocha-framework@^0.6.4 \
|
wdio-mocha-framework@^0.6.4 \
|
||||||
wdio-spec-reporter@^0.1.5 \
|
wdio-spec-reporter@^0.1.5 \
|
||||||
webdriverio@^4.14.1 \
|
webdriverio@^4.14.1 \
|
||||||
chromedriver@2
|
chromedriver@^78.0.1
|
||||||
|
@ -61,7 +61,7 @@ exports.config = {
|
|||||||
maxInstances: 2,
|
maxInstances: 2,
|
||||||
//
|
//
|
||||||
browserName: 'chrome',
|
browserName: 'chrome',
|
||||||
chromeOptions: {
|
'goog:chromeOptions': {
|
||||||
args: process.env.NODE_RED_NON_HEADLESS
|
args: process.env.NODE_RED_NON_HEADLESS
|
||||||
// Runs tests with opening a browser.
|
// Runs tests with opening a browser.
|
||||||
? ['--disable-gpu']
|
? ['--disable-gpu']
|
||||||
@ -134,7 +134,7 @@ exports.config = {
|
|||||||
// Services take over a specific job you don't want to take care of. They enhance
|
// Services take over a specific job you don't want to take care of. They enhance
|
||||||
// your test setup with almost no effort. Unlike plugins, they don't add new
|
// your test setup with almost no effort. Unlike plugins, they don't add new
|
||||||
// commands. Instead, they hook themselves up into the test process.
|
// commands. Instead, they hook themselves up into the test process.
|
||||||
port: '9515',
|
port: 9515,
|
||||||
path: '/',
|
path: '/',
|
||||||
services: ['chromedriver'],
|
services: ['chromedriver'],
|
||||||
//
|
//
|
||||||
|
@ -251,7 +251,8 @@ describe('delay Node', function() {
|
|||||||
var helperNode1 = helper.getNode("helperNode1");
|
var helperNode1 = helper.getNode("helperNode1");
|
||||||
var receivedMessagesStack = [];
|
var receivedMessagesStack = [];
|
||||||
|
|
||||||
var rate = 1000/aLimit;
|
// Add a small grace to the calculated delay
|
||||||
|
var rate = 1000/aLimit + 10;
|
||||||
|
|
||||||
var receiveTimestamp;
|
var receiveTimestamp;
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ describe("api/admin/nodes", function() {
|
|||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.post('/nodes')
|
.post('/nodes')
|
||||||
.send({module: 'foo',version:"1.2.3"})
|
.send({module: 'foo',version:"1.2.3",url:"https://example/foo-1.2.3.tgz"})
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -238,6 +238,7 @@ describe("api/admin/nodes", function() {
|
|||||||
res.body.nodes[0].should.have.property("id","123");
|
res.body.nodes[0].should.have.property("id","123");
|
||||||
opts.should.have.property("module","foo");
|
opts.should.have.property("module","foo");
|
||||||
opts.should.have.property("version","1.2.3");
|
opts.should.have.property("version","1.2.3");
|
||||||
|
opts.should.have.property("url","https://example/foo-1.2.3.tgz");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -256,7 +257,7 @@ describe("api/admin/nodes", function() {
|
|||||||
});
|
});
|
||||||
request(app)
|
request(app)
|
||||||
.post('/nodes')
|
.post('/nodes')
|
||||||
.send({module: 'foo',version:"1.2.3"})
|
.send({module: 'foo',version:"1.2.3",url:"https://example/foo-1.2.3.tgz"})
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(function(err,res) {
|
.end(function(err,res) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -121,6 +121,17 @@ describe('nodes/registry/installer', function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("rejects when update requested to existing version and url", function(done) {
|
||||||
|
sinon.stub(typeRegistry,"getModuleInfo", function() {
|
||||||
|
return {
|
||||||
|
version: "0.1.1"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
installer.installModule("this_wont_exist","0.1.1","https://example/foo-0.1.1.tgz").catch(function(err) {
|
||||||
|
err.code.should.be.eql('module_already_loaded');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
it("rejects with generic error", function(done) {
|
it("rejects with generic error", function(done) {
|
||||||
var res = {
|
var res = {
|
||||||
code: 1,
|
code: 1,
|
||||||
@ -201,6 +212,29 @@ describe('nodes/registry/installer', function() {
|
|||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("succeeds when url is valid node-red module", function(done) {
|
||||||
|
var nodeInfo = {nodes:{module:"foo",types:["a"]}};
|
||||||
|
|
||||||
|
var res = {
|
||||||
|
code: 0,
|
||||||
|
stdout:"",
|
||||||
|
stderr:""
|
||||||
|
}
|
||||||
|
var p = Promise.resolve(res);
|
||||||
|
p.catch((err)=>{});
|
||||||
|
initInstaller(p)
|
||||||
|
|
||||||
|
var addModule = sinon.stub(registry,"addModule",function(md) {
|
||||||
|
return when.resolve(nodeInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
installer.installModule("this_wont_exist",null,"https://example/foo-0.1.1.tgz").then(function(info) {
|
||||||
|
info.should.eql(nodeInfo);
|
||||||
|
done();
|
||||||
|
}).catch(function(err) {
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
describe("uninstalls module", function() {
|
describe("uninstalls module", function() {
|
||||||
|
@ -298,7 +298,7 @@ describe('Subflow', function() {
|
|||||||
// // stoppedNodes.should.have.a.property(sfConfigId);
|
// // stoppedNodes.should.have.a.property(sfConfigId);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
it("instantiates a subflow inside a subflow and stops it",function(done) {
|
it("instantiates a subflow inside a subflow and stops it",function(done) {
|
||||||
var config = flowUtils.parseConfig([
|
var config = flowUtils.parseConfig([
|
||||||
@ -331,7 +331,7 @@ describe('Subflow', function() {
|
|||||||
Object.keys(currentNodes).should.have.length(0);
|
Object.keys(currentNodes).should.have.length(0);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
it("rewires a subflow node on update/start",function(done){
|
it("rewires a subflow node on update/start",function(done){
|
||||||
|
|
||||||
@ -391,8 +391,8 @@ describe('Subflow', function() {
|
|||||||
flow.stop().then(function() {
|
flow.stop().then(function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#stop', function() {
|
describe('#stop', function() {
|
||||||
@ -452,7 +452,7 @@ describe('Subflow', function() {
|
|||||||
flow.stop().then(function() {
|
flow.stop().then(function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
it("passes a status event to the subflow's parent tab status node - targetted scope",function(done) {
|
it("passes a status event to the subflow's parent tab status node - targetted scope",function(done) {
|
||||||
var config = flowUtils.parseConfig([
|
var config = flowUtils.parseConfig([
|
||||||
@ -491,7 +491,7 @@ describe('Subflow', function() {
|
|||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -536,7 +536,7 @@ describe('Subflow', function() {
|
|||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
it("emits a status event when a message is passed to a subflow-status node - msg.payload as status obj", function(done) {
|
it("emits a status event when a message is passed to a subflow-status node - msg.payload as status obj", function(done) {
|
||||||
var config = flowUtils.parseConfig([
|
var config = flowUtils.parseConfig([
|
||||||
@ -578,7 +578,7 @@ describe('Subflow', function() {
|
|||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
it("emits a status event when a message is passed to a subflow-status node - msg.status", function(done) {
|
it("emits a status event when a message is passed to a subflow-status node - msg.status", function(done) {
|
||||||
var config = flowUtils.parseConfig([
|
var config = flowUtils.parseConfig([
|
||||||
@ -620,7 +620,7 @@ describe('Subflow', function() {
|
|||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
it("does not emit a regular status event if it contains a subflow-status node", function(done) {
|
it("does not emit a regular status event if it contains a subflow-status node", function(done) {
|
||||||
var config = flowUtils.parseConfig([
|
var config = flowUtils.parseConfig([
|
||||||
@ -690,7 +690,7 @@ describe('Subflow', function() {
|
|||||||
flow.stop().then(function() {
|
flow.stop().then(function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
it("passes an error event to the subflow's parent tab catch node - targetted scope",function(done) {
|
it("passes an error event to the subflow's parent tab catch node - targetted scope",function(done) {
|
||||||
var config = flowUtils.parseConfig([
|
var config = flowUtils.parseConfig([
|
||||||
@ -727,7 +727,7 @@ describe('Subflow', function() {
|
|||||||
flow.stop().then(function() {
|
flow.stop().then(function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -777,7 +777,7 @@ describe('Subflow', function() {
|
|||||||
flow.stop().then(function() {
|
flow.stop().then(function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can access subflow env var", function(done) {
|
it("can access subflow env var", function(done) {
|
||||||
@ -817,7 +817,7 @@ describe('Subflow', function() {
|
|||||||
flow.stop().then(function() {
|
flow.stop().then(function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("can access nested subflow env var", function(done) {
|
it("can access nested subflow env var", function(done) {
|
||||||
@ -875,9 +875,9 @@ describe('Subflow', function() {
|
|||||||
flow.stop().then(function() {
|
flow.stop().then(function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
},50);
|
},150);
|
||||||
},50);
|
},150);
|
||||||
},50);
|
},150);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -19,6 +19,7 @@ var fs = require('fs-extra');
|
|||||||
var path = require('path');
|
var path = require('path');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var NR_TEST_UTILS = require("nr-test-utils");
|
var NR_TEST_UTILS = require("nr-test-utils");
|
||||||
|
var process = require("process");
|
||||||
|
|
||||||
var localfilesystem = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem");
|
var localfilesystem = NR_TEST_UTILS.require("@node-red/runtime/lib/storage/localfilesystem");
|
||||||
var log = NR_TEST_UTILS.require("@node-red/util").log;
|
var log = NR_TEST_UTILS.require("@node-red/util").log;
|
||||||
@ -474,4 +475,44 @@ describe('storage/localfilesystem', function() {
|
|||||||
done(err);
|
done(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle flow file in random unc path and non-existent subfolder',function(done) {
|
||||||
|
// only test on win32
|
||||||
|
if (process.platform !== 'win32') {
|
||||||
|
console.log('skipped test as not win32');
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a real windows path
|
||||||
|
var flowFile = path.win32.resolve(userDir+'/some/random/path');
|
||||||
|
var rootdir = path.win32.resolve(userDir+'/some');
|
||||||
|
// make it into a local UNC path
|
||||||
|
flowFile = flowFile.replace('C:\\', '\\\\localhost\\c$\\');
|
||||||
|
localfilesystem.init({userDir:userDir, flowFile:flowFile}, mockRuntime).then(function() {
|
||||||
|
fs.existsSync(flowFile).should.be.false();
|
||||||
|
localfilesystem.saveFlows(testFlow).then(function() {
|
||||||
|
fs.existsSync(flowFile).should.be.true();
|
||||||
|
localfilesystem.getFlows().then(function(flows) {
|
||||||
|
flows.should.eql(testFlow);
|
||||||
|
// cleanup
|
||||||
|
fs.removeSync(rootdir);
|
||||||
|
done();
|
||||||
|
}).catch(function(err) {
|
||||||
|
// cleanup
|
||||||
|
fs.removeSync(rootdir);
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
}).catch(function(err) {
|
||||||
|
// cleanup
|
||||||
|
fs.removeSync(rootdir);
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
}).catch(function(err) {
|
||||||
|
// cleanup
|
||||||
|
fs.removeSync(rootdir);
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -224,5 +224,29 @@ describe("@node-red/util/log", function() {
|
|||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
it('it can log without exception', function() {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
mystrangeobj:"hello",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
msg.msg.toString = function(){
|
||||||
|
throw new Error('Exception in toString - should have been caught');
|
||||||
|
}
|
||||||
|
msg.msg.constructor = { name: "strangeobj" };
|
||||||
|
var ret = log.info(msg.msg);
|
||||||
|
});
|
||||||
|
it('it can log an object but use .message', function() {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
message: "my special message",
|
||||||
|
mystrangeobj:"hello",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var ret = log.info(msg.msg);
|
||||||
|
sinon.assert.calledWithMatch(util.log,"my special message");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -772,6 +772,117 @@ describe("@node-red/util/util", function() {
|
|||||||
var resultJson = JSON.parse(result.msg);
|
var resultJson = JSON.parse(result.msg);
|
||||||
resultJson.socket.should.eql('[internal]');
|
resultJson.socket.should.eql('[internal]');
|
||||||
});
|
});
|
||||||
|
it('object which fails to serialise', function(done) {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
obj:{
|
||||||
|
cantserialise:{
|
||||||
|
message:'this will not be displayed',
|
||||||
|
toJSON: function(val) {
|
||||||
|
throw 'this exception should have been caught';
|
||||||
|
return 'should not display because we threw first';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
canserialise:{
|
||||||
|
message:'this should be displayed',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var result = util.encodeObject(msg);
|
||||||
|
result.format.should.eql("error");
|
||||||
|
var success = (result.msg.indexOf('cantserialise') > 0);
|
||||||
|
success &= (result.msg.indexOf('this exception should have been caught') > 0);
|
||||||
|
success &= (result.msg.indexOf('canserialise') > 0);
|
||||||
|
success.should.eql(1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
it('object which fails to serialise - different error type', function(done) {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
obj:{
|
||||||
|
cantserialise:{
|
||||||
|
message:'this will not be displayed',
|
||||||
|
toJSON: function(val) {
|
||||||
|
throw new Error('this exception should have been caught');
|
||||||
|
return 'should not display because we threw first';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
canserialise:{
|
||||||
|
message:'this should be displayed',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var result = util.encodeObject(msg);
|
||||||
|
result.format.should.eql("error");
|
||||||
|
var success = (result.msg.indexOf('cantserialise') > 0);
|
||||||
|
success &= (result.msg.indexOf('this exception should have been caught') > 0);
|
||||||
|
success &= (result.msg.indexOf('canserialise') > 0);
|
||||||
|
success.should.eql(1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
it('very large object which fails to serialise should be truncated', function(done) {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
obj:{
|
||||||
|
big:"",
|
||||||
|
cantserialise:{
|
||||||
|
message:'this will not be displayed',
|
||||||
|
toJSON: function(val) {
|
||||||
|
throw new Error('this exception should have been caught');
|
||||||
|
return 'should not display because we threw first';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
canserialise:{
|
||||||
|
message:'this should be displayed',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < 1000; i++) {
|
||||||
|
msg.msg.obj.big += 'some more string ';
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = util.encodeObject(msg);
|
||||||
|
result.format.should.eql("error");
|
||||||
|
var resultJson = JSON.parse(result.msg);
|
||||||
|
var success = (resultJson.message.length <= 1000);
|
||||||
|
success.should.eql(true);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
it('test bad toString', function(done) {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
mystrangeobj:"hello",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
msg.msg.toString = function(){
|
||||||
|
throw new Error('Exception in toString - should have been caught');
|
||||||
|
}
|
||||||
|
msg.msg.constructor = { name: "strangeobj" };
|
||||||
|
|
||||||
|
var result = util.encodeObject(msg);
|
||||||
|
var success = (result.msg.indexOf('[Type not printable]') >= 0);
|
||||||
|
success.should.eql(true);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
it('test bad object constructor', function(done) {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
mystrangeobj:"hello",
|
||||||
|
constructor: {
|
||||||
|
get name(){
|
||||||
|
throw new Error('Exception in constructor name');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var result = util.encodeObject(msg);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user